From 8b4cb29237b43e0050f2bd4702830889cbb9f048 Mon Sep 17 00:00:00 2001 From: vsr Date: Thu, 9 Aug 2012 11:45:31 +0000 Subject: [PATCH] Merge from V6_main_20120808 08Aug12 --- Makefile.am | 36 +- NETGENPLUGIN_version.h.in | 32 +- adm_local/Makefile.am | 30 +- adm_local/cmake_files/FindNETGEN.cmake | 82 + adm_local/unix/Makefile.am | 30 +- adm_local/unix/config_files/Makefile.am | 30 +- adm_local/unix/config_files/check_NETGEN.m4 | 188 +- .../unix/config_files/check_NETGENPLUGIN.m4 | 31 +- adm_local/unix/make_common_starter.am | 36 +- bin/Makefile.am | 30 +- bin/VERSION.in | 4 +- build_cmake | 27 + build_cmake.bat | 20 + build_configure | 100 +- clean_configure | 39 +- configure.ac | 174 +- doc/Makefile.am | 32 + doc/salome/Makefile.am | 34 + doc/salome/gui/Makefile.am | 32 + doc/salome/gui/NETGENPLUGIN/Makefile.am | 67 + doc/salome/gui/NETGENPLUGIN/doxyfile.in | 115 + doc/salome/gui/NETGENPLUGIN/doxyfile_py.in | 162 + doc/salome/gui/NETGENPLUGIN/images/head.png | Bin 0 -> 78545 bytes doc/salome/gui/NETGENPLUGIN/images/image1.png | Bin 0 -> 17155 bytes doc/salome/gui/NETGENPLUGIN/images/image2.gif | Bin 0 -> 4694 bytes .../gui/NETGENPLUGIN/images/netgen2d3d.png | Bin 0 -> 32806 bytes .../NETGENPLUGIN/images/netgen2d3d_only.png | Bin 0 -> 28481 bytes .../NETGENPLUGIN/images/netgen2d3d_simple.png | Bin 0 -> 34920 bytes .../images/netgen3d_local_size.png | Bin 0 -> 16229 bytes .../NETGENPLUGIN/input/additional_hypo.doc | 28 + doc/salome/gui/NETGENPLUGIN/input/index.doc | 20 + .../NETGENPLUGIN/input/netgen_2d_3d_hypo.doc | 100 + .../input/netgenplugin_python_interface.doc | 59 + .../gui/NETGENPLUGIN/static/doxygen.css | 836 +++++ .../gui/NETGENPLUGIN/static/footer.html | 12 + .../gui/NETGENPLUGIN/static/header.html.in | 20 + .../gui/NETGENPLUGIN/static/header_py.html.in | 21 + idl/Makefile.am | 48 +- idl/NETGENPlugin_Algorithm.idl | 71 +- resources/Makefile.am | 30 +- resources/NETGENPlugin.xml | 68 +- resources/SalomeApp.xml | 5 +- src/GUI/Makefile.am | 44 +- src/GUI/NETGENPluginGUI.cxx | 34 +- src/GUI/NETGENPluginGUI.h | 32 +- src/GUI/NETGENPluginGUI_HypothesisCreator.cxx | 611 +++- src/GUI/NETGENPluginGUI_HypothesisCreator.h | 62 +- src/GUI/NETGENPluginGUI_SimpleCreator.cxx | 108 +- src/GUI/NETGENPluginGUI_SimpleCreator.h | 31 +- src/GUI/NETGENPlugin_images.ts | 32 +- src/GUI/NETGENPlugin_msg_en.ts | 284 +- src/GUI/NETGENPlugin_msg_fr.ts | 151 + src/Makefile.am | 40 +- src/NETGEN/Makefile.am | 30 +- src/NETGEN/ReadMeForNgUsers | 43 + src/NETGEN/netgen45ForSalome.patch | 714 ++-- src/NETGEN/netgen49ForSalome.patch | 1014 ++++++ src/NETGEN/netgen_copy_include_for_salome | 39 + src/NETGENPlugin/Makefile.am | 58 +- src/NETGENPlugin/NETGENPluginDC.py | 306 ++ src/NETGENPlugin/NETGENPlugin_Defs.hxx | 33 +- src/NETGENPlugin/NETGENPlugin_Hypothesis.cxx | 172 +- src/NETGENPlugin/NETGENPlugin_Hypothesis.hxx | 51 +- .../NETGENPlugin_Hypothesis_2D.cxx | 34 +- .../NETGENPlugin_Hypothesis_2D.hxx | 32 +- .../NETGENPlugin_Hypothesis_2D_ONLY_i.cxx | 72 + .../NETGENPlugin_Hypothesis_2D_ONLY_i.hxx | 57 + .../NETGENPlugin_Hypothesis_2D_i.cxx | 60 +- .../NETGENPlugin_Hypothesis_2D_i.hxx | 44 +- .../NETGENPlugin_Hypothesis_3D_i.cxx | 71 + .../NETGENPlugin_Hypothesis_3D_i.hxx | 59 + .../NETGENPlugin_Hypothesis_i.cxx | 270 +- .../NETGENPlugin_Hypothesis_i.hxx | 89 +- src/NETGENPlugin/NETGENPlugin_Mesher.cxx | 3198 ++++++++++++++--- src/NETGENPlugin/NETGENPlugin_Mesher.hxx | 197 +- src/NETGENPlugin/NETGENPlugin_NETGEN_2D.cxx | 71 +- src/NETGENPlugin/NETGENPlugin_NETGEN_2D.hxx | 40 +- src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.cxx | 67 +- src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.hxx | 41 +- .../NETGENPlugin_NETGEN_2D3D_i.cxx | 31 +- .../NETGENPlugin_NETGEN_2D3D_i.hxx | 31 +- .../NETGENPlugin_NETGEN_2D_ONLY.cxx | 436 ++- .../NETGENPlugin_NETGEN_2D_ONLY.hxx | 63 +- .../NETGENPlugin_NETGEN_2D_ONLY_i.cxx | 34 +- .../NETGENPlugin_NETGEN_2D_ONLY_i.hxx | 30 +- src/NETGENPlugin/NETGENPlugin_NETGEN_2D_i.cxx | 31 +- src/NETGENPlugin/NETGENPlugin_NETGEN_2D_i.hxx | 31 +- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 807 +++-- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx | 63 +- src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.cxx | 39 +- src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.hxx | 31 +- .../NETGENPlugin_SimpleHypothesis_2D.cxx | 61 +- .../NETGENPlugin_SimpleHypothesis_2D.hxx | 40 +- .../NETGENPlugin_SimpleHypothesis_2D_i.cxx | 109 +- .../NETGENPlugin_SimpleHypothesis_2D_i.hxx | 45 +- .../NETGENPlugin_SimpleHypothesis_3D.cxx | 30 +- .../NETGENPlugin_SimpleHypothesis_3D.hxx | 30 +- .../NETGENPlugin_SimpleHypothesis_3D_i.cxx | 32 +- .../NETGENPlugin_SimpleHypothesis_3D_i.hxx | 30 +- src/NETGENPlugin/NETGENPlugin_i.cxx | 47 +- 100 files changed, 10176 insertions(+), 2815 deletions(-) create mode 100644 adm_local/cmake_files/FindNETGEN.cmake 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/Makefile.am create mode 100755 doc/salome/gui/NETGENPLUGIN/Makefile.am create mode 100755 doc/salome/gui/NETGENPLUGIN/doxyfile.in create mode 100755 doc/salome/gui/NETGENPLUGIN/doxyfile_py.in create mode 100755 doc/salome/gui/NETGENPLUGIN/images/head.png create mode 100755 doc/salome/gui/NETGENPLUGIN/images/image1.png create mode 100755 doc/salome/gui/NETGENPLUGIN/images/image2.gif create mode 100644 doc/salome/gui/NETGENPLUGIN/images/netgen2d3d.png create mode 100644 doc/salome/gui/NETGENPLUGIN/images/netgen2d3d_only.png create mode 100644 doc/salome/gui/NETGENPLUGIN/images/netgen2d3d_simple.png create mode 100644 doc/salome/gui/NETGENPLUGIN/images/netgen3d_local_size.png create mode 100644 doc/salome/gui/NETGENPLUGIN/input/additional_hypo.doc create mode 100644 doc/salome/gui/NETGENPLUGIN/input/index.doc create mode 100644 doc/salome/gui/NETGENPLUGIN/input/netgen_2d_3d_hypo.doc create mode 100644 doc/salome/gui/NETGENPLUGIN/input/netgenplugin_python_interface.doc create mode 100755 doc/salome/gui/NETGENPLUGIN/static/doxygen.css create mode 100755 doc/salome/gui/NETGENPLUGIN/static/footer.html create mode 100755 doc/salome/gui/NETGENPLUGIN/static/header.html.in create mode 100644 doc/salome/gui/NETGENPLUGIN/static/header_py.html.in create mode 100755 src/GUI/NETGENPlugin_msg_fr.ts create mode 100644 src/NETGEN/netgen49ForSalome.patch create mode 100755 src/NETGEN/netgen_copy_include_for_salome create mode 100644 src/NETGENPlugin/NETGENPluginDC.py create mode 100644 src/NETGENPlugin/NETGENPlugin_Hypothesis_2D_ONLY_i.cxx create mode 100644 src/NETGENPlugin/NETGENPlugin_Hypothesis_2D_ONLY_i.hxx create mode 100644 src/NETGENPlugin/NETGENPlugin_Hypothesis_3D_i.cxx create mode 100644 src/NETGENPlugin/NETGENPlugin_Hypothesis_3D_i.hxx diff --git a/Makefile.am b/Makefile.am index 893cd5c..6c9e9d1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # -* Makefile *- # Author : Patrick GOLDBRONN (CEA) # Date : 28/06/2001 @@ -41,11 +39,11 @@ else !NETGENPLUGIN_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 = NETGENPLUGIN_version.h diff --git a/NETGENPLUGIN_version.h.in b/NETGENPLUGIN_version.h.in index 8f1132a..d90a928 100644 --- a/NETGENPLUGIN_version.h.in +++ b/NETGENPLUGIN_version.h.in @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : NETGENPLUGIN_version.h // Author : Vadim SANDLER // Module : SALOME @@ -32,5 +33,6 @@ #define NETGENPLUGIN_VERSION_STR "@VERSION@" #define NETGENPLUGIN_VERSION @XVERSION@ +#define NETGENPLUGIN_DEVELOPMENT @VERSION_DEV@ #endif // __NETGENPLUGIN_VERSION_H__ diff --git a/adm_local/Makefile.am b/adm_local/Makefile.am index f35273f..9863d29 100644 --- a/adm_local/Makefile.am +++ b/adm_local/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + include $(top_srcdir)/adm_local/unix/make_common_starter.am SUBDIRS = unix diff --git a/adm_local/cmake_files/FindNETGEN.cmake b/adm_local/cmake_files/FindNETGEN.cmake new file mode 100644 index 0000000..65dc9ee --- /dev/null +++ b/adm_local/cmake_files/FindNETGEN.cmake @@ -0,0 +1,82 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +SET(NETGENHOME $ENV{NETGENHOME}) +FIND_PATH(NETGEN_INCLUDES_DIR nglib.h ${NETGENHOME}/include) +SET(NETGEN_INCLUDES) +SET(NETGEN_INCLUDES ${NETGEN_INCLUDES} -I${NETGEN_INCLUDES_DIR}) +SET(NETGEN_INCLUDES ${NETGEN_INCLUDES} -DNO_PARALLEL_THREADS -DOCCGEOMETRY) + +FIND_LIBRARY(NETGEN_LIB_nglib nglib PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + +IF(NETGEN_LIB_nglib) + SET(NETGEN_NEW ON) + SET(NETGEN_INCLUDES ${NETGEN_INCLUDES} -I${NETGENHOME}/share/netgen/include -DNETGEN_NEW) +ELSE(NETGEN_LIB_nglib) + SET(NETGEN_NEW OFF) +ENDIF(NETGEN_LIB_nglib) + +IF(NETGEN_NEW) + SET(NETGEN_LIBS) + IF(WINDOWS) + FIND_LIBRARY(NETGEN_LIB_csg csg PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + FIND_LIBRARY(NETGEN_LIB_gen gen PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + FIND_LIBRARY(NETGEN_LIB_geom2d geom2d PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + FIND_LIBRARY(NETGEN_LIB_gprim gprim PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + FIND_LIBRARY(NETGEN_LIB_interface interface PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + FIND_LIBRARY(NETGEN_LIB_la la PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + FIND_LIBRARY(NETGEN_LIB_mesh mesh PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + FIND_LIBRARY(NETGEN_LIB_occ occ PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + FIND_LIBRARY(NETGEN_LIB_stl stl PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_csg}) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_gen}) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_geom2d}) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_gprim}) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_interface}) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_la}) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_mesh}) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_occ}) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_stl}) + ENDIF(WINDOWS) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_nglib}) +ELSE(NETGEN_NEW) + FIND_LIBRARY(NETGEN_LIB_csg csg PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + FIND_LIBRARY(NETGEN_LIB_gen gen PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + FIND_LIBRARY(NETGEN_LIB_geom2d geom2d PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + FIND_LIBRARY(NETGEN_LIB_gprim gprim PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + FIND_LIBRARY(NETGEN_LIB_la la PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + FIND_LIBRARY(NETGEN_LIB_mesh mesh PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + FIND_LIBRARY(NETGEN_LIB_nginterface nginterface PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + FIND_LIBRARY(NETGEN_LIB_occ occ PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + FIND_LIBRARY(NETGEN_LIB_opti opti PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + FIND_LIBRARY(NETGEN_LIB_stlgeom stlgeom PATHS ${NETGENHOME}/lib ${NETGENHOME}/lib/LINUX) + SET(NETGEN_LIBS) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_csg}) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_gen}) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_geom2d}) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_gprim}) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_la}) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_mesh}) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_nginterface}) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_occ}) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_opti}) + SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_stlgeom}) +ENDIF(NETGEN_NEW) + +SET(CMAKE_BUILD 1) diff --git a/adm_local/unix/Makefile.am b/adm_local/unix/Makefile.am index 5f6d5f7..0d5ee76 100644 --- a/adm_local/unix/Makefile.am +++ b/adm_local/unix/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + include $(top_srcdir)/adm_local/unix/make_common_starter.am SUBDIRS = config_files diff --git a/adm_local/unix/config_files/Makefile.am b/adm_local/unix/config_files/Makefile.am index ef7b6d6..77cb591 100644 --- a/adm_local/unix/config_files/Makefile.am +++ b/adm_local/unix/config_files/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + include $(top_srcdir)/adm_local/unix/make_common_starter.am dist_admlocalm4_DATA = \ diff --git a/adm_local/unix/config_files/check_NETGEN.m4 b/adm_local/unix/config_files/check_NETGEN.m4 index c33735f..2738aeb 100644 --- a/adm_local/unix/config_files/check_NETGEN.m4 +++ b/adm_local/unix/config_files/check_NETGEN.m4 @@ -1,24 +1,25 @@ -dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE dnl -dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl -dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl + AC_DEFUN([CHECK_NETGEN],[ AC_REQUIRE([AC_PROG_CXX])dnl @@ -35,6 +36,8 @@ AC_ARG_WITH(netgen, NETGEN_INCLUDES="" NETGEN_LIBS_DIR="" +NETGEN_LIBS="" +NETGEN_NEW=no Netgen_ok=no @@ -52,29 +55,29 @@ fi if test "x$NETGEN_HOME" != "x"; then - echo - echo - echo ------------------------------------------------- + if test -f ${NETGEN_HOME}/lib/libnglib.so ; then + NETGEN_NEW=yes + fi + + echo ---------------------------------------------------------- + echo ---------------------------------------------------------- echo You are about to choose to use somehow the echo Netgen Library to generate Tetrahedric mesh. - echo - echo WARNING echo ---------------------------------------------------------- echo ---------------------------------------------------------- echo You are strongly advised to consult the file - echo NETGENPLUGIN_SRC/src/NETGEN/ReadMeForNgUsers, particularly about - echo assumptions made on the installation of the Netgen + echo NETGENPLUGIN_SRC/src/NETGEN/ReadMeForNgUsers, particularly + echo about assumptions made on the installation of the Netgen echo application and libraries. - echo Ask your system administrator for those details. echo ---------------------------------------------------------- echo ---------------------------------------------------------- - echo - echo - - NETGEN_INCLUDES="-I${NETGEN_HOME}/include" - + + if test "$NETGEN_NEW" = "yes" ; then + NETGEN_INCLUDES="${NETGEN_INCLUDES} -DNETGEN_NEW -I${NETGEN_HOME}/share/netgen/include" + fi + # check ${NETGEN_HOME}/lib/LINUX directory for libraries if test -f ${NETGEN_HOME}/lib/LINUX/libcsg.a ; then NETGEN_LIBS_DIR="${NETGEN_HOME}/lib/LINUX" @@ -91,18 +94,20 @@ if test "x$NETGEN_HOME" != "x"; then CPPFLAGS_old="$CPPFLAGS" CXXFLAGS_old="$CXXFLAGS" - CPPFLAGS="$NETGEN_INCLUDES $CAS_CPPFLAGS $CPPFLAGS" - CXXFLAGS="$NETGEN_INCLUDES $CAS_CPPFLAGS $CXXFLAGS" + CPPFLAGS="$CAS_CPPFLAGS $NETGEN_INCLUDES $CPPFLAGS" + CXXFLAGS="$CAS_CPPFLAGS $NETGEN_INCLUDES $CXXFLAGS" AC_MSG_CHECKING(for Netgen header file) AC_CHECK_HEADER(nglib.h,Netgen_ok=yes,Netgen_ok=no) if test "x$Netgen_ok" == "xyes"; then + if test "$NETGEN_NEW" = "no" ; then + AC_MSG_CHECKING(for Netgen libraries) - LDFLAGS_old="$LDFLAGS" - LDFLAGS="-L. -lNETGEN $CAS_LDPATH -lTKBRep -lTKShHealing -lTKSTEP -lTKXSBase -lTKIGES -lTKSTL -lTKTopAlgo $LDFLAGS" + LIBS_old="$LIBS" + LIBS="-L. -lNETGEN $CAS_LDPATH -lTKernel -lTKMath -lTKG3d -lTKBRep -lTKShHealing -lTKSTEP -lTKXSBase -lTKIGES -lTKSTL -lTKTopAlgo $LIBS" AC_TRY_COMPILE(#include #include @@ -127,24 +132,102 @@ namespace nglib { rm -rf linopt.o bfgs.o linsearch.o global.o bisect.o meshtool.o refine.o ruler3.o improve3.o adfront3.o tetrarls.o prism2rls.o profiler.o pyramidrls.o pyramid2rls.o netrule3.o ruler2.o meshclass.o improve2.o adfront2.o netrule2.o triarls.o geomsearch.o secondorder.o meshtype.o parser3.o quadrls.o specials.o parser2.o meshing2.o meshing3.o meshfunc.o localh.o improve2gen.o delaunay.o boundarylayer.o msghandler.o meshfunc2d.o smoothing2.o smoothing3.o topology.o curvedelems_new.o clusters.o zrefine.o ngexception.o geomtest3d.o geom2d.o geom2dmesh.o geom3d.o adtree.o transform3d.o geomfuncs.o polynomial.o densemat.o vector.o basemat.o sparsmat.o algprim.o brick.o manifold.o bspline2d.o meshsurf.o csgeom.o polyhedra.o curve2d.o singularref.o edgeflw.o solid.o explicitcurve2d.o specpoin.o gencyl.o revolution.o genmesh.o genmesh2d.o spline3d.o surface.o identify.o triapprox.o meshstlsurface.o stlline.o stltopology.o stltool.o stlgeom.o stlgeomchart.o stlgeommesh.o table.o optmem.o spbita2d.o hashtabl.o sort.o flags.o seti.o bitarray.o array.o symbolta.o mystring.o moveablemem.o spline.o splinegeometry.o ngnewdelete.o nglib.o hprefinement.o Partition_Inter2d.o Partition_Loop.o Partition_Loop3d.o Partition_Inter3d.o Partition_Loop2d.o Partition_Spliter.o occgeom.o occgenmesh.o occmeshsurf.o csgparser.o dynamicmem.o extrusion.o occconstruction.o parthreads.o readuser.o writeabaqus.o writediffpack.o writeelmer.o writefeap.o writefluent.o writegmsh.o writejcm.o writepermas.o writetecplot.o writetochnog.o writeuser.o wuchemnitz.o, Netgen_ok=no) - AC_CACHE_VAL(salome_netgen_lib,[ - AC_TRY_LINK( -#include -#include -namespace nglib { -#include "nglib.h" -} -#define OCCGEOMETRY -#include -,nglib::Ng_Init(); - netgen::OCCGeometry occgeo; - nglib::Ng_Exit();, - eval "salome_netgen_lib=yes";rm -rf libNETGEN.so,eval "salome_netgen_lib=no";rm -rf libNETGEN.so) - ]) - Netgen_ok="$salome_netgen_lib" + AC_CACHE_VAL(salome_cv_netgen_lib,[ + AC_TRY_LINK([ + #include + #include + namespace nglib { + #include "nglib.h" + } + #define OCCGEOMETRY + #include + ],[ + nglib::Ng_Init(); + netgen::OCCGeometry occgeo; + nglib::Ng_Exit(); + ], + [eval "salome_cv_netgen_lib=yes";rm -rf libNETGEN.so], + [eval "salome_cv_netgen_lib=no";rm -rf libNETGEN.so]) + ]) + Netgen_ok="$salome_cv_netgen_lib" + + else + + LIBS_old="$LIBS" + LIBS="-L${NETGEN_LIBS_DIR} -lnglib $CAS_LDPATH -lTKernel -lTKMath -lTKG3d -lTKBRep -lTKShHealing -lTKSTEP -lTKXSBase -lTKIGES -lTKSTL -lTKTopAlgo -lTKGeomBase $LIBS" + + AC_MSG_CHECKING(for official Netgen libraries) + AC_CACHE_VAL(salome_cv_netgen_lib,[ + AC_TRY_LINK([ + #include + #include + namespace nglib { + #include "nglib.h" + } + ],[ + nglib::Ng_Init(); + nglib::Ng_Exit(); + ], + [eval "salome_cv_netgen_lib=yes"], + [eval "salome_cv_netgen_lib=no"]) + ]) + Netgen_ok="$salome_cv_netgen_lib" + if test "$Netgen_ok" = "yes" ; then + AC_MSG_RESULT(yes) + AC_MSG_CHECKING(for occ support in Netgen libraries) + AC_CACHE_VAL(salome_cv_netgen_occ_lib,[ + AC_TRY_LINK([ + #include + #include + #define OCCGEOMETRY + namespace nglib { + #include "nglib.h" + } + ],[ + nglib::Ng_Init(); + nglib::Ng_OCC_Geometry * ng_occ_geom = nglib::Ng_OCC_NewGeometry(); + nglib::Ng_Exit(); + ], + [eval "salome_cv_netgen_occ_lib=yes"], + [eval "salome_cv_netgen_occ_lib=no"]) + ]) + Netgen_ok="$salome_cv_netgen_occ_lib" + fi - LDFLAGS="$LDFLAGS_old" + if test "$Netgen_ok" = "yes" ; then + AC_MSG_RESULT(yes) + AC_MSG_CHECKING(for salome patch in Netgen installation) + AC_CACHE_VAL(salome_cv_netgen_salome_patch_lib,[ + AC_TRY_LINK([ + #include + #include + #define OCCGEOMETRY + namespace nglib { + #include "nglib.h" + } + #include + ],[ + nglib::Ng_Init(); + netgen::OCCGeometry occgeo; + nglib::Ng_Exit(); + ], + [eval "salome_cv_netgen_salome_patch_lib=yes"], + [eval "salome_cv_netgen_salome_patch_lib=no"]) + ]) + Netgen_ok="$salome_cv_netgen_salome_patch_lib" + fi + + if test "x$Netgen_ok" == xno ; then + AC_MSG_RESULT(no) + AC_MSG_ERROR(Netgen is not properly installed. Read NETGENPLUGIN_SRC/src/NETGEN/ReadMeForNgUsers for details.) + fi + + NETGEN_LIBS="-L${NETGEN_LIBS_DIR} -lnglib" + + fi + + LIBS="$LIBS_old" fi CPPFLAGS="$CPPFLAGS_old" @@ -152,14 +235,21 @@ namespace nglib { if test "x$Netgen_ok" == xno ; then AC_MSG_RESULT(no) - AC_MSG_WARN(Netgen libraries not found or not properly installed) + AC_MSG_ERROR(Netgen libraries not found or not properly installed) else AC_MSG_RESULT(yes) fi + +else + + AC_MSG_ERROR(Netgen libraries not found. Please define NETGENHOME or use --with-netgen option) + fi AC_SUBST(NETGEN_INCLUDES) AC_SUBST(NETGEN_LIBS_DIR) +AC_SUBST(NETGEN_LIBS) +AM_CONDITIONAL(NETGEN_NEW, [test x"$NETGEN_NEW" = x"yes"]) AC_LANG_RESTORE diff --git a/adm_local/unix/config_files/check_NETGENPLUGIN.m4 b/adm_local/unix/config_files/check_NETGENPLUGIN.m4 index 9ceac78..6d94051 100644 --- a/adm_local/unix/config_files/check_NETGENPLUGIN.m4 +++ b/adm_local/unix/config_files/check_NETGENPLUGIN.m4 @@ -1,24 +1,25 @@ -dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +dnl Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE dnl -dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +dnl Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +dnl CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License. +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License. dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library; if not, write to the Free Software -dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA dnl -dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com dnl + #------------------------------------------------------------ # Check availability of Salome NETGEN mesh plugin module # distribution diff --git a/adm_local/unix/make_common_starter.am b/adm_local/unix/make_common_starter.am index 36ad8c3..4f70a70 100644 --- a/adm_local/unix/make_common_starter.am +++ b/adm_local/unix/make_common_starter.am @@ -1,24 +1,30 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com + +# ============================================================ +# The following is to avoid PACKAGE_... env variable +# redefinition compilation warnings +# ============================================================ # +AM_CXXFLAGS = @KERNEL_CXXFLAGS@ -include SALOMEconfig.h +AM_CPPFLAGS = @KERNEL_CXXFLAGS@ -include SALOMEconfig.h + # ============================================================ # This file defines the common definitions used in several # Makefile. This file must be included, if needed, by the file diff --git a/bin/Makefile.am b/bin/Makefile.am index 88eceb7..d636593 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # -* Makefile *- # Author : Guillaume Boulant (CSSI) # Module : KERNEL diff --git a/bin/VERSION.in b/bin/VERSION.in index b5e9383..85a021f 100755 --- a/bin/VERSION.in +++ b/bin/VERSION.in @@ -1 +1,3 @@ -THIS IS SALOME - NETGENPLUGIN VERSION: @VERSION@ +[SALOME NETGENPLUGIN] : @VERSION@ +[DEVELOPMENT] : @VERSION_DEV@ +[DESCRIPTION] : Netgen meshing plug-in for SALOME Mesh module diff --git a/build_cmake b/build_cmake new file mode 100755 index 0000000..79de542 --- /dev/null +++ b/build_cmake @@ -0,0 +1,27 @@ +#!/bin/sh +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +CURRENT_DIR=`pwd` +CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` +cd ${CONF_DIR} +python $KERNEL_ROOT_DIR/salome_adm/cmake_files/am2cmake.py --netgenplugin +status=$? +cd ${CURRENT_DIR} +exit $status diff --git a/build_cmake.bat b/build_cmake.bat new file mode 100644 index 0000000..0c3a272 --- /dev/null +++ b/build_cmake.bat @@ -0,0 +1,20 @@ +@REM Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +@REM +@REM This library is free software; you can redistribute it and/or +@REM modify it under the terms of the GNU Lesser General Public +@REM License as published by the Free Software Foundation; either +@REM version 2.1 of the License. +@REM +@REM This library is distributed in the hope that it will be useful, +@REM but WITHOUT ANY WARRANTY; without even the implied warranty of +@REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +@REM Lesser General Public License for more details. +@REM +@REM You should have received a copy of the GNU Lesser General Public +@REM License along with this library; if not, write to the Free Software +@REM Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +@REM +@REM See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +@REM + +%PYTHONBIN% %KERNEL_ROOT_DIR%\salome_adm\cmake_files\am2cmake.py --netgenplugin diff --git a/build_configure b/build_configure index 4e3b7e4..e7120c7 100755 --- a/build_configure +++ b/build_configure @@ -1,25 +1,26 @@ #!/bin/bash -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # Tool for updating list of .in file for the SALOME project # and regenerating configure script # Author : Marc Tajchman - CEA @@ -30,7 +31,6 @@ # ORIG_DIR=`pwd` CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"` -NETGENPLUGIN_WITH_GUI="yes" ######################################################################## # Test if the KERNEL_ROOT_DIR is set correctly @@ -46,27 +46,6 @@ fi # echo "failed : KERNEL_SRC variable is not correct !" # exit #fi -for option -do - case $option in - -with-gui | --with-gui) - NETGENPLUGIN_WITH_GUI="yes" - break;; - -without-gui | --without-gui | -with-gui=no | --with-gui=no) - NETGENPLUGIN_WITH_GUI="no" - break;; - esac -done - -######################################################################## -# Test if the GUI_ROOT_DIR is set correctly - -if test ${NETGENPLUGIN_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 @@ -96,40 +75,17 @@ cd ${CONF_DIR} ABS_CONF_DIR=`pwd` ####################################################################### -# Update configure.ac script: to set NETGENPLUGIN_WITH_GUI variable -sed -e s/NETGENPLUGIN_WITH_GUI=[a-z]*/NETGENPLUGIN_WITH_GUI=${NETGENPLUGIN_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 ${NETGENPLUGIN_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 \ @@ -150,10 +106,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 @@ -173,11 +129,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 f57f7b3..1f4c3ce 100755 --- a/clean_configure +++ b/clean_configure @@ -1,35 +1,28 @@ #!/bin/sh -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + rm -rf autom4te.cache aclocal.m4 configure make_config find . -name "*~" -print -exec rm {} \; find . -name "*.pyc" -print -exec rm {} \; #exit # ==================== ON SORT AVANT -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 +find . -name Makefile.in | xargs rm -f +( cd adm_local/unix/config_files && rm -f config.* depcomp install-sh ltmain.sh missing py-compile ) diff --git a/configure.ac b/configure.ac index 5855ffc..e4c8b86 100644 --- a/configure.ac +++ b/configure.ac @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # PLEASE DO NOT MODIFY configure.in FILE # ALL CHANGES WILL BE DISCARDED BY THE NEXT # build_configure COMMAND @@ -31,14 +29,16 @@ # Reorganization for usage of autotools # Created from configure.in.base # -AC_INIT([Salome2 Project NETGENPLUGIN module], [5.1.0], [webmaster.salome@opencascade.com], [SalomeNETGENPLUGIN]) -AC_CONFIG_AUX_DIR(salome_adm/unix/config_files) +AC_INIT([Salome2 Project NETGENPLUGIN module], [6.5.0], [webmaster.salome@opencascade.com], [SalomeNETGENPLUGIN]) +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=netgenplugin @@ -80,6 +80,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 ! @@ -101,7 +102,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 @@ -161,7 +162,15 @@ dnl testing MPICH dnl --------------------------------------------- dnl -CHECK_MPICH +dnl CHECK_MPICH + +echo +echo --------------------------------------------- +echo testing MPI +echo --------------------------------------------- +echo + +CHECK_MPI echo echo --------------------------------------------- @@ -237,11 +246,34 @@ AC_SUBST_FILE(CORBA) corba=make_$ORB CORBA=adm_local/unix/$corba -NETGENPLUGIN_WITH_GUI=yes +echo +echo --------------------------------------------- +echo Testing GUI +echo --------------------------------------------- +echo + +CHECK_GUI_MODULE + +gui_ok=no +if test "${SalomeGUI_need}" != "no" -a "${FullGUI_ok}" = "yes" ; then + gui_ok=yes +fi -AM_CONDITIONAL(NETGENPLUGIN_ENABLE_GUI, [test "${NETGENPLUGIN_WITH_GUI}" = "yes"]) +AM_CONDITIONAL(NETGENPLUGIN_ENABLE_GUI, [test "${gui_ok}" = "yes"]) + +if test "${SalomeGUI_need}" == "yes"; then + if test "${FullGUI_ok}" != "yes"; then + AC_MSG_WARN(For configure NETGENPLUGIN 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 "${NETGENPLUGIN_WITH_GUI}" = "yes"; then +if test "${gui_ok}" = "yes"; then echo echo --------------------------------------------- echo testing openGL @@ -257,35 +289,15 @@ if test "${NETGENPLUGIN_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 NETGENPLUGIN module necessary full GUI !" - exit - fi -fi +CHECK_VTK echo echo --------------------------------------------- @@ -357,14 +369,17 @@ echo Summary echo --------------------------------------------- echo +AM_CONDITIONAL(CMAKE_BUILD, false) #AM_CONDITIONAL( USE_GFORTRAN, [test "$F77" = "gfortran"]) echo Configure -if test "${NETGENPLUGIN_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 SMesh_ok Netgen_ok" -fi -if test "${NETGENPLUGIN_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 SMesh_ok Netgen_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 gui_ok Geom_ok SMesh_ok Netgen_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 gui_ok Geom_ok SMesh_ok Netgen_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 SMesh_ok Netgen_ok" fi for var in $variables @@ -385,6 +400,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 @@ -400,23 +418,41 @@ 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 \ - ./NETGENPLUGIN_version.h \ - ./src/Makefile \ - ./src/GUI/Makefile \ - ./src/NETGEN/Makefile \ - ./src/NETGENPlugin/Makefile \ - ./resources/Makefile \ - ./idl/Makefile \ + adm_local/Makefile \ + adm_local/unix/Makefile \ + adm_local/unix/config_files/Makefile \ + bin/VERSION \ + bin/Makefile \ + NETGENPLUGIN_version.h \ + doc/Makefile \ + doc/salome/Makefile \ + doc/salome/gui/Makefile \ + doc/salome/gui/NETGENPLUGIN/Makefile \ + doc/salome/gui/NETGENPLUGIN/doxyfile \ + doc/salome/gui/NETGENPLUGIN/doxyfile_py \ + doc/salome/gui/NETGENPLUGIN/static/header.html \ + doc/salome/gui/NETGENPLUGIN/static/header_py.html \ + src/Makefile \ + src/GUI/Makefile \ + src/NETGEN/Makefile \ + src/NETGENPlugin/Makefile \ + resources/Makefile \ + idl/Makefile \ Makefile \ ]) diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..570ccb2 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,32 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# -* Makefile *- +# Author : Patrick GOLDBRONN (CEA) +# Date : 30/11/2001 +# Modified by : Alexander BORODIN (OCN) - autotools usage +# $Header$ +# source path +# +SUBDIRS = salome + +usr_docs: + (cd salome && $(MAKE) $(AM_MAKEFLAGS) usr_docs) + +docs: usr_docs \ No newline at end of file diff --git a/doc/salome/Makefile.am b/doc/salome/Makefile.am new file mode 100644 index 0000000..9ded0be --- /dev/null +++ b/doc/salome/Makefile.am @@ -0,0 +1,34 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# -* Makefile *- +# Author : Patrick GOLDBRONN (CEA) +# Date : 30/11/2001 +# Modified by : Alexander BORODIN (OCN) - autotools usage +# $Header: +# +SUBDIRS = gui +SUBDIRSGUI = gui + +usr_docs: + @@SETX@; for d in $(SUBDIRSGUI); do \ + (cd $$d && $(MAKE) $@) || exit 1; \ + done; + +docs: usr_docs \ No newline at end of file diff --git a/doc/salome/gui/Makefile.am b/doc/salome/gui/Makefile.am new file mode 100644 index 0000000..7a41bf6 --- /dev/null +++ b/doc/salome/gui/Makefile.am @@ -0,0 +1,32 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# File : Makefile.in +# Author : Vasily Rusyaev (Open Cascade NN) +# Modified by : Alexander BORODIN (OCN) - autotools usage +# Module : doc +# +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +SUBDIRS = NETGENPLUGIN + +usr_docs: + (cd NETGENPLUGIN && $(MAKE) $(AM_MAKEFLAGS) usr_docs) + +docs: usr_docs diff --git a/doc/salome/gui/NETGENPLUGIN/Makefile.am b/doc/salome/gui/NETGENPLUGIN/Makefile.am new file mode 100755 index 0000000..c075ffe --- /dev/null +++ b/doc/salome/gui/NETGENPLUGIN/Makefile.am @@ -0,0 +1,67 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# File : Makefile.in +# Author : Vasily Rusyaev (Open Cascade NN) +# Modified by : Alexander BORODIN (OCN) - autotools usage +# 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/NETGENPLUGIN +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/NETGENPLUGIN + @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/NETGENPLUGIN ;; \ + esac ; \ + done ; + cp -rp $(srcdir)/images/head.png $(DESTDIR)$(docdir)/gui/NETGENPLUGIN/netgenpluginpy_doc ; + +uninstall-local: + rm -rf $(DESTDIR)$(docdir)/gui/NETGENPLUGIN \ No newline at end of file diff --git a/doc/salome/gui/NETGENPLUGIN/doxyfile.in b/doc/salome/gui/NETGENPLUGIN/doxyfile.in new file mode 100755 index 0000000..510aa76 --- /dev/null +++ b/doc/salome/gui/NETGENPLUGIN/doxyfile.in @@ -0,0 +1,115 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = "SALOME NETGENPLUGIN User's Guide" +OUTPUT_DIRECTORY = . +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +TAB_SIZE = 5 + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES + +#--------------------------------------------------------------------------- +#Input related options +#--------------------------------------------------------------------------- +INPUT = @srcdir@/input +FILE_PATTERNS = *.doc +EXCLUDE = +IMAGE_PATH = @srcdir@/images +EXAMPLE_PATH = + +#--------------------------------------------------------------------------- +#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 + + +#--------------------------------------------------------------------------- +# 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 + +#--------------------------------------------------------------------------- +#SORT related options +#--------------------------------------------------------------------------- +SORT_GROUP_NAMES = NO + + +#--------------------------------------------------------------------------- +#LaTeX related option +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +EXTRA_PACKAGES = amsmath + +#--------------------------------------------------------------------------- +#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 = netgenpluginpy_doc.tag=../NETGENPLUGIN/netgenpluginpy_doc +SEARCHENGINE = YES diff --git a/doc/salome/gui/NETGENPLUGIN/doxyfile_py.in b/doc/salome/gui/NETGENPLUGIN/doxyfile_py.in new file mode 100755 index 0000000..58fba65 --- /dev/null +++ b/doc/salome/gui/NETGENPLUGIN/doxyfile_py.in @@ -0,0 +1,162 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = "SALOME NETGENPLUGIN 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/NETGENPlugin/NETGENPluginDC.py +FILE_PATTERNS = +IMAGE_PATH = @srcdir@/images +RECURSIVE = NO +EXAMPLE_PATH = + +#--------------------------------------------------------------------------- +#HTML related options +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = netgenpluginpy_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 = netgenpluginpy_doc.tag +SEARCHENGINE = YES \ No newline at end of file diff --git a/doc/salome/gui/NETGENPLUGIN/images/head.png b/doc/salome/gui/NETGENPLUGIN/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/NETGENPLUGIN/images/image1.png b/doc/salome/gui/NETGENPLUGIN/images/image1.png new file mode 100755 index 0000000000000000000000000000000000000000..da6b149344cbf1f4e1d8a2c568eda29359a55417 GIT binary patch literal 17155 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 XE}LbIZJPmZslZcL)=@$!*hKw*R&g#J literal 0 HcmV?d00001 diff --git a/doc/salome/gui/NETGENPLUGIN/images/image2.gif b/doc/salome/gui/NETGENPLUGIN/images/image2.gif new file mode 100755 index 0000000000000000000000000000000000000000..198351307f7783f5771a22bb6ea363dea50a10e8 GIT binary patch literal 4694 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 BV)+07 literal 0 HcmV?d00001 diff --git a/doc/salome/gui/NETGENPLUGIN/images/netgen2d3d.png b/doc/salome/gui/NETGENPLUGIN/images/netgen2d3d.png new file mode 100644 index 0000000000000000000000000000000000000000..97b95486e44943aa4a47e11848bdebfd6fe95c7e GIT binary patch literal 32806 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
JX=1cnHu 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 literal 0 HcmV?d00001 diff --git a/doc/salome/gui/NETGENPLUGIN/images/netgen2d3d_simple.png b/doc/salome/gui/NETGENPLUGIN/images/netgen2d3d_simple.png new file mode 100644 index 0000000000000000000000000000000000000000..f8d11661024d0893cd9aed69bf91ca24ec3e9cac GIT binary patch literal 34920 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
D!7!C)a=P-1AjvOS~;kd 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 literal 0 HcmV?d00001 diff --git a/doc/salome/gui/NETGENPLUGIN/images/netgen3d_local_size.png b/doc/salome/gui/NETGENPLUGIN/images/netgen3d_local_size.png new file mode 100644 index 0000000000000000000000000000000000000000..f7bcd18b9d4d3f0855e52a03e5c8d2357e303c4f GIT binary patch literal 16229 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 V7x=OO9-l{3kX4o`l{WhD{{W_oml*&6 literal 0 HcmV?d00001 diff --git a/doc/salome/gui/NETGENPLUGIN/input/additional_hypo.doc b/doc/salome/gui/NETGENPLUGIN/input/additional_hypo.doc new file mode 100644 index 0000000..44766e8 --- /dev/null +++ b/doc/salome/gui/NETGENPLUGIN/input/additional_hypo.doc @@ -0,0 +1,28 @@ +/*! + +\page additional_hypo_page Additional Hypotheses + +\n Additional Hypotheses can be applied as a supplement to the +main hypotheses, introducing additional concepts to mesh creation. + +Following additional hypotheses can be used together with NETGEN algoritm: +
    + +
  • Quadrangle Preference - This additional hypothesis can be used together with Netgen 2D algorithm. +It allows Netgen 2D to build quadrangular meshes.
  • +
    +This hypothesis has one restriction on its work: the total quantity of +segments on all four sides of the face must be even (divisible by 2). + + +
  • Viscous Layers additional hypothesis can be used together with NETGEN 3D. +This hypothesis allows creation of layers of highly stretched prisms near +mesh boundary, which is beneficial for high quality viscous +computations. The prisms constructed on the quadrangular mesh faces are +actually the hexahedrons.
  • +
+ +For more detailed description of the described above hypothesis please refer SALOME Mesh User's Guide. +*/ + + diff --git a/doc/salome/gui/NETGENPLUGIN/input/index.doc b/doc/salome/gui/NETGENPLUGIN/input/index.doc new file mode 100644 index 0000000..df3ed3a --- /dev/null +++ b/doc/salome/gui/NETGENPLUGIN/input/index.doc @@ -0,0 +1,20 @@ +/*! + +\mainpage Introduction to NETGENPLUGIN + +\b NETGENPLUGIN plugin is destined for: +- Meshing 1D, 2D and 3D geometric entities. + - Faces are split into triangular elements. + - Volumes are split into tetrahedral (pyramidal) elements. +- Generating 3D meshes from 2D meshes, working without geometrical objects. + +To manage parameters of the NETGENPLUGIN use \subpage netgen_2d_3d_hypo_page and \subpage additional_hypo_page. + +Also all NETGENPLUGIN functionalities are accessible via +\subpage netgenplugin_python_interface_page "NETGENPLUGIN Python interface". + +\image html image1.png "Example of a triangular 2D mesh" + +\image html image2.gif "Example of a tetrahedral 3D mesh" + +*/ \ No newline at end of file diff --git a/doc/salome/gui/NETGENPLUGIN/input/netgen_2d_3d_hypo.doc b/doc/salome/gui/NETGENPLUGIN/input/netgen_2d_3d_hypo.doc new file mode 100644 index 0000000..7a75cdd --- /dev/null +++ b/doc/salome/gui/NETGENPLUGIN/input/netgen_2d_3d_hypo.doc @@ -0,0 +1,100 @@ +/*! + +\page netgen_2d_3d_hypo_page Netgen 2D and 3D hypotheses + +Netgen 2D Parameters and Netgen 3D Parameters hypotheses work only with +Netgen 1D-2D, Netgen 2D, Netgen 1D-2D-3D and +Netgen 3D algorithms. Netgen 1D-2D and Netgen +1D-2D-3D algorithms do not require definition of lower-level +hypotheses and algorithms (2D and 1D for meshing 3D objects and 1D for +meshing 2D objects). + +\image html netgen2d3d.png +
Dialog boxes of Netgen 1D-2D and Netgen +1D-2D-3D algorithms
+
+ +\image html netgen2d3d_only.png +
Dialog boxes of Netgen 2D and Netgen 3D +algorithms
+ +- Name - allows to define the name for the algorithm (Netgen +2D (or 3D) Parameters by default). +- Max Size - maximum linear dimensions for mesh cells. +- Min Size - minimum linear dimensions for mesh cells. It is +ignored if it is more than Max Size. +- Second Order - if this box is checked in, the algorithm will +create second order nodes on the mesh, which actually will become +\ref adding_quadratic_elements_page "Quadratic". +- Fineness - ranging from Very Coarse to Very Fine allows to set the +level of meshing detalization using the three parameters below. You +can select Custom to define them manually. +- Growth rate - allows to define how much the linear dimensions of +two adjacent cells can differ (i.e. 0.3 means 30%). +- Nb. Segs per Edge and Nb Segs per Radius - allows to define the +minimum number of mesh segments in which edges and radiuses will be +split. +- Allow Quadrangles - allows to use quadrangle elements in a +triangle 2D mesh. This checkbox is not present in Netgen 3D parameters +because currently building a tetrahedral mesh with quadrangle faces is +not possible. +- Optimize - if this box is checked in, the algorithm will try to +create regular (possessing even sides) elements. + +\image html netgen3d_local_size.png + +- Local sizes - allows to define size of elements on and +around specified geometrical edges and vertices. To define the local +size it is necessary to select a geometrical edge or vertex in the +object browser or in the viewer, and to click On Edge or On +Vertex correspondingly. Name of the geometrical object and +a default Value will be added in the table where the +Value can be changed. +- Remove - deletes a selected row from the table. + +\image html netgen2d3d_simple.png + +Netgen 2D simple parameters and Netgen 3D simple +parameters allow defining the size of elements for each +dimension. + +\b 1D group allows defining the size of 1D elements in either of two ways: +- Number of Segments has the same sense as \ref +number_of_segments_anchor "Number of segments" hypothesis with +equidistant distribution. +- Local Length has the same sense as \ref +average_length_anchor "Local Length" hypothesis. + +\b 2D group allows defining the size of 2D elements +- Length from edges if checked in, acts like \ref +length_from_edges_anchor "Length from Edges" hypothesis, else +- Max. Element Area defines the maximum element area like \ref +max_element_area_anchor "Max Element Area" hypothesis. +- Allow Quadrangles - allows to use quadrangle elements in a +triangle 2D mesh. This checkbox is not present in Netgen 3D simple parameters +because currently building a tetrahedral mesh with quadrangle faces is +not possible. + +\b 3D groups allows defining the size of 3D elements. +- Length from faces if checked in, the area of sides of +volumic elements will be equal to an average area of 2D elements, else +- Max. Element Volume defines the maximum element volume like +\ref max_element_volume_hypo_page "Max Element Volume" +hypothesis. + +\note Netgen algorithm does not strictly follow the input +parameters. The actual mesh can be more or less dense than +required. There are several factors in it: +- NETGEN does not actually use "NbOfSegments" parameter for discretization of +edge. This parameter is used only to define the local element size +(size at the given point), so local sizes of adjacent edges influence +each other. +- NETGEN additionally restricts the element size according to edge curvature. +- The local size of edges influences the size of close triangles. +- The order of elements and their size in the 1D mesh generated by +NETGEN differ from those in the 1D mesh generated by Regular_1D +algorithm, resulting in different 2D and 3D meshes. + +*/ + + diff --git a/doc/salome/gui/NETGENPLUGIN/input/netgenplugin_python_interface.doc b/doc/salome/gui/NETGENPLUGIN/input/netgenplugin_python_interface.doc new file mode 100644 index 0000000..87905e7 --- /dev/null +++ b/doc/salome/gui/NETGENPLUGIN/input/netgenplugin_python_interface.doc @@ -0,0 +1,59 @@ +/*! + +\page netgenplugin_python_interface_page Python Interface + +Python package \ref NETGENPluginDC "NETGENPlugin" defines several classes, destined for creation of the 2D and 3D meshes. + +Documentation for NETGENPlugin package is available in linear form grouped by classes, declared in the NETGENPluginDC.py file. + +Below you can see an example of usage of the NETGENPlugin package for mesh generation: + +\code + +import geompy +import smesh + +# create a box +box = geompy.MakeBoxDXDYDZ(10., 10., 10.) +geompy.addToStudy(box, "Box") + + +# 1. Create a triangular 2D mesh on the box with NETGEN_1D2D algorithm +triaN = smesh.Mesh(box, "Box : triangular mesh by NETGEN_1D2D") + +# create a Netgen_1D2D algorithm for solids +algo2D = triaN.Triangle(smesh.NETGEN_1D2D) + +# define hypotheses +n12_params = algo2D.Parameters() + +# define number of segments +n12_params.SetNbSegPerEdge(19) + +# define max element +n12_params.SetMaxSize(300) + +# 2. Create a tetrahedral mesh on the box with NETGEN_1D2D3D algorithm (full netgen) +tetraN = smesh.Mesh(box, "Box : tetrahedrical mesh by NETGEN_1D2D3D") + +# create a Netgen_1D2D3D algorithm for solids +algo3D = tetraN.Tetrahedron(smesh.FULL_NETGEN) + +# define hypotheses +n123_params = algo3D.Parameters() + +# define number of segments +n123_params.SetNbSegPerEdge(11) + +# define max element size +n123_params.SetMaxSize(300) + +# compute the meshes +triaN.Compute() +tetraN.Compute() + +\endcode + +*/ + + diff --git a/doc/salome/gui/NETGENPLUGIN/static/doxygen.css b/doc/salome/gui/NETGENPLUGIN/static/doxygen.css new file mode 100755 index 0000000..7a2dcbd --- /dev/null +++ b/doc/salome/gui/NETGENPLUGIN/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/NETGENPLUGIN/static/footer.html b/doc/salome/gui/NETGENPLUGIN/static/footer.html new file mode 100755 index 0000000..4c89a2b --- /dev/null +++ b/doc/salome/gui/NETGENPLUGIN/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/NETGENPLUGIN/static/header.html.in b/doc/salome/gui/NETGENPLUGIN/static/header.html.in new file mode 100755 index 0000000..4571b43 --- /dev/null +++ b/doc/salome/gui/NETGENPLUGIN/static/header.html.in @@ -0,0 +1,20 @@ + + + + + +$title + +$treeview +$search +$mathjax + + + + +
+
Version: @VERSION@
+ +
diff --git a/doc/salome/gui/NETGENPLUGIN/static/header_py.html.in b/doc/salome/gui/NETGENPLUGIN/static/header_py.html.in new file mode 100644 index 0000000..61414bb --- /dev/null +++ b/doc/salome/gui/NETGENPLUGIN/static/header_py.html.in @@ -0,0 +1,21 @@ + + + + + +$title + +$treeview +$search +$mathjax + + + + +
diff --git a/idl/Makefile.am b/idl/Makefile.am index c496875..da889b2 100644 --- a/idl/Makefile.am +++ b/idl/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # This Makefile is responsible of generating the client and server # implementation of IDL interfaces for both C++ and python usage. # The building process of the C++ files is in charge of each source @@ -28,6 +26,8 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am BASEIDL_FILES= NETGENPlugin_Algorithm.idl +BASEIDL_FILES_PY=$(BASEIDL_FILES:%.idl=%_idl.py) + # This variable defines the files to be installed dist_salomeidl_DATA = $(BASEIDL_FILES) @@ -46,7 +46,6 @@ libSalomeIDLNETGENPLUGIN_la_CPPFLAGS = \ $(SMESH_CXXFLAGS) \ @CORBA_CXXFLAGS@ \ @CORBA_INCLUDES@ \ - -I$(top_builddir)/salome_adm/unix \ -I$(top_builddir)/idl libSalomeIDLNETGENPLUGIN_la_LDFLAGS = -no-undefined -version-info=0:0:0 @@ -71,8 +70,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 \ @@ -92,9 +90,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 NETGENPlugin ; 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 @@ -108,7 +112,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/idl/NETGENPlugin_Algorithm.idl b/idl/NETGENPlugin_Algorithm.idl index f968db2..1dd6fc0 100644 --- a/idl/NETGENPlugin_Algorithm.idl +++ b/idl/NETGENPlugin_Algorithm.idl @@ -1,39 +1,41 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : NETGENPlugin_Algorithm.idl // Author : Julia DOROVSKIKH -// $Header$ // #ifndef _SMESH_NETGENALGORITHM_IDL_ #define _SMESH_NETGENALGORITHM_IDL_ #include "SALOME_Exception.idl" #include "SMESH_Hypothesis.idl" +#include "GEOM_Gen.idl" /*! * NETGENPlugin: interfaces to NETGEN related hypotheses and algorithms */ module NETGENPlugin { + typedef sequence string_array; /*! * NETGENPlugin_NETGEN_3D: interface of "Tetrahedron (Netgen)" algorithm */ @@ -72,6 +74,9 @@ module NETGENPlugin void SetMaxSize(in double value); double GetMaxSize(); + void SetMinSize(in double value); + double GetMinSize(); + void SetSecondOrder(in boolean value); boolean GetSecondOrder(); @@ -89,6 +94,15 @@ module NETGENPlugin void SetNbSegPerRadius(in double value); double GetNbSegPerRadius(); + + void SetQuadAllowed(in boolean value); + boolean GetQuadAllowed(); + + void SetLocalSizeOnShape(in GEOM::GEOM_Object GeomObj, in double localSize); + void SetLocalSizeOnEntry(in string entry, in double localSize); + double GetLocalSizeOnEntry(in string entry); + string_array GetLocalSizeEntries(); + void UnsetLocalSizeOnEntry(in string entry); }; /*! @@ -96,8 +110,20 @@ module NETGENPlugin */ interface NETGENPlugin_Hypothesis_2D : NETGENPlugin_Hypothesis { - void SetQuadAllowed(in boolean value); - boolean GetQuadAllowed(); + }; + + /*! + * interface of "NETGEN 2D parameters" hypothesis used by NETGENPlugin_NETGEN_2D_ONLY algoritm + */ + interface NETGENPlugin_Hypothesis_2D_ONLY : NETGENPlugin_Hypothesis_2D + { + }; + + /*! + * interface of "NETGEN 3D parameters" hypothesis used by NETGENPlugin_NETGEN_3D algorithm + */ + interface NETGENPlugin_Hypothesis_3D : NETGENPlugin_Hypothesis + { }; /*! @@ -139,6 +165,15 @@ module NETGENPlugin * Can be zero in case of LengthFromEdges() */ double GetMaxElementArea(); + + /*! + * Enables/disables generation of quadrangular faces + */ + void SetAllowQuadrangles(in boolean toAllow); + /*! + * Returns true if generation of quadrangular faces is enabled + */ + boolean GetAllowQuadrangles(); }; /*! diff --git a/resources/Makefile.am b/resources/Makefile.am index d11fed6..dfcdf8f 100644 --- a/resources/Makefile.am +++ b/resources/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # -* Makefile *- # Author : Patrick GOLDBRONN (CEA) # Date : 28/06/2001 diff --git a/resources/NETGENPlugin.xml b/resources/NETGENPlugin.xml index 248e1e1..2848836 100644 --- a/resources/NETGENPlugin.xml +++ b/resources/NETGENPlugin.xml @@ -1,7 +1,7 @@ +
+ +
diff --git a/src/GUI/Makefile.am b/src/GUI/Makefile.am index a2f52dc..537055e 100644 --- a/src/GUI/Makefile.am +++ b/src/GUI/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : Makefile.in # Author : Michael Sazonov # Modified by : Alexander BORODIN (OCN) - autotools usage @@ -51,8 +49,9 @@ nodist_libNETGENPluginGUI_la_SOURCES= \ # additionnal information to compil and link file libNETGENPluginGUI_la_CPPFLAGS = \ - $(QT_INCLUDES) \ $(CAS_CPPFLAGS) \ + $(NETGEN_INCLUDES) \ + $(QT_INCLUDES) \ $(PYTHON_INCLUDES) \ $(KERNEL_CXXFLAGS) \ $(GUI_CXXFLAGS) \ @@ -63,16 +62,19 @@ libNETGENPluginGUI_la_CPPFLAGS = \ $(CORBA_CXXFLAGS) \ $(CORBA_INCLUDES) \ -I$(srcdir)/../NETGENPlugin \ - -I$(top_builddir)/idl \ - -I$(top_builddir)/salome_adm/unix + -I$(top_builddir)/idl libNETGENPluginGUI_la_LDFLAGS = \ + ../../idl/libSalomeIDLNETGENPLUGIN.la \ ../NETGENPlugin/libNETGENEngine.la \ - ${SMESH_LDFLAGS} -lSMESH \ + ${QT_MT_LIBS} \ + ${GUI_LDFLAGS} -lSalomeApp -lqtx -lsuit -lSalomeObject -lLightApp \ + ${SMESH_LDFLAGS} -lSMESH -lGeomSelectionTools \ $(CAS_KERNEL) # resources files nodist_salomeres_DATA= \ NETGENPlugin_images.qm \ - NETGENPlugin_msg_en.qm + NETGENPlugin_msg_en.qm \ + NETGENPlugin_msg_fr.qm diff --git a/src/GUI/NETGENPluginGUI.cxx b/src/GUI/NETGENPluginGUI.cxx index d455547..1484062 100755 --- a/src/GUI/NETGENPluginGUI.cxx +++ b/src/GUI/NETGENPluginGUI.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin GUI: GUI for plugged-in mesher NETGENPlugin // File : NETGENPluginGUI.cxx // Author : Michael Zorin @@ -40,7 +41,8 @@ extern "C" SMESHGUI_GenericHypothesisCreator* GetHypothesisCreator( const QString& aHypType ) { SMESHGUI_GenericHypothesisCreator* aCreator = NULL; - if( aHypType=="NETGEN_Parameters_2D" || aHypType=="NETGEN_Parameters" ) + if( aHypType=="NETGEN_Parameters_2D" || aHypType=="NETGEN_Parameters" || + aHypType=="NETGEN_Parameters_2D_ONLY" || aHypType=="NETGEN_Parameters_3D" ) aCreator = new NETGENPluginGUI_HypothesisCreator( aHypType ); else if ( aHypType=="NETGEN_SimpleParameters_2D" || aHypType=="NETGEN_SimpleParameters_3D" ) diff --git a/src/GUI/NETGENPluginGUI.h b/src/GUI/NETGENPluginGUI.h index ca882b4..2b5063e 100755 --- a/src/GUI/NETGENPluginGUI.h +++ b/src/GUI/NETGENPluginGUI.h @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin GUI: GUI for plugged-in mesher NETGENPlugin // File : NETGENPluginGUI.h // Author : Alexander A. BORODIN @@ -26,7 +24,7 @@ // $Header: // #ifdef WIN32 - #ifdef NETGENPLUGIN_GUI_EXPORTS + #if defined NETGENPLUGIN_GUI_EXPORTS || defined NETGENPluginGUI_EXPORTS #define NETGENPLUGIN_GUI_EXPORT __declspec( dllexport ) #else #define NETGENPLUGIN_GUI_EXPORT __declspec( dllimport ) diff --git a/src/GUI/NETGENPluginGUI_HypothesisCreator.cxx b/src/GUI/NETGENPluginGUI_HypothesisCreator.cxx index fc9d196..58f599f 100644 --- a/src/GUI/NETGENPluginGUI_HypothesisCreator.cxx +++ b/src/GUI/NETGENPluginGUI_HypothesisCreator.cxx @@ -1,35 +1,36 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin GUI: GUI for plugged-in mesher NETGENPlugin // File : NETGENPluginGUI_HypothesisCreator.cxx // Author : Michael Zorin // Module : NETGENPlugin -// $Header: // #include "NETGENPluginGUI_HypothesisCreator.h" #include #include -#include +#include +#include #include CORBA_SERVER_HEADER(NETGENPlugin_Algorithm) @@ -37,8 +38,8 @@ #include #include - -#include +#include +#include #include #include @@ -48,21 +49,51 @@ #include #include #include +#include +#include +#include - enum Fineness - { - VeryCoarse, - Coarse, - Moderate, - Fine, - VeryFine, - UserDefined - }; +enum Fineness + { + VeryCoarse, + Coarse, + Moderate, + Fine, + VeryFine, + UserDefined + }; + +enum { + STD_TAB = 0, + LSZ_TAB +}; + +enum { + LSZ_ENTRY_COLUMN = 0, + LSZ_NAME_COLUMN, + LSZ_LOCALSIZE_COLUMN, + LSZ_NB_COLUMNS +}; + +enum { + LSZ_BTNS = 0, + LSZ_VERTEX_BTN, + LSZ_EDGE_BTN, +#ifdef NETGEN_NEW + LSZ_FACE_BTN, +#endif + LSZ_SEPARATOR2, + LSZ_REMOVE_BTN +}; NETGENPluginGUI_HypothesisCreator::NETGENPluginGUI_HypothesisCreator( const QString& theHypType ) -: SMESHGUI_GenericHypothesisCreator( theHypType ), - myIs2D(false) + : SMESHGUI_GenericHypothesisCreator( theHypType ) { + myGeomSelectionTools = NULL; + myLocalSizeMap.clear(); + myIs2D = ( theHypType.startsWith("NETGEN_Parameters_2D")); + myIsONLY = ( theHypType == "NETGEN_Parameters_2D_ONLY" || + theHypType == "NETGEN_Parameters_3D"); } NETGENPluginGUI_HypothesisCreator::~NETGENPluginGUI_HypothesisCreator() @@ -75,12 +106,19 @@ bool NETGENPluginGUI_HypothesisCreator::checkParams(QString& msg) const readParamsFromHypo( data_old ); readParamsFromWidgets( data_new ); bool res = storeParamsToHypo( data_new ); - storeParamsToHypo( data_old ); + //storeParamsToHypo( data_old ); -- issue 0021364: Dump of netgen parameters has duplicate lines res = myMaxSize->isValid(msg,true) && res; + res = myMinSize->isValid(msg,true) && res; res = myGrowthRate->isValid(msg,true) && res; ; - res = myNbSegPerEdge->isValid(msg,true) && res; - res = myNbSegPerRadius->isValid(msg,true) && res; + if ( myNbSegPerEdge ) + res = myNbSegPerEdge->isValid(msg,true) && res; + if ( myNbSegPerRadius ) + res = myNbSegPerRadius->isValid(msg,true) && res; + + if ( !res ) // -- issue 0021364: Dump of netgen parameters has duplicate lines + storeParamsToHypo( data_old ); + return res; } @@ -92,8 +130,12 @@ QFrame* NETGENPluginGUI_HypothesisCreator::buildFrame() lay->setMargin( 5 ); lay->setSpacing( 0 ); - QGroupBox* GroupC1 = new QGroupBox( tr( "SMESH_ARGUMENTS" ), fr ); - lay->addWidget( GroupC1 ); + QTabWidget* tab = new QTabWidget( fr ); + tab->setTabShape( QTabWidget::Rounded ); + tab->setTabPosition( QTabWidget::North ); + lay->addWidget( tab ); + QWidget* GroupC1 = new QWidget(); + tab->insertTab( STD_TAB, GroupC1, tr( "SMESH_ARGUMENTS" ) ); QGridLayout* aGroupLayout = new QGridLayout( GroupC1 ); aGroupLayout->setSpacing( 6 ); @@ -105,23 +147,31 @@ QFrame* NETGENPluginGUI_HypothesisCreator::buildFrame() { aGroupLayout->addWidget( new QLabel( tr( "SMESH_NAME" ), GroupC1 ), row, 0 ); myName = new QLineEdit( GroupC1 ); + myName->setMinimumWidth(160); aGroupLayout->addWidget( myName, row, 1 ); row++; } aGroupLayout->addWidget( new QLabel( tr( "NETGEN_MAX_SIZE" ), GroupC1 ), row, 0 ); - myMaxSize = new SalomeApp_DoubleSpinBox( GroupC1 ); - myMaxSize->setDecimals( 7 ); - myMaxSize->setMinimum( 1e-07 ); - myMaxSize->setMaximum( 1e+06 ); - myMaxSize->setSingleStep( 10 ); + myMaxSize = new SMESHGUI_SpinBox( GroupC1 ); + myMaxSize->RangeStepAndValidator( 1e-07, 1e+06, 10., "length_precision" ); aGroupLayout->addWidget( myMaxSize, row, 1 ); row++; - - mySecondOrder = new QCheckBox( tr( "NETGEN_SECOND_ORDER" ), GroupC1 ); - aGroupLayout->addWidget( mySecondOrder, row, 0 ); + + aGroupLayout->addWidget( new QLabel( tr( "NETGEN_MIN_SIZE" ), GroupC1 ), row, 0 ); + myMinSize = new SMESHGUI_SpinBox( GroupC1 ); + myMinSize->RangeStepAndValidator( 0.0, 1e+06, 10., "length_precision" ); + aGroupLayout->addWidget( myMinSize, row, 1 ); row++; - + + mySecondOrder = 0; + if ( !myIsONLY ) + { + mySecondOrder = new QCheckBox( tr( "NETGEN_SECOND_ORDER" ), GroupC1 ); + aGroupLayout->addWidget( mySecondOrder, row, 0 ); + row++; + } + aGroupLayout->addWidget( new QLabel( tr( "NETGEN_FINENESS" ), GroupC1 ), row, 0 ); myFineness = new QComboBox( GroupC1 ); QStringList types; @@ -132,43 +182,88 @@ QFrame* NETGENPluginGUI_HypothesisCreator::buildFrame() row++; aGroupLayout->addWidget( new QLabel( tr( "NETGEN_GROWTH_RATE" ), GroupC1 ), row, 0 ); - myGrowthRate = new SalomeApp_DoubleSpinBox( GroupC1 ); - myGrowthRate->setMinimum( 0.1 ); - myGrowthRate->setMaximum( 10 ); - myGrowthRate->setSingleStep( 0.1 ); + myGrowthRate = new SMESHGUI_SpinBox( GroupC1 ); + myGrowthRate->RangeStepAndValidator( .0001, 10., .1, "parametric_precision" ); aGroupLayout->addWidget( myGrowthRate, row, 1 ); row++; - const double VALUE_MAX = 1.0e+6; + myNbSegPerEdge = 0; + myNbSegPerRadius = 0; + if ( !myIsONLY ) + { + const double VALUE_MAX = 1.0e+6; - aGroupLayout->addWidget( new QLabel( tr( "NETGEN_SEG_PER_EDGE" ), GroupC1 ), row, 0 ); - myNbSegPerEdge = new SalomeApp_DoubleSpinBox( GroupC1 ); - myNbSegPerEdge->setMinimum( 0.2 ); - myNbSegPerEdge->setMaximum( VALUE_MAX ); // (PAL14890) max value in native netgen gui is 5 - aGroupLayout->addWidget( myNbSegPerEdge, row, 1 ); - row++; - - aGroupLayout->addWidget( new QLabel( tr( "NETGEN_SEG_PER_RADIUS" ), GroupC1 ), row, 0 ); - myNbSegPerRadius = new SalomeApp_DoubleSpinBox( GroupC1 ); - myNbSegPerRadius->setMinimum( 0.2 ); - myNbSegPerRadius->setMaximum( VALUE_MAX ); // (PAL14890) max value in native netgen gui is 5 - aGroupLayout->addWidget( myNbSegPerRadius, row, 1 ); - row++; + aGroupLayout->addWidget( new QLabel( tr( "NETGEN_SEG_PER_EDGE" ), GroupC1 ), row, 0 ); + myNbSegPerEdge = new SMESHGUI_SpinBox( GroupC1 ); + myNbSegPerEdge->RangeStepAndValidator( .2, VALUE_MAX, .1, "parametric_precision" ); + aGroupLayout->addWidget( myNbSegPerEdge, row, 1 ); + row++; - if ( hypType()=="NETGEN_Parameters_2D" ) + aGroupLayout->addWidget( new QLabel( tr( "NETGEN_SEG_PER_RADIUS" ), GroupC1 ), row, 0 ); + myNbSegPerRadius = new SMESHGUI_SpinBox( GroupC1 ); + myNbSegPerRadius->RangeStepAndValidator( .2, VALUE_MAX, .1, "parametric_precision" ); + aGroupLayout->addWidget( myNbSegPerRadius, row, 1 ); + row++; + } + myAllowQuadrangles = 0; + if ( true /*myIs2D*/ ) // issue 0021676 { myAllowQuadrangles = new QCheckBox( tr( "NETGEN_ALLOW_QUADRANGLES" ), GroupC1 ); aGroupLayout->addWidget( myAllowQuadrangles, row, 0 ); - myIs2D = true; row++; } myOptimize = new QCheckBox( tr( "NETGEN_OPTIMIZE" ), GroupC1 ); aGroupLayout->addWidget( myOptimize, row, 0 ); row++; - + connect( myFineness, SIGNAL( activated( int ) ), this, SLOT( onFinenessChanged() ) ); - + + myLocalSizeTable = 0; + if ( !myIsONLY ) + { + QWidget* localSizeGroup = new QWidget(); + QGridLayout* localSizeLayout = new QGridLayout(localSizeGroup); + + myLocalSizeTable = new QTableWidget(0, LSZ_NB_COLUMNS, localSizeGroup); + localSizeLayout->addWidget(myLocalSizeTable, 1, 0, 8, 1); + QStringList localSizeHeaders; + localSizeHeaders << tr( "LSZ_ENTRY_COLUMN" )<< tr( "LSZ_NAME_COLUMN" ) << tr( "LSZ_LOCALSIZE_COLUMN" ); + myLocalSizeTable->setHorizontalHeaderLabels(localSizeHeaders); + myLocalSizeTable->horizontalHeader()->hideSection(LSZ_ENTRY_COLUMN); + myLocalSizeTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive); + myLocalSizeTable->resizeColumnToContents(LSZ_NAME_COLUMN); + myLocalSizeTable->resizeColumnToContents(LSZ_LOCALSIZE_COLUMN); + myLocalSizeTable->setAlternatingRowColors(true); + myLocalSizeTable->verticalHeader()->hide(); + + QPushButton* addVertexButton = new QPushButton(tr("NETGEN_LSZ_VERTEX"), localSizeGroup); + localSizeLayout->addWidget(addVertexButton, LSZ_VERTEX_BTN, 1, 1, 1); + QPushButton* addEdgeButton = new QPushButton(tr("NETGEN_LSZ_EDGE"), localSizeGroup); + localSizeLayout->addWidget(addEdgeButton, LSZ_EDGE_BTN, 1, 1, 1); +#ifdef NETGEN_NEW + QPushButton* addFaceButton = new QPushButton(tr("NETGEN_LSZ_FACE"), localSizeGroup); + localSizeLayout->addWidget(addFaceButton, LSZ_FACE_BTN, 1, 1, 1); +#endif + + QFrame *line2 = new QFrame(localSizeGroup); + line2->setFrameShape(QFrame::HLine); + line2->setFrameShadow(QFrame::Sunken); + localSizeLayout->addWidget(line2, LSZ_SEPARATOR2, 1, 1, 1); + + QPushButton* removeButton = new QPushButton(tr("NETGEN_LSZ_REMOVE"), localSizeGroup); + localSizeLayout->addWidget(removeButton, LSZ_REMOVE_BTN, 1, 1, 1); + + connect( addVertexButton, SIGNAL(clicked()), this, SLOT(onAddLocalSizeOnVertex())); + connect( addEdgeButton, SIGNAL(clicked()), this, SLOT(onAddLocalSizeOnEdge())); +#ifdef NETGEN_NEW + connect( addFaceButton, SIGNAL(clicked()), this, SLOT(onAddLocalSizeOnFace())); +#endif + connect( removeButton, SIGNAL(clicked()), this, SLOT(onRemoveLocalSizeOnShape())); + connect( myLocalSizeTable, SIGNAL(cellChanged(int, int)), this, SLOT(onSetLocalSize(int, int))); + + tab->insertTab(LSZ_TAB, localSizeGroup, tr("NETGEN_LOCAL_SIZE")); + } return fr; } @@ -183,9 +278,16 @@ void NETGENPluginGUI_HypothesisCreator::retrieveParams() const myMaxSize->setValue( data.myMaxSize ); else myMaxSize->setText( data.myMaxSizeVar ); - - mySecondOrder->setChecked( data.mySecondOrder ); - myOptimize->setChecked( data.myOptimize ); + + if(data.myMinSizeVar.isEmpty()) + myMinSize->setValue( data.myMinSize ); + else + myMinSize->setText( data.myMinSizeVar ); + + if ( mySecondOrder ) + mySecondOrder->setChecked( data.mySecondOrder ); + if ( myOptimize ) + myOptimize->setChecked( data.myOptimize ); myFineness->setCurrentIndex( data.myFineness ); if(data.myGrowthRateVar.isEmpty()) @@ -193,24 +295,53 @@ void NETGENPluginGUI_HypothesisCreator::retrieveParams() const else myGrowthRate->setText( data.myGrowthRateVar ); - if(data.myNbSegPerEdgeVar.isEmpty()) - myNbSegPerEdge->setValue( data.myNbSegPerEdge ); - else - myNbSegPerEdge->setText( data.myNbSegPerEdgeVar ); - - if(data.myNbSegPerRadiusVar.isEmpty()) - myNbSegPerRadius->setValue( data.myNbSegPerRadius ); - else - myNbSegPerRadius->setText( data.myNbSegPerRadiusVar ); - - if (myIs2D) + if ( myNbSegPerEdge ) + { + if(data.myNbSegPerEdgeVar.isEmpty()) + myNbSegPerEdge->setValue( data.myNbSegPerEdge ); + else + myNbSegPerEdge->setText( data.myNbSegPerEdgeVar ); + } + if ( myNbSegPerRadius ) + { + if(data.myNbSegPerRadiusVar.isEmpty()) + myNbSegPerRadius->setValue( data.myNbSegPerRadius ); + else + myNbSegPerRadius->setText( data.myNbSegPerRadiusVar ); + } + if (myAllowQuadrangles) myAllowQuadrangles->setChecked( data.myAllowQuadrangles ); // update widgets bool isCustom = (myFineness->currentIndex() == UserDefined); myGrowthRate->setEnabled(isCustom); - myNbSegPerEdge->setEnabled(isCustom); - myNbSegPerRadius->setEnabled(isCustom); + if ( myNbSegPerEdge ) + myNbSegPerEdge->setEnabled(isCustom); + if ( myNbSegPerRadius ) + myNbSegPerRadius->setEnabled(isCustom); + + if ( myLocalSizeTable ) + { + NETGENPluginGUI_HypothesisCreator* that = (NETGENPluginGUI_HypothesisCreator*)this; + QMapIterator i(myLocalSizeMap); + GeomSelectionTools* geomSelectionTools = that->getGeomSelectionTools(); + while (i.hasNext()) { + i.next(); + const QString entry = i.key(); + std::string shapeName = geomSelectionTools->getNameFromEntry(entry.toStdString()); + const QString localSize = i.value(); + int row = myLocalSizeTable->rowCount(); + myLocalSizeTable->setRowCount(row+1); + myLocalSizeTable->setItem(row, LSZ_ENTRY_COLUMN, new QTableWidgetItem(entry)); + myLocalSizeTable->item(row, LSZ_ENTRY_COLUMN)->setFlags(0); + myLocalSizeTable->setItem(row, LSZ_NAME_COLUMN, new QTableWidgetItem(QString::fromStdString(shapeName))); + myLocalSizeTable->item(row, LSZ_NAME_COLUMN)->setFlags(0); + myLocalSizeTable->setItem(row, LSZ_LOCALSIZE_COLUMN, new QTableWidgetItem(localSize)); + myLocalSizeTable->item(row, LSZ_LOCALSIZE_COLUMN)->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEditable|Qt::ItemIsEnabled); + } + myLocalSizeTable->resizeColumnToContents(LSZ_NAME_COLUMN); + myLocalSizeTable->resizeColumnToContents(LSZ_LOCALSIZE_COLUMN); + } } QString NETGENPluginGUI_HypothesisCreator::storeParams() const @@ -220,6 +351,7 @@ QString NETGENPluginGUI_HypothesisCreator::storeParams() const storeParamsToHypo( data ); QString valStr = tr("NETGEN_MAX_SIZE") + " = " + QString::number( data.myMaxSize ) + "; "; + valStr += tr("NETGEN_MIN_SIZE") + " = " + QString::number( data.myMinSize ) + "; "; if ( data.mySecondOrder ) valStr += tr("NETGEN_SECOND_ORDER") + "; "; if ( data.myOptimize ) @@ -242,30 +374,49 @@ bool NETGENPluginGUI_HypothesisCreator::readParamsFromHypo( NetgenHypothesisData HypothesisData* data = SMESH::GetHypothesisData( hypType() ); h_data.myName = isCreation() && data ? data->Label : ""; - SMESH::ListOfParameters_var aParameters = h->GetLastParameters(); - h_data.myMaxSize = h->GetMaxSize(); - h_data.myMaxSizeVar = (aParameters->length() > 0) ? QString(aParameters[0].in()) : QString(""); + h_data.myMaxSizeVar = getVariableName("SetMaxSize"); h_data.mySecondOrder = h->GetSecondOrder(); h_data.myOptimize = h->GetOptimize(); h_data.myFineness = (int) h->GetFineness(); h_data.myGrowthRate = h->GetGrowthRate(); - h_data.myGrowthRateVar = (aParameters->length() > 1) ? QString(aParameters[1].in()) : QString(""); + h_data.myGrowthRateVar = getVariableName("SetGrowthRate"); h_data.myNbSegPerEdge = h->GetNbSegPerEdge(); - h_data.myNbSegPerEdgeVar = (aParameters->length() > 2) ? QString(aParameters[2].in()) : QString(""); + h_data.myNbSegPerEdgeVar = getVariableName("SetNbSegPerEdge"); h_data.myNbSegPerRadius = h->GetNbSegPerRadius(); - h_data.myNbSegPerRadiusVar = (aParameters->length() > 3) ? QString(aParameters[3].in()) : QString(""); + h_data.myNbSegPerRadiusVar = getVariableName("SetNbSegPerRadius"); + h_data.myMinSize = h->GetMinSize(); + h_data.myMinSizeVar = getVariableName("SetMinSize"); if ( myIs2D ) { NETGENPlugin::NETGENPlugin_Hypothesis_2D_var h_2d = - NETGENPlugin::NETGENPlugin_Hypothesis_2D::_narrow( initParamsHypothesis() ); + NETGENPlugin::NETGENPlugin_Hypothesis_2D::_narrow( initParamsHypothesis() ); if ( !h_2d->_is_nil() ) - h_data.myAllowQuadrangles = h_2d->GetQuadAllowed(); + h_data.myAllowQuadrangles = h_2d->GetQuadAllowed(); } + NETGENPluginGUI_HypothesisCreator* that = (NETGENPluginGUI_HypothesisCreator*)this; + NETGENPlugin::string_array_var myEntries = h->GetLocalSizeEntries(); + for ( int i=0 ; ilength() ; i++ ) + { + QString entry = myEntries[i].in(); + double val = h->GetLocalSizeOnEntry(entry.toStdString().c_str()); + std::ostringstream tmp; + tmp << val; + QString valstring = QString::fromStdString(tmp.str()); + if (myLocalSizeMap.contains(entry)) + { + if (myLocalSizeMap[entry] == "__TO_DELETE__") + { + continue; + } + } + that->myLocalSizeMap[entry] = valstring; + } + return true; } @@ -279,9 +430,8 @@ bool NETGENPluginGUI_HypothesisCreator::storeParamsToHypo( const NetgenHypothesi { if( isCreation() ) SMESH::SetName( SMESH::FindSObject( h ), h_data.myName.toLatin1().data() ); - QStringList aVariablesList; + h->SetVarParameter( h_data.myMaxSizeVar.toLatin1().constData(), "SetMaxSize"); h->SetMaxSize( h_data.myMaxSize ); - aVariablesList.append(h_data.myMaxSizeVar); h->SetSecondOrder( h_data.mySecondOrder ); h->SetOptimize( h_data.myOptimize ); int fineness = h_data.myFineness; @@ -289,32 +439,42 @@ bool NETGENPluginGUI_HypothesisCreator::storeParamsToHypo( const NetgenHypothesi if( fineness==UserDefined ) { - h->SetGrowthRate( h_data.myGrowthRate ); - h->SetNbSegPerEdge( h_data.myNbSegPerEdge ); - h->SetNbSegPerRadius( h_data.myNbSegPerRadius ); - - aVariablesList.append(h_data.myGrowthRateVar); - aVariablesList.append(h_data.myNbSegPerEdgeVar); - aVariablesList.append(h_data.myNbSegPerRadiusVar); + h->SetVarParameter( h_data.myGrowthRateVar.toLatin1().constData(), "SetGrowthRate"); + h->SetGrowthRate( h_data.myGrowthRate ); + h->SetVarParameter( h_data.myNbSegPerEdgeVar.toLatin1().constData(), "SetNbSegPerEdge"); + h->SetNbSegPerEdge( h_data.myNbSegPerEdge ); + h->SetVarParameter( h_data.myNbSegPerRadiusVar.toLatin1().constData(), "SetNbSegPerRadius"); + h->SetNbSegPerRadius( h_data.myNbSegPerRadius ); } + h->SetVarParameter( h_data.myMinSizeVar.toLatin1().constData(), "SetMinSize"); + h->SetMinSize( h_data.myMinSize ); if ( myIs2D ) { - NETGENPlugin::NETGENPlugin_Hypothesis_2D_var h_2d = - NETGENPlugin::NETGENPlugin_Hypothesis_2D::_narrow( h ); - - if ( !h_2d->_is_nil() ) - h_2d->SetQuadAllowed( h_data.myAllowQuadrangles ); + NETGENPlugin::NETGENPlugin_Hypothesis_2D_var h_2d = + NETGENPlugin::NETGENPlugin_Hypothesis_2D::_narrow( h ); + + if ( !h_2d->_is_nil() ) + h_2d->SetQuadAllowed( h_data.myAllowQuadrangles ); } - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); - if( fineness==UserDefined ) - { - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); - } - + QMapIterator i(myLocalSizeMap); + while (i.hasNext()) { + i.next(); + const QString entry = i.key(); + const QString localSize = i.value(); + if (localSize == "__TO_DELETE__") + { + h->UnsetLocalSizeOnEntry(entry.toLatin1().constData()); + } + else + { + std::istringstream tmp(localSize.toLatin1().constData()); + double val; + tmp >> val; + h->SetLocalSizeOnEntry(entry.toLatin1().constData(), val); + } + } } catch(const SALOME::SALOME_Exception& ex) { @@ -329,21 +489,40 @@ bool NETGENPluginGUI_HypothesisCreator::readParamsFromWidgets( NetgenHypothesisD h_data.myName = myName ? myName->text() : ""; h_data.myMaxSize = myMaxSize->value(); h_data.myMaxSizeVar = myMaxSize->text(); - h_data.mySecondOrder = mySecondOrder->isChecked(); - h_data.myOptimize = myOptimize->isChecked(); + h_data.myMinSize = myMinSize->value(); + h_data.myMinSizeVar = myMinSize->text(); + if ( mySecondOrder ) + h_data.mySecondOrder = mySecondOrder->isChecked(); + if ( myOptimize ) + h_data.myOptimize = myOptimize->isChecked(); h_data.myFineness = myFineness->currentIndex(); h_data.myGrowthRate = myGrowthRate->value(); - h_data.myNbSegPerEdge = myNbSegPerEdge->value(); - h_data.myNbSegPerRadius = myNbSegPerRadius->value(); + if ( myNbSegPerEdge ) + h_data.myNbSegPerEdge = myNbSegPerEdge->value(); + if ( myNbSegPerRadius ) + h_data.myNbSegPerRadius = myNbSegPerRadius->value(); - h_data.myGrowthRateVar = myGrowthRate->text(); - h_data.myNbSegPerEdgeVar = myNbSegPerEdge->text(); - h_data.myNbSegPerRadiusVar = myNbSegPerRadius->text(); + h_data.myGrowthRateVar = myGrowthRate->text(); + if ( myNbSegPerEdge ) + h_data.myNbSegPerEdgeVar = myNbSegPerEdge->text(); + if ( myNbSegPerRadius ) + h_data.myNbSegPerRadiusVar = myNbSegPerRadius->text(); - if ( myIs2D ) + if ( myAllowQuadrangles ) h_data.myAllowQuadrangles = myAllowQuadrangles->isChecked(); - + + if ( myLocalSizeTable ) + { + NETGENPluginGUI_HypothesisCreator* that = (NETGENPluginGUI_HypothesisCreator*)this; + int nbRows = myLocalSizeTable->rowCount(); + for(int row=0 ; row < nbRows ; row++) + { + QString entry = myLocalSizeTable->item(row, LSZ_ENTRY_COLUMN)->text(); + QString localSize = myLocalSizeTable->item(row, LSZ_LOCALSIZE_COLUMN)->text().trimmed(); + that->myLocalSizeMap[entry] = localSize; + } + } return true; } @@ -352,49 +531,175 @@ void NETGENPluginGUI_HypothesisCreator::onFinenessChanged() bool isCustom = (myFineness->currentIndex() == UserDefined); myGrowthRate->setEnabled(isCustom); - myNbSegPerEdge->setEnabled(isCustom); - myNbSegPerRadius->setEnabled(isCustom); + if ( myNbSegPerEdge ) + myNbSegPerEdge->setEnabled(isCustom); + if ( myNbSegPerRadius ) + myNbSegPerRadius->setEnabled(isCustom); if (!isCustom) { double aGrowthRate, aNbSegPerEdge, aNbSegPerRadius; switch ( myFineness->currentIndex() ) - { - case VeryCoarse: - aGrowthRate = 0.7; - aNbSegPerEdge = 0.3; - aNbSegPerRadius = 1; - break; - case Coarse: - aGrowthRate = 0.5; - aNbSegPerEdge = 0.5; - aNbSegPerRadius = 1.5; - break; - case Fine: - aGrowthRate = 0.2; - aNbSegPerEdge = 2; - aNbSegPerRadius = 3; - break; - case VeryFine: - aGrowthRate = 0.1; - aNbSegPerEdge = 3; - aNbSegPerRadius = 5; - break; - case Moderate: - default: - aGrowthRate = 0.3; - aNbSegPerEdge = 1; - aNbSegPerRadius = 2; - break; - } + { + case VeryCoarse: + aGrowthRate = 0.7; + aNbSegPerEdge = 0.3; + aNbSegPerRadius = 1; + break; + case Coarse: + aGrowthRate = 0.5; + aNbSegPerEdge = 0.5; + aNbSegPerRadius = 1.5; + break; + case Fine: + aGrowthRate = 0.2; + aNbSegPerEdge = 2; + aNbSegPerRadius = 3; + break; + case VeryFine: + aGrowthRate = 0.1; + aNbSegPerEdge = 3; + aNbSegPerRadius = 5; + break; + case Moderate: + default: + aGrowthRate = 0.3; + aNbSegPerEdge = 1; + aNbSegPerRadius = 2; + break; + } myGrowthRate->setValue( aGrowthRate ); - myNbSegPerEdge->setValue( aNbSegPerEdge ); - myNbSegPerRadius->setValue( aNbSegPerRadius ); + if ( myNbSegPerEdge ) + myNbSegPerEdge->setValue( aNbSegPerEdge ); + if ( myNbSegPerRadius ) + myNbSegPerRadius->setValue( aNbSegPerRadius ); } } +void NETGENPluginGUI_HypothesisCreator::onAddLocalSizeOnVertex() +{ + addLocalSizeOnShape(TopAbs_VERTEX); +} + +void NETGENPluginGUI_HypothesisCreator::onAddLocalSizeOnEdge() +{ + addLocalSizeOnShape(TopAbs_EDGE); +} + +void NETGENPluginGUI_HypothesisCreator::onAddLocalSizeOnFace() +{ + addLocalSizeOnShape(TopAbs_FACE); +} + +void NETGENPluginGUI_HypothesisCreator::addLocalSizeOnShape(TopAbs_ShapeEnum typeShapeAsked) +{ + NETGENPlugin::NETGENPlugin_Hypothesis_var h = NETGENPlugin::NETGENPlugin_Hypothesis::_narrow(initParamsHypothesis()); + GeomSelectionTools* geomSelectionTools = getGeomSelectionTools(); + LightApp_SelectionMgr* mySel = geomSelectionTools->selectionMgr(); + SALOME_ListIO ListSelectedObjects; + mySel->selectedObjects(ListSelectedObjects, NULL, false ); + SALOME_ListIteratorOfListIO Object_It(ListSelectedObjects); + for (Object_It ; Object_It.More() ; Object_It.Next()) + { + Handle(SALOME_InteractiveObject) anObject = Object_It.Value(); + std::string entry, shapeName; + entry = geomSelectionTools->getEntryOfObject(anObject); + shapeName = anObject->getName(); + TopAbs_ShapeEnum shapeType; + shapeType = geomSelectionTools->entryToShapeType(entry); + if (shapeType == TopAbs_SHAPE) + { + // E.A. if shapeType == TopAbs_SHAPE, it is NOT a TopoDS_Shape !!! + continue; + } + // -- + if(shapeType != typeShapeAsked) + { + continue; + } + // -- + myLocalSizeTable->setFocus(); + QString shapeEntry; + shapeEntry = QString::fromStdString(entry); + if (myLocalSizeMap.contains(shapeEntry)) + { + if (myLocalSizeMap[shapeEntry] != "__TO_DELETE__") + { + continue; + } + } + double phySize = h->GetMaxSize(); + std::ostringstream oss; + oss << phySize; + QString localSize; + localSize = QString::fromStdString(oss.str()); + // -- + int row = myLocalSizeTable->rowCount() ; + myLocalSizeTable->setRowCount(row+1); + myLocalSizeTable->setItem(row, LSZ_ENTRY_COLUMN, new QTableWidgetItem(shapeEntry)); + myLocalSizeTable->item(row, LSZ_ENTRY_COLUMN )->setFlags(0); + myLocalSizeTable->setItem(row, LSZ_NAME_COLUMN, new QTableWidgetItem(QString::fromStdString(shapeName))); + myLocalSizeTable->item(row, LSZ_NAME_COLUMN )->setFlags(0); + myLocalSizeTable->setItem(row, LSZ_LOCALSIZE_COLUMN, new QTableWidgetItem(localSize)); + myLocalSizeTable->item(row, LSZ_LOCALSIZE_COLUMN )->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEditable|Qt::ItemIsEnabled); + myLocalSizeTable->resizeColumnToContents(LSZ_NAME_COLUMN); + myLocalSizeTable->resizeColumnToContents(LSZ_LOCALSIZE_COLUMN); + myLocalSizeTable->clearSelection(); + myLocalSizeTable->scrollToItem( myLocalSizeTable->item( row, LSZ_LOCALSIZE_COLUMN ) ); + // -- + } +} + +void NETGENPluginGUI_HypothesisCreator::onRemoveLocalSizeOnShape() +{ + QList selectedRows; + QList selected = myLocalSizeTable->selectedItems(); + QTableWidgetItem* item; + int row; + foreach(item, selected) { + row = item->row(); + if (!selectedRows.contains(row)) + selectedRows.append( row ); + } + qSort( selectedRows ); + QListIterator it( selectedRows ); + it.toBack(); + while (it.hasPrevious()) + { + row = it.previous(); + QString entry = myLocalSizeTable->item(row,LSZ_ENTRY_COLUMN)->text(); + if (myLocalSizeMap.contains(entry)) + { + myLocalSizeMap[entry] = "__TO_DELETE__"; + } + myLocalSizeTable->removeRow(row ); + } + myLocalSizeTable->resizeColumnToContents(LSZ_NAME_COLUMN); + myLocalSizeTable->resizeColumnToContents(LSZ_LOCALSIZE_COLUMN); +} + +void NETGENPluginGUI_HypothesisCreator::onSetLocalSize(int row,int col) +{ + if (col == LSZ_LOCALSIZE_COLUMN) { + QString entry = myLocalSizeTable->item(row, LSZ_ENTRY_COLUMN)->text(); + QString localSize = myLocalSizeTable->item(row, LSZ_LOCALSIZE_COLUMN)->text().trimmed(); + myLocalSizeMap[entry] = localSize; + myLocalSizeTable->resizeColumnToContents(LSZ_LOCALSIZE_COLUMN); + } +} + +GeomSelectionTools* NETGENPluginGUI_HypothesisCreator::getGeomSelectionTools() +{ + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + if (myGeomSelectionTools == NULL || myGeomSelectionTools->getMyStudy() != aStudy) { + delete myGeomSelectionTools; + myGeomSelectionTools = new GeomSelectionTools(aStudy); + } + return myGeomSelectionTools; +} + QString NETGENPluginGUI_HypothesisCreator::caption() const { return tr( QString( "NETGEN_%1_TITLE" ).arg(myIs2D?QString("2D"):QString("3D")).toLatin1().data() ); diff --git a/src/GUI/NETGENPluginGUI_HypothesisCreator.h b/src/GUI/NETGENPluginGUI_HypothesisCreator.h index a23739e..f636dcc 100644 --- a/src/GUI/NETGENPluginGUI_HypothesisCreator.h +++ b/src/GUI/NETGENPluginGUI_HypothesisCreator.h @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin GUI: GUI for plugged-in mesher NETGENPlugin // File : NETGENPluginGUI_HypothesisCreator.h // Author : Michael Zorin @@ -32,18 +33,22 @@ #include -class SalomeApp_DoubleSpinBox; +#include + +class SMESHGUI_SpinBox; +class GeomSelectionTools; class QComboBox; class QCheckBox; class QLineEdit; +class QTableWidget; typedef struct { - double myMaxSize, myGrowthRate, myNbSegPerEdge, myNbSegPerRadius; + double myMaxSize, myMinSize, myGrowthRate, myNbSegPerEdge, myNbSegPerRadius; int myFineness; bool mySecondOrder, myAllowQuadrangles, myOptimize; QString myName; - QString myMaxSizeVar, myGrowthRateVar, myNbSegPerEdgeVar, myNbSegPerRadiusVar; + QString myMaxSizeVar, myMinSizeVar, myGrowthRateVar, myNbSegPerEdgeVar, myNbSegPerRadiusVar; } NetgenHypothesisData; /*! @@ -71,24 +76,37 @@ protected: protected slots: virtual void onFinenessChanged(); + virtual void onAddLocalSizeOnVertex(); + virtual void onAddLocalSizeOnEdge(); + virtual void onAddLocalSizeOnFace(); + virtual void onRemoveLocalSizeOnShape(); + virtual void onSetLocalSize(int,int); private: bool readParamsFromHypo( NetgenHypothesisData& ) const; bool readParamsFromWidgets( NetgenHypothesisData& ) const; bool storeParamsToHypo( const NetgenHypothesisData& ) const; + GeomSelectionTools* getGeomSelectionTools(); + void addLocalSizeOnShape(TopAbs_ShapeEnum); private: QLineEdit* myName; - SalomeApp_DoubleSpinBox* myMaxSize; + SMESHGUI_SpinBox* myMaxSize; + SMESHGUI_SpinBox* myMinSize; QCheckBox* mySecondOrder; QCheckBox* myOptimize; QComboBox* myFineness; - SalomeApp_DoubleSpinBox* myGrowthRate; - SalomeApp_DoubleSpinBox* myNbSegPerEdge; - SalomeApp_DoubleSpinBox* myNbSegPerRadius; + SMESHGUI_SpinBox* myGrowthRate; + SMESHGUI_SpinBox* myNbSegPerEdge; + SMESHGUI_SpinBox* myNbSegPerRadius; QCheckBox* myAllowQuadrangles; bool myIs2D; + bool myIsONLY; + + QTableWidget* myLocalSizeTable; + GeomSelectionTools* myGeomSelectionTools; + QMap myLocalSizeMap; }; #endif diff --git a/src/GUI/NETGENPluginGUI_SimpleCreator.cxx b/src/GUI/NETGENPluginGUI_SimpleCreator.cxx index 596a34d..12fa4b8 100644 --- a/src/GUI/NETGENPluginGUI_SimpleCreator.cxx +++ b/src/GUI/NETGENPluginGUI_SimpleCreator.cxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : NETGENPluginGUI_SimpleCreator.cxx // Author : Open CASCADE S.A.S. // SMESH includes @@ -28,7 +26,6 @@ #include #include #include -#include // IDL includes #include CORBA_SERVER_HEADER(NETGENPlugin_Algorithm) @@ -74,6 +71,7 @@ NETGENPluginGUI_SimpleCreator::NETGENPluginGUI_SimpleCreator(const QString& theH myLengthRadioBut(0), myLenFromEdgesCheckBox(0), myArea(0), + myAllowQuadCheckBox(0), myLenFromFacesCheckBox(0), myVolume(0) { @@ -86,12 +84,15 @@ NETGENPluginGUI_SimpleCreator::~NETGENPluginGUI_SimpleCreator() bool NETGENPluginGUI_SimpleCreator::checkParams(QString& msg) const { bool result = true; - result = myNbSeg->isValid(msg,true) && result; - result = myLength->isValid(msg,true) && result; - result = myArea->isValid(msg,true) && result; - if (myVolume) + if ( myNbSeg->isEnabled() ) + result = myNbSeg->isValid(msg,true) && result; + if ( myLength->isEnabled() ) + result = myLength->isValid(msg,true) && result; + if ( myArea->isEnabled() ) + result = myArea->isValid(msg,true) && result; + if (myVolume && myVolume->isEnabled() ) result = myVolume->isValid(msg,true) && result; - + return result; } @@ -151,7 +152,7 @@ QFrame* NETGENPluginGUI_SimpleCreator::buildFrame() // * local length myLengthRadioBut = new QRadioButton( tr( "SMESH_LOCAL_LENGTH_HYPOTHESIS" ), dimGroup ); myLength = new SMESHGUI_SpinBox( dimGroup ); - myLength->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 0.1, 6 ); + myLength->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 0.1, "length_precision" ); myLength->setValue( 1. ); dimLay->addWidget( myLengthRadioBut, dimRow, 0 ); dimLay->addWidget( myLength, dimRow, 1 ); @@ -178,13 +179,22 @@ QFrame* NETGENPluginGUI_SimpleCreator::buildFrame() // * max area dimLay->addWidget( new QLabel( tr( "SMESH_MAX_ELEMENT_AREA_HYPOTHESIS" ), dimGroup), dimRow, 0); myArea = new SMESHGUI_SpinBox( dimGroup ); - myArea->RangeStepAndValidator( VALUE_SMALL_2, VALUE_MAX_2, 0.1, 6 ); + myArea->RangeStepAndValidator( VALUE_SMALL_2, VALUE_MAX_2, 0.1, "area_precision" ); myArea->setValue( 1. ); dimLay->addWidget( myArea, dimRow, 1 ); dimRow++; + // * allow quadrangles + const bool is3D = ( hypType()=="NETGEN_SimpleParameters_3D" ); + if ( !is3D ) + { + myAllowQuadCheckBox = new QCheckBox( tr( "NETGEN_ALLOW_QUADRANGLES" ), dimGroup ); + dimLay->addWidget( myAllowQuadCheckBox, dimRow, 0, 1, 2 ); + dimRow++; + } + // 3D params group - if ( hypType()=="NETGEN_SimpleParameters_3D" ) + if ( is3D ) { dimGroup = new QGroupBox( tr( "NG_3D" ), argGroup ); argLay->addWidget( dimGroup, argRow, 0, 1, 2 ); @@ -205,7 +215,7 @@ QFrame* NETGENPluginGUI_SimpleCreator::buildFrame() // * max volume dimLay->addWidget(new QLabel( tr("SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS"), dimGroup), dimRow, 0); myVolume = new SMESHGUI_SpinBox( dimGroup ); - myVolume->RangeStepAndValidator( VALUE_SMALL_3, VALUE_MAX_3, 0.1, 6 ); + myVolume->RangeStepAndValidator( VALUE_SMALL_3, VALUE_MAX_3, 0.1, "volume_precision" ); myVolume->setValue( 1. ); dimLay->addWidget( myVolume, dimRow, 1 ); dimRow++; @@ -225,20 +235,18 @@ void NETGENPluginGUI_SimpleCreator::retrieveParams() const if ( isCreation() ) myName->setText( hypName() ); - // set default real values + // Set default values NETGENPlugin_SimpleHypothesis_2D_var h = NETGENPlugin_SimpleHypothesis_2D::_narrow( initParamsHypothesis( hasInitParamsHypothesis() )); - if ( double len = h->GetLocalLength() ) + int dfltNbSeg = (int) h->GetNumberOfSegments(); + myNbSeg->setValue( dfltNbSeg ); + if ( double len = h->GetLocalLength() ) { myLength->setValue( len ); - if ( double area = h->GetMaxElementArea() ) - myArea->setValue( area ); - if ( myVolume ) { - NETGENPlugin_SimpleHypothesis_3D_var h3d = - NETGENPlugin_SimpleHypothesis_3D::_narrow( initParamsHypothesis( hasInitParamsHypothesis()) ); - if ( double volume = (double) h3d->GetMaxElementVolume() ) - myVolume->setValue( volume ); + myArea->setValue( len * len ); + if ( myVolume ) + myVolume->setValue( len * len * len ); } h = NETGENPlugin_SimpleHypothesis_2D::_narrow( hypothesis() ); @@ -248,14 +256,14 @@ void NETGENPluginGUI_SimpleCreator::retrieveParams() const SMESH::ListOfParameters_var aParameters = h->GetLastParameters(); // 1D - int nbSeg = (int) h->GetNumberOfSegments(); + int nbSeg = isCreation() ? dfltNbSeg : (int) h->GetNumberOfSegments(); myNbSegRadioBut->setChecked( nbSeg ); myLengthRadioBut->setChecked( !nbSeg ); QString aPrm; if ( nbSeg ) { myLength->setEnabled( false ); myNbSeg->setEnabled( true ); - aPrm = (aParameters->length() > 0) ? QString(aParameters[0].in()) : QString(""); + aPrm = getVariableName("SetNumberOfSegments"); if(aPrm.isEmpty()) myNbSeg->setValue( nbSeg ); else @@ -264,7 +272,7 @@ void NETGENPluginGUI_SimpleCreator::retrieveParams() const else { myNbSeg->setEnabled( false ); myLength->setEnabled( true ); - aPrm = (aParameters->length() > 0) ? QString(aParameters[0].in()) : QString(""); + aPrm = getVariableName("SetLocalLength"); if(aPrm.isEmpty()) myLength->setValue( h->GetLocalLength() ); else @@ -275,7 +283,7 @@ void NETGENPluginGUI_SimpleCreator::retrieveParams() const if ( double area = h->GetMaxElementArea() ) { myLenFromEdgesCheckBox->setChecked( false ); myArea->setEnabled( true ); - aPrm = (aParameters->length() > 1) ? QString(aParameters[1].in()) : QString(""); + aPrm = getVariableName("SetMaxElementArea"); if(aPrm.isEmpty()) myArea->setValue( area ); else @@ -285,6 +293,8 @@ void NETGENPluginGUI_SimpleCreator::retrieveParams() const myLenFromEdgesCheckBox->setChecked( true ); myArea->setEnabled( false ); } + if ( myAllowQuadCheckBox ) + myAllowQuadCheckBox->setChecked( h->GetAllowQuadrangles() ); // 3D if ( myVolume ) { @@ -292,7 +302,7 @@ void NETGENPluginGUI_SimpleCreator::retrieveParams() const if ( double volume = (double) h->GetMaxElementVolume() ) { myLenFromFacesCheckBox->setChecked( false ); myVolume->setEnabled( true ); - aPrm = (aParameters->length() > 2) ? QString(aParameters[2].in()) : QString(""); + aPrm = getVariableName("SetMaxElementVolume"); if(aPrm.isEmpty()) myVolume->setValue( volume ); else @@ -319,49 +329,43 @@ QString NETGENPluginGUI_SimpleCreator::storeParams() const // 1D - QStringList aVariablesList; if ( myNbSeg->isEnabled() ) { + h->SetVarParameter( myNbSeg->text().toLatin1().constData(), "SetNumberOfSegments"); h->SetNumberOfSegments( myNbSeg->value() ); valStr += "nbSeg=" + myNbSeg->text(); - aVariablesList.append(myNbSeg->text()); } else { + h->SetVarParameter( myLength->text().toLatin1().constData(), "SetLocalLength"); h->SetLocalLength( myLength->value() ); valStr += "len=" + myLength->text(); - aVariablesList.append(myLength->text()); } - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); - // 2D if ( myArea->isEnabled() ) { + h->SetVarParameter( myArea->text().toLatin1().constData(), "SetMaxElementArea"); h->SetMaxElementArea( myArea->value() ); valStr += "; area=" + myArea->text(); - aVariablesList.append(myArea->text()); } else { h->LengthFromEdges(); valStr += "; lenFromEdges"; - aVariablesList.append(QString()); } - - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); + if ( myAllowQuadCheckBox ) + h->SetAllowQuadrangles( myAllowQuadCheckBox->isChecked() ); // 3D if ( myVolume ) { NETGENPlugin_SimpleHypothesis_3D_var h = NETGENPlugin_SimpleHypothesis_3D::_narrow( hypothesis() ); if ( myVolume->isEnabled() ) { + h->SetVarParameter( myVolume->text().toLatin1().constData(), "SetMaxElementVolume"); h->SetMaxElementVolume( myVolume->value() ); valStr += "; vol=" + myVolume->text(); - aVariablesList.append( myVolume->text()); } else { h->LengthFromFaces(); valStr += "; lenFromFaces"; - aVariablesList.append(QString()); } - h->SetParameters(SMESHGUI::JoinObjectParameters(aVariablesList)); } } catch(const SALOME::SALOME_Exception& ex) diff --git a/src/GUI/NETGENPluginGUI_SimpleCreator.h b/src/GUI/NETGENPluginGUI_SimpleCreator.h index 4b7bb88..a275463 100644 --- a/src/GUI/NETGENPluginGUI_SimpleCreator.h +++ b/src/GUI/NETGENPluginGUI_SimpleCreator.h @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : NETGENPluginGUI_SimpleCreator.h // Author : Open CASCADE S.A.S. // @@ -69,6 +67,7 @@ private: QCheckBox* myLenFromEdgesCheckBox; SMESHGUI_SpinBox* myArea; + QCheckBox* myAllowQuadCheckBox; QCheckBox* myLenFromFacesCheckBox; SMESHGUI_SpinBox* myVolume; diff --git a/src/GUI/NETGENPlugin_images.ts b/src/GUI/NETGENPlugin_images.ts index 92ae658..121c504 100644 --- a/src/GUI/NETGENPlugin_images.ts +++ b/src/GUI/NETGENPlugin_images.ts @@ -1,28 +1,6 @@ + - - + @default @@ -45,13 +23,17 @@ ICON_SMESH_TREE_ALGO_NETGEN_2D mesh_tree_algo_netgen_2d.png + + ICON_SMESH_TREE_ALGO_NETGEN_2D_ONLY + mesh_tree_algo_netgen_2d.png + ICON_SMESH_TREE_ALGO_NETGEN_2D3D mesh_tree_algo_netgen_2d3d.png ICON_SMESH_TREE_ALGO_NETGEN_3D - mesh_tree_algo_tetra.png + mesh_tree_algo_netgen_2d3d.png ICON_SMESH_TREE_HYPO_NETGEN_Parameters diff --git a/src/GUI/NETGENPlugin_msg_en.ts b/src/GUI/NETGENPlugin_msg_en.ts index 42ef251..55e4ceb 100644 --- a/src/GUI/NETGENPlugin_msg_en.ts +++ b/src/GUI/NETGENPlugin_msg_en.ts @@ -1,137 +1,151 @@ + - - - - @default - - NETGEN_2D_HYPOTHESIS - Netgen 2D - - - NETGEN_2D_TITLE - Hypothesis Construction - - - NETGEN_3D_HYPOTHESIS - Netgen 3D - - - NETGEN_3D_TITLE - Hypothesis Construction - - - NETGEN_SimpleParameters_3D_HYPOTHESIS - Netgen 3D simple parameters - - - NETGEN_SimpleParameters_3D_TITLE - Hypothesis Construction - - - NETGEN_SimpleParameters_2D_HYPOTHESIS - Netgen 2D simple parameters - - - NETGEN_SimpleParameters_2D_TITLE - Hypothesis Construction - - - NETGEN_ALLOW_QUADRANGLES - Allow Quadrangles - - - NETGEN_COARSE - Coarse - - - NETGEN_CUSTOM - Custom - - - NETGEN_FINE - Fine - - - NETGEN_FINENESS - Fineness - - - NETGEN_GROWTH_RATE - Growth Rate - - - NETGEN_MAX_SIZE - Max. Size - - - NETGEN_MODERATE - Moderate - - - NETGEN_OPTIMIZE - Optimize - - - NETGEN_SECOND_ORDER - Second Order - - - NETGEN_SEG_PER_EDGE - Nb. Segs per Edge - - - NETGEN_SEG_PER_RADIUS - Nb. Segs per Radius - - - NETGEN_VERYCOARSE - Very Coarse - - - NETGEN_VERYFINE - Very Fine - - - NG_1D - 1D - - - NG_2D - 2D - - - NG_3D - 3D - - - NG_LENGTH_FROM_EDGES - Length from edges - - - NG_LENGTH_FROM_FACES - Length from faces - - + + + @default + + NETGEN_2D_HYPOTHESIS + Netgen 2D + + + NETGEN_2D_TITLE + Hypothesis Construction + + + NETGEN_3D_HYPOTHESIS + Netgen 3D + + + NETGEN_3D_TITLE + Hypothesis Construction + + + NETGEN_SimpleParameters_3D_HYPOTHESIS + Netgen 3D simple parameters + + + NETGEN_SimpleParameters_3D_TITLE + Hypothesis Construction + + + NETGEN_SimpleParameters_2D_HYPOTHESIS + Netgen 2D simple parameters + + + NETGEN_SimpleParameters_2D_TITLE + Hypothesis Construction + + + NETGEN_ALLOW_QUADRANGLES + Allow Quadrangles + + + NETGEN_COARSE + Coarse + + + NETGEN_CUSTOM + Custom + + + NETGEN_FINE + Fine + + + NETGEN_FINENESS + Fineness + + + NETGEN_GROWTH_RATE + Growth Rate + + + NETGEN_MAX_SIZE + Max. Size + + + NETGEN_MIN_SIZE + Min. Size + + + NETGEN_MODERATE + Moderate + + + NETGEN_OPTIMIZE + Optimize + + + NETGEN_SECOND_ORDER + Second Order + + + NETGEN_SEG_PER_EDGE + Nb. Segs per Edge + + + NETGEN_SEG_PER_RADIUS + Nb. Segs per Radius + + + NETGEN_VERYCOARSE + Very Coarse + + + NETGEN_VERYFINE + Very Fine + + + NG_1D + 1D + + + NG_2D + 2D + + + NG_3D + 3D + + + NG_LENGTH_FROM_EDGES + Length from edges + + + NG_LENGTH_FROM_FACES + Length from faces + + + NETGEN_LOCAL_SIZE + Local sizes + + + NETGEN_LSZ_VERTEX + On Vertex + + + NETGEN_LSZ_EDGE + On Edge + + + NETGEN_LSZ_FACE + On Sub-Face + + + NETGEN_LSZ_REMOVE + Remove + + + LSZ_ENTRY_COLUMN + Entry + + + LSZ_NAME_COLUMN + Name + + + LSZ_LOCALSIZE_COLUMN + Value + + diff --git a/src/GUI/NETGENPlugin_msg_fr.ts b/src/GUI/NETGENPlugin_msg_fr.ts new file mode 100755 index 0000000..01acbc0 --- /dev/null +++ b/src/GUI/NETGENPlugin_msg_fr.ts @@ -0,0 +1,151 @@ + + + + + @default + + NETGEN_2D_HYPOTHESIS + Netgen 2D + + + NETGEN_2D_TITLE + Construction d'une hypothèse + + + NETGEN_3D_HYPOTHESIS + Netgen 3D + + + NETGEN_3D_TITLE + Construction d'une hypothèse + + + NETGEN_SimpleParameters_3D_HYPOTHESIS + Netgen 3D paramètres simplifiés + + + NETGEN_SimpleParameters_3D_TITLE + Construction d'une hypothèse + + + NETGEN_SimpleParameters_2D_HYPOTHESIS + Netgen 2D paramètres simplifiés + + + NETGEN_SimpleParameters_2D_TITLE + Construction d'une hypothèse + + + NETGEN_ALLOW_QUADRANGLES + Autoriser les quadrangles + + + NETGEN_COARSE + Grossier + + + NETGEN_CUSTOM + Personnalisé + + + NETGEN_FINE + Fin + + + NETGEN_FINENESS + Finesse + + + NETGEN_GROWTH_RATE + Taux d'accroissement + + + NETGEN_MAX_SIZE + Taille maximale + + + NETGEN_MIN_SIZE + Taille minimale + + + NETGEN_MODERATE + Moyen + + + NETGEN_OPTIMIZE + Optimiser + + + NETGEN_SECOND_ORDER + Second ordre + + + NETGEN_SEG_PER_EDGE + Nb. segments par arête + + + NETGEN_SEG_PER_RADIUS + Nb. segments par rayon + + + NETGEN_VERYCOARSE + Très grossier + + + NETGEN_VERYFINE + Très fin + + + NG_1D + 1D + + + NG_2D + 2D + + + NG_3D + 3D + + + NG_LENGTH_FROM_EDGES + Longueur à partir des arêtes + + + NG_LENGTH_FROM_FACES + Longueur à partir des faces + + + NETGEN_LOCAL_SIZE + Tailles locales + + + NETGEN_LSZ_VERTEX + Sur un point + + + NETGEN_LSZ_EDGE + Sur une arête + + + NETGEN_LSZ_FACE + Sur une sous-face + + + NETGEN_LSZ_REMOVE + Supprimer + + + LSZ_ENTRY_COLUMN + Entrée + + + LSZ_NAME_COLUMN + Nom + + + LSZ_LOCALSIZE_COLUMN + Valeur + + + diff --git a/src/Makefile.am b/src/Makefile.am index 7251f43..0b988a7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # File : Makefile.in # Author : Patrick GOLDBRONN (CEA) # Modified by : Alexander BORODIN (OCN) - autotools usage @@ -27,7 +25,15 @@ # include $(top_srcdir)/adm_local/unix/make_common_starter.am -SUBDIRS = NETGEN NETGENPlugin +SUBDIRS = +if CMAKE_BUILD +else +if NETGEN_NEW +else + SUBDIRS += NETGEN +endif +endif +SUBDIRS += NETGENPlugin if NETGENPLUGIN_ENABLE_GUI SUBDIRS += GUI diff --git a/src/NETGEN/Makefile.am b/src/NETGEN/Makefile.am index 0ac0539..c494321 100644 --- a/src/NETGEN/Makefile.am +++ b/src/NETGEN/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # -* Makefile *- # Author : Edward AGAPOV (OCC) # Modified by : Alexander BORODIN (OCN) - autotools usage diff --git a/src/NETGEN/ReadMeForNgUsers b/src/NETGEN/ReadMeForNgUsers index 0b7cb28..7d982a8 100644 --- a/src/NETGEN/ReadMeForNgUsers +++ b/src/NETGEN/ReadMeForNgUsers @@ -1,3 +1,41 @@ +# ------------------------------------------------------------------ +# ------------------------------------------------------------------ +# Notes for Netgen >= 4.9 +# ------------------------------------------------------------------ +# ------------------------------------------------------------------ + +Netgen can be find at http://www.hpfem.jku.at/netgen/ + +1. How to build Netgen for Netgen Plugin +------------------------------ + +1.1. Download Netgen archive (here netgen-4.9.12.tar.gz) and unpack it + +1.2. Configure the netgen compilation. The "good" options are + ../netgen-4.9.12/configure \ + --prefix=THE_INSTALLATION_PATH \ + --with-occ=${CASROOT} \ + CXXFLAGS="-I${TOGL_HOME}/include" \ + LDFLAGS="-L${TOGL_HOME}/lib/Togl1.7" + +1.3. Compile the netgen product + make then make install + +1.4. Patch the installation directory to copy include files + needed by NETGEN Plugin. Use the script + NETGENPLUGIN_SRC/src/NETGEN/netgen_copy_include_for_salome + to achieve that. The first argument is the directory containing + the Netgen sources. The second argument is THE_INSTALLATION_PATH + +Erwan ADAM +erwan.adam@cea.fr + +# ------------------------------------------------------------------ +# ------------------------------------------------------------------ +# Notes for Netgen 4.5 +# ------------------------------------------------------------------ +# ------------------------------------------------------------------ + The Netgen 4.5 from the web location : http://www.hpfem.jku.at/netgen/ (CVS access) is used in the SMESH Module of Salome3 distribution. @@ -92,3 +130,8 @@ The suggested patch alters some Netgen sources to compile them. Michael SAZONOV m-sazonov@opencascade.com + +# ------------------------------------------------------------------ +# ------------------------------------------------------------------ +# ------------------------------------------------------------------ +# ------------------------------------------------------------------ diff --git a/src/NETGEN/netgen45ForSalome.patch b/src/NETGEN/netgen45ForSalome.patch index fac1fc0..b77fc51 100644 --- a/src/NETGEN/netgen45ForSalome.patch +++ b/src/NETGEN/netgen45ForSalome.patch @@ -1,6 +1,66 @@ -diff -Naur netgen-4.5.old/libsrc/csg/meshsurf.cpp netgen-4.5.new/libsrc/csg/meshsurf.cpp ---- netgen-4.5.old/libsrc/csg/meshsurf.cpp 2006-02-14 11:54:35.000000000 +0300 -+++ netgen-4.5.new/libsrc/csg/meshsurf.cpp 2008-02-12 14:57:01.000000000 +0300 +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/csg/algprim.cpp netgen-4.5_new/libsrc/csg/algprim.cpp +--- netgen-4.5_orig/libsrc/csg/algprim.cpp 2006-01-25 16:30:28.000000000 +0300 ++++ netgen-4.5_new/libsrc/csg/algprim.cpp 2010-11-25 10:11:30.000000000 +0300 +@@ -108,7 +108,7 @@ + void Plane :: GetPrimitiveData (char *& classname, + ARRAY & coeffs) const + { +- classname = "plane"; ++ classname = (char*)"plane"; + coeffs.SetSize (6); + coeffs.Elem(1) = p(0); + coeffs.Elem(2) = p(1); +@@ -355,7 +355,7 @@ + + void Sphere :: GetPrimitiveData (char *& classname, ARRAY & coeffs) const + { +- classname = "sphere"; ++ classname = (char*)"sphere"; + coeffs.SetSize (4); + coeffs.Elem(1) = c(0); + coeffs.Elem(2) = c(1); +@@ -760,7 +760,7 @@ + + void Cylinder :: GetPrimitiveData (char *& classname, ARRAY & coeffs) const + { +- classname = "cylinder"; ++ classname = (char*)"cylinder"; + coeffs.SetSize (7); + coeffs.Elem(1) = a(0); + coeffs.Elem(2) = a(1); +@@ -1243,7 +1243,7 @@ + + void Cone :: GetPrimitiveData (char *& classname, ARRAY & coeffs) const + { +- classname = "cone"; ++ classname = (char*)"cone"; + coeffs.SetSize (8); + coeffs.Elem(1) = a(0); + coeffs.Elem(2) = a(1); +@@ -1446,7 +1446,7 @@ + + void Torus :: GetPrimitiveData (char *& classname, ARRAY & coeffs) const + { +- classname = "torus"; ++ classname = (char*)"torus"; + coeffs.SetSize (8); + coeffs.Elem(1) = c(0); + coeffs.Elem(2) = c(1); +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/csg/brick.cpp netgen-4.5_new/libsrc/csg/brick.cpp +--- netgen-4.5_orig/libsrc/csg/brick.cpp 2006-02-08 15:23:15.000000000 +0300 ++++ netgen-4.5_new/libsrc/csg/brick.cpp 2010-11-25 10:11:30.000000000 +0300 +@@ -345,7 +345,7 @@ + void Brick :: + GetPrimitiveData (char *& classname, ARRAY & coeffs) const + { +- classname = "brick"; ++ classname = (char*)"brick"; + coeffs.SetSize(12); + coeffs.Elem(1) = p1(0); + coeffs.Elem(2) = p1(1); +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/csg/meshsurf.cpp netgen-4.5_new/libsrc/csg/meshsurf.cpp +--- netgen-4.5_orig/libsrc/csg/meshsurf.cpp 2006-02-14 11:54:35.000000000 +0300 ++++ netgen-4.5_new/libsrc/csg/meshsurf.cpp 2010-11-25 10:11:30.000000000 +0300 @@ -77,11 +77,12 @@ } @@ -15,9 +75,9 @@ diff -Naur netgen-4.5.old/libsrc/csg/meshsurf.cpp netgen-4.5.new/libsrc/csg/mesh } void MeshOptimize2dSurfaces :: ProjectPoint2 (INDEX surfind, INDEX surfind2, -diff -Naur netgen-4.5.old/libsrc/csg/meshsurf.hpp netgen-4.5.new/libsrc/csg/meshsurf.hpp ---- netgen-4.5.old/libsrc/csg/meshsurf.hpp 2004-01-20 14:49:44.000000000 +0300 -+++ netgen-4.5.new/libsrc/csg/meshsurf.hpp 2008-02-12 14:57:01.000000000 +0300 +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/csg/meshsurf.hpp netgen-4.5_new/libsrc/csg/meshsurf.hpp +--- netgen-4.5_orig/libsrc/csg/meshsurf.hpp 2004-01-20 14:49:44.000000000 +0300 ++++ netgen-4.5_new/libsrc/csg/meshsurf.hpp 2010-11-25 10:11:30.000000000 +0300 @@ -45,7 +45,7 @@ MeshOptimize2dSurfaces (const CSGeometry & ageometry); @@ -27,9 +87,104 @@ diff -Naur netgen-4.5.old/libsrc/csg/meshsurf.hpp netgen-4.5.new/libsrc/csg/mesh /// virtual void ProjectPoint2 (INDEX surfind, INDEX surfind2, Point3d & p) const; /// -diff -Naur netgen-4.5.old/libsrc/interface/Makefile netgen-4.5.new/libsrc/interface/Makefile ---- netgen-4.5.old/libsrc/interface/Makefile 2005-08-09 18:14:59.000000000 +0400 -+++ netgen-4.5.new/libsrc/interface/Makefile 2008-02-12 14:57:01.000000000 +0300 +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/csg/polyhedra.cpp netgen-4.5_new/libsrc/csg/polyhedra.cpp +--- netgen-4.5_orig/libsrc/csg/polyhedra.cpp 2006-02-09 13:33:11.000000000 +0300 ++++ netgen-4.5_new/libsrc/csg/polyhedra.cpp 2010-11-25 10:11:30.000000000 +0300 +@@ -287,7 +287,7 @@ + void Polyhedra :: GetPrimitiveData (char *& classname, + ARRAY & coeffs) const + { +- classname = "Polyhedra"; ++ classname = (char*)"Polyhedra"; + coeffs.SetSize(0); + coeffs.Append (points.Size()); + coeffs.Append (faces.Size()); +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/csg/surface.cpp netgen-4.5_new/libsrc/csg/surface.cpp +--- netgen-4.5_orig/libsrc/csg/surface.cpp 2006-02-08 15:23:16.000000000 +0300 ++++ netgen-4.5_new/libsrc/csg/surface.cpp 2010-11-25 10:11:30.000000000 +0300 +@@ -215,7 +215,7 @@ + void Primitive :: GetPrimitiveData (char *& classname, + ARRAY & coeffs) const + { +- classname = "undef"; ++ classname = (char*)"undef"; + coeffs.SetSize (0); + } + +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/general/profiler.cpp netgen-4.5_new/libsrc/general/profiler.cpp +--- netgen-4.5_orig/libsrc/general/profiler.cpp 2006-01-11 13:05:59.000000000 +0300 ++++ netgen-4.5_new/libsrc/general/profiler.cpp 2010-11-25 10:11:30.000000000 +0300 +@@ -34,8 +34,14 @@ + { + StopTimer (total_timer); + +- ofstream prof ("netgen.prof"); +- Print (prof); ++ char* env; ++ if ((env = getenv("NETGEN_PROF")) && !strcmp(env, "1")) { ++ ofstream prof ("netgen.prof"); ++ Print (prof); ++ } ++ else if ((env = getenv("NETGEN_PROF")) && !strcmp(env, "0")) { ++ Print (std::cout); ++ } + } + + +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/geom2d/genmesh2d.cpp netgen-4.5_new/libsrc/geom2d/genmesh2d.cpp +--- netgen-4.5_orig/libsrc/geom2d/genmesh2d.cpp 2006-02-16 19:17:47.000000000 +0300 ++++ netgen-4.5_new/libsrc/geom2d/genmesh2d.cpp 2010-11-25 10:11:30.000000000 +0300 +@@ -121,11 +121,11 @@ + + int hsteps = mp.optsteps2d; + +- mp.optimize2d = "smcm"; ++ mp.optimize2d = (char*)"smcm"; + mp.optsteps2d = hsteps/2; + Optimize2d (*mesh, mp); + +- mp.optimize2d = "Smcm"; ++ mp.optimize2d = (char*)"Smcm"; + mp.optsteps2d = (hsteps+1)/2; + Optimize2d (*mesh, mp); + +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/gprim/geom2d.hpp netgen-4.5_new/libsrc/gprim/geom2d.hpp +--- netgen-4.5_orig/libsrc/gprim/geom2d.hpp 2004-01-20 14:49:44.000000000 +0300 ++++ netgen-4.5_new/libsrc/gprim/geom2d.hpp 2010-11-25 10:11:30.000000000 +0300 +@@ -53,7 +53,7 @@ + int IsOnLongLine (const Line2d & l, const Point2d & p); + int Hit (const Line2d & l1, const Line2d & l2, double heps = EPSGEOM); + ostream & operator<<(ostream & s, const Line2d & l); +-Point2d CrossPoint (const PLine2d & l1, const PLine2d & l2); ++Point2d CrossPoint (const Line2d & l1, const Line2d & l2); + int Parallel (const PLine2d & l1, const PLine2d & l2, double peps = EPSGEOM); + int IsOnLine (const PLine2d & l, const Point2d & p, double heps = EPSGEOM); + int IsOnLongLine (const PLine2d & l, const Point2d & p); +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/gprim/geom3d.hpp netgen-4.5_new/libsrc/gprim/geom3d.hpp +--- netgen-4.5_orig/libsrc/gprim/geom3d.hpp 2004-08-30 16:04:04.000000000 +0400 ++++ netgen-4.5_new/libsrc/gprim/geom3d.hpp 2010-11-25 10:11:30.000000000 +0300 +@@ -25,6 +25,7 @@ + inline Point3d Center (const Point3d & p1, const Point3d & p2, const Point3d & p3); + inline Point3d Center (const Point3d & p1, const Point3d & p2, + const Point3d & p3, const Point3d & p4); ++inline double Dist2 (const Point3d & p1, const Point3d & p2); + ostream & operator<<(ostream & s, const Point3d & p); + inline Vec3d operator- (const Vec3d & p1, const Vec3d & v); + inline Vec3d operator+ (const Vec3d & p1, const Vec3d & v); +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/include/mystdlib.h netgen-4.5_new/libsrc/include/mystdlib.h +--- netgen-4.5_orig/libsrc/include/mystdlib.h 2006-01-16 17:16:56.000000000 +0300 ++++ netgen-4.5_new/libsrc/include/mystdlib.h 2010-11-25 10:11:30.000000000 +0300 +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #endif + + +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/interface/Makefile netgen-4.5_new/libsrc/interface/Makefile +--- netgen-4.5_orig/libsrc/interface/Makefile 2005-08-09 18:14:59.000000000 +0400 ++++ netgen-4.5_new/libsrc/interface/Makefile 2010-11-25 10:11:30.000000000 +0300 @@ -1,4 +1,5 @@ -src = nginterface.cpp writeuser.cpp writediffpack.cpp writeabaqus.cpp writefluent.cpp writepermas.cpp writetochnog.cpp writetecplot.cpp wuchemnitz.cpp writetochnog.cpp writefeap.cpp writeelmer.cpp writegmsh.cpp writejcm.cpp readuser.cpp importsolution.cpp +#src = nginterface.cpp writeuser.cpp writediffpack.cpp writeabaqus.cpp writefluent.cpp writepermas.cpp writetochnog.cpp writetecplot.cpp wuchemnitz.cpp writetochnog.cpp writefeap.cpp writeelmer.cpp writegmsh.cpp writejcm.cpp readuser.cpp importsolution.cpp @@ -37,9 +192,9 @@ diff -Naur netgen-4.5.old/libsrc/interface/Makefile netgen-4.5.new/libsrc/interf # lib = nginterface libpath = libsrc/interface -diff -Naur netgen-4.5.old/libsrc/interface/nglib.cpp netgen-4.5.new/libsrc/interface/nglib.cpp ---- netgen-4.5.old/libsrc/interface/nglib.cpp 2005-10-18 17:53:18.000000000 +0400 -+++ netgen-4.5.new/libsrc/interface/nglib.cpp 2008-02-12 14:57:01.000000000 +0300 +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/interface/nglib.cpp netgen-4.5_new/libsrc/interface/nglib.cpp +--- netgen-4.5_orig/libsrc/interface/nglib.cpp 2005-10-18 17:53:18.000000000 +0400 ++++ netgen-4.5_new/libsrc/interface/nglib.cpp 2010-11-25 10:11:30.000000000 +0300 @@ -56,7 +56,8 @@ void Ng_Exit () @@ -50,9 +205,33 @@ diff -Naur netgen-4.5.old/libsrc/interface/nglib.cpp netgen-4.5.new/libsrc/inter } -diff -Naur netgen-4.5.old/libsrc/makefile.inc netgen-4.5.new/libsrc/makefile.inc ---- netgen-4.5.old/libsrc/makefile.inc 2005-09-02 17:17:51.000000000 +0400 -+++ netgen-4.5.new/libsrc/makefile.inc 2008-02-12 14:59:55.000000000 +0300 +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/interface/writeuser.cpp netgen-4.5_new/libsrc/interface/writeuser.cpp +--- netgen-4.5_orig/libsrc/interface/writeuser.cpp 2005-08-09 18:14:59.000000000 +0400 ++++ netgen-4.5_new/libsrc/interface/writeuser.cpp 2010-11-25 10:11:30.000000000 +0300 +@@ -17,7 +17,7 @@ + + void RegisterUserFormats (ARRAY & names) + { +- char *types[] = ++ const char *types[] = + { + "Neutral Format", + "Surface Mesh Format" , +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/linalg/densemat.hpp netgen-4.5_new/libsrc/linalg/densemat.hpp +--- netgen-4.5_orig/libsrc/linalg/densemat.hpp 2005-12-09 15:26:19.000000000 +0300 ++++ netgen-4.5_new/libsrc/linalg/densemat.hpp 2010-11-25 10:11:30.000000000 +0300 +@@ -14,6 +14,8 @@ + + #include + ++class DenseMatrix; ++void CalcAtA (const DenseMatrix & a, DenseMatrix & m2); + + class DenseMatrix + { +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/makefile.inc netgen-4.5_new/libsrc/makefile.inc +--- netgen-4.5_orig/libsrc/makefile.inc 2005-09-02 17:17:51.000000000 +0400 ++++ netgen-4.5_new/libsrc/makefile.inc 2010-11-25 10:11:30.000000000 +0300 @@ -8,17 +8,14 @@ LIBSRC_DIR=$(CPP_DIR)/libsrc LIB_DIR=$(CPP_DIR)/lib/$(MACHINE) @@ -76,9 +255,9 @@ diff -Naur netgen-4.5.old/libsrc/makefile.inc netgen-4.5.new/libsrc/makefile.inc # ARFLAGS = r # -diff -Naur netgen-4.5.old/libsrc/makefile.mach.LINUX netgen-4.5.new/libsrc/makefile.mach.LINUX ---- netgen-4.5.old/libsrc/makefile.mach.LINUX 2004-10-11 23:49:26.000000000 +0400 -+++ netgen-4.5.new/libsrc/makefile.mach.LINUX 2008-02-12 14:57:01.000000000 +0300 +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/makefile.mach.LINUX netgen-4.5_new/libsrc/makefile.mach.LINUX +--- netgen-4.5_orig/libsrc/makefile.mach.LINUX 2004-10-11 23:49:26.000000000 +0400 ++++ netgen-4.5_new/libsrc/makefile.mach.LINUX 2010-11-25 10:11:30.000000000 +0300 @@ -16,7 +16,7 @@ # CFLAGS2 = @@ -88,29 +267,9 @@ diff -Naur netgen-4.5.old/libsrc/makefile.mach.LINUX netgen-4.5.new/libsrc/makef -ftemplate-depth-99 -finline-limit=10000 \ -Wdisabled-optimization -funroll-loops -DnoNGSOLVE -diff -Naur netgen-4.5.old/libsrc/meshing/meshtype.cpp netgen-4.5.new/libsrc/meshing/meshtype.cpp ---- netgen-4.5.old/libsrc/meshing/meshtype.cpp 2006-02-10 13:11:08.000000000 +0300 -+++ netgen-4.5.new/libsrc/meshing/meshtype.cpp 2008-03-14 13:19:53.000000000 +0300 -@@ -1,4 +1,5 @@ - #include -+#include - - #include "meshing.hpp" - -@@ -774,7 +775,7 @@ - frob /= 2; - - double det = trans.Det(); -- if (det <= 0) -+ if (det <= DBL_MIN) - err += 1e12; - else - err += frob * frob / det; - - -diff -Naur netgen-4.5.old/libsrc/meshing/improve2.cpp netgen-4.5.new/libsrc/meshing/improve2.cpp ---- netgen-4.5.old/libsrc/meshing/improve2.cpp 2006-01-11 19:08:19.000000000 +0300 -+++ netgen-4.5.new/libsrc/meshing/improve2.cpp 2008-02-12 14:57:01.000000000 +0300 +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/meshing/improve2.cpp netgen-4.5_new/libsrc/meshing/improve2.cpp +--- netgen-4.5_orig/libsrc/meshing/improve2.cpp 2006-01-11 19:08:19.000000000 +0300 ++++ netgen-4.5_new/libsrc/meshing/improve2.cpp 2010-11-25 10:11:30.000000000 +0300 @@ -4,7 +4,7 @@ #include @@ -120,9 +279,9 @@ diff -Naur netgen-4.5.old/libsrc/meshing/improve2.cpp netgen-4.5.new/libsrc/mesh #endif namespace netgen -diff -Naur netgen-4.5.old/libsrc/meshing/improve2.hpp netgen-4.5.new/libsrc/meshing/improve2.hpp ---- netgen-4.5.old/libsrc/meshing/improve2.hpp 2004-10-12 23:22:55.000000000 +0400 -+++ netgen-4.5.new/libsrc/meshing/improve2.hpp 2008-02-12 14:57:01.000000000 +0300 +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/meshing/improve2.hpp netgen-4.5_new/libsrc/meshing/improve2.hpp +--- netgen-4.5_orig/libsrc/meshing/improve2.hpp 2004-10-12 23:22:55.000000000 +0400 ++++ netgen-4.5_new/libsrc/meshing/improve2.hpp 2010-11-25 10:11:30.000000000 +0300 @@ -32,17 +32,16 @@ /// virtual void SelectSurfaceOfPoint (const Point3d & p, @@ -149,9 +308,51 @@ diff -Naur netgen-4.5.old/libsrc/meshing/improve2.hpp netgen-4.5.new/libsrc/mesh /// virtual void GetNormalVector(INDEX surfind, const Point3d & p, PointGeomInfo & gi, Vec3d & n) const; -diff -Naur netgen-4.5.old/libsrc/meshing/smoothing2.cpp netgen-4.5.new/libsrc/meshing/smoothing2.cpp ---- netgen-4.5.old/libsrc/meshing/smoothing2.cpp 2006-01-11 19:08:20.000000000 +0300 -+++ netgen-4.5.new/libsrc/meshing/smoothing2.cpp 2008-02-12 14:57:01.000000000 +0300 +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/meshing/meshtype.cpp netgen-4.5_new/libsrc/meshing/meshtype.cpp +--- netgen-4.5_orig/libsrc/meshing/meshtype.cpp 2006-02-10 13:11:08.000000000 +0300 ++++ netgen-4.5_new/libsrc/meshing/meshtype.cpp 2010-11-25 10:11:30.000000000 +0300 +@@ -1,4 +1,5 @@ + #include ++#include + + #include "meshing.hpp" + +@@ -774,7 +775,7 @@ + frob /= 2; + + double det = trans.Det(); +- if (det <= 0) ++ if (det <= DBL_MIN) + err += 1e12; + else + err += frob * frob / det; +@@ -2222,9 +2223,9 @@ + + MeshingParameters :: MeshingParameters () + { +- optimize3d = "cmdmstm"; ++ optimize3d = (char*)"cmdmstm"; + optsteps3d = 3; +- optimize2d = "smsmsmSmSmSm"; ++ optimize2d = (char*)"smsmsmSmSmSm"; + optsteps2d = 3; + opterrpow = 2; + blockfill = 1; +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/meshing/meshtype.hpp netgen-4.5_new/libsrc/meshing/meshtype.hpp +--- netgen-4.5_orig/libsrc/meshing/meshtype.hpp 2006-02-10 13:11:08.000000000 +0300 ++++ netgen-4.5_new/libsrc/meshing/meshtype.hpp 2010-11-25 10:11:30.000000000 +0300 +@@ -13,7 +13,7 @@ + Classes for NETGEN + */ + +- ++class Mesh; + enum ELEMENT_TYPE { + SEGMENT = 1, SEGMENT3 = 2, + TRIG = 10, QUAD=11, TRIG6 = 12, QUAD6 = 13, QUAD8 = 14, +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/meshing/smoothing2.cpp netgen-4.5_new/libsrc/meshing/smoothing2.cpp +--- netgen-4.5_orig/libsrc/meshing/smoothing2.cpp 2006-01-11 19:08:20.000000000 +0300 ++++ netgen-4.5_new/libsrc/meshing/smoothing2.cpp 2010-11-25 10:11:30.000000000 +0300 @@ -300,7 +300,7 @@ double Opti2SurfaceMinFunction :: FuncGrad (const Vector & x, Vector & grad) const @@ -270,9 +471,119 @@ diff -Naur netgen-4.5.old/libsrc/meshing/smoothing2.cpp netgen-4.5.new/libsrc/me if (moveisok) { for (j = 0; j < locelements.Size(); j++) -diff -Naur netgen-4.5.old/libsrc/occ/occconstruction.cpp netgen-4.5.new/libsrc/occ/occconstruction.cpp ---- netgen-4.5.old/libsrc/occ/occconstruction.cpp 2005-12-06 18:15:53.000000000 +0300 -+++ netgen-4.5.new/libsrc/occ/occconstruction.cpp 2008-02-12 14:57:01.000000000 +0300 +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/occ/Partition_Inter2d.cxx netgen-4.5_new/libsrc/occ/Partition_Inter2d.cxx +--- netgen-4.5_orig/libsrc/occ/Partition_Inter2d.cxx 2005-06-09 18:51:10.000000000 +0400 ++++ netgen-4.5_new/libsrc/occ/Partition_Inter2d.cxx 2010-11-25 10:11:31.000000000 +0300 +@@ -29,10 +29,10 @@ + // $Header$ + + //using namespace std; +-#include "Partition_Inter2d.ixx" +- + #include "utilities.h" + ++#include "Partition_Inter2d.ixx" ++ + #include + #include + #include +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/occ/Partition_Inter3d.cxx netgen-4.5_new/libsrc/occ/Partition_Inter3d.cxx +--- netgen-4.5_orig/libsrc/occ/Partition_Inter3d.cxx 2005-06-09 18:51:10.000000000 +0400 ++++ netgen-4.5_new/libsrc/occ/Partition_Inter3d.cxx 2010-11-25 10:11:31.000000000 +0300 +@@ -29,13 +29,17 @@ + // $Header$ + + //using namespace std; ++ ++#include "utilities.h" ++ + #include "Partition_Inter2d.hxx" + #include "Partition_Inter3d.ixx" +-#include "utilities.h" + + #include + #include + #include ++//using namespace std; ++ + #include + #include + #include +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/occ/Partition_Loop.cxx netgen-4.5_new/libsrc/occ/Partition_Loop.cxx +--- netgen-4.5_orig/libsrc/occ/Partition_Loop.cxx 2005-06-09 18:51:10.000000000 +0400 ++++ netgen-4.5_new/libsrc/occ/Partition_Loop.cxx 2010-11-25 10:11:31.000000000 +0300 +@@ -29,12 +29,14 @@ + // $Header$ + + //using namespace std; +-#include + +-#include "Partition_Loop.ixx" + + #include "utilities.h" + ++#include ++ ++#include "Partition_Loop.ixx" ++ + #include + #include + #include +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/occ/Partition_Loop2d.cxx netgen-4.5_new/libsrc/occ/Partition_Loop2d.cxx +--- netgen-4.5_orig/libsrc/occ/Partition_Loop2d.cxx 2005-06-09 18:51:10.000000000 +0400 ++++ netgen-4.5_new/libsrc/occ/Partition_Loop2d.cxx 2010-11-25 10:11:31.000000000 +0300 +@@ -12,9 +12,11 @@ + // $Header$ + + //using namespace std; +-#include "Partition_Loop2d.ixx" ++ + + #include "utilities.h" ++ ++#include "Partition_Loop2d.ixx" + #include + + #include +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/occ/Partition_Loop3d.cxx netgen-4.5_new/libsrc/occ/Partition_Loop3d.cxx +--- netgen-4.5_orig/libsrc/occ/Partition_Loop3d.cxx 2005-06-09 18:51:10.000000000 +0400 ++++ netgen-4.5_new/libsrc/occ/Partition_Loop3d.cxx 2010-11-25 10:11:31.000000000 +0300 +@@ -10,6 +10,11 @@ + // Module : GEOM + + //using namespace std; ++ ++ ++ ++#include "utilities.h" ++ + #include "Partition_Loop3d.ixx" + + #include +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/occ/Partition_Spliter.cxx netgen-4.5_new/libsrc/occ/Partition_Spliter.cxx +--- netgen-4.5_orig/libsrc/occ/Partition_Spliter.cxx 2005-07-11 10:33:27.000000000 +0400 ++++ netgen-4.5_new/libsrc/occ/Partition_Spliter.cxx 2010-11-25 10:11:31.000000000 +0300 +@@ -29,14 +29,15 @@ + // $Header$ + + //using namespace std; ++ ++#include "utilities.h" ++ + #include "Partition_Inter2d.hxx" + #include "Partition_Inter3d.hxx" + #include "Partition_Loop2d.hxx" + #include "Partition_Loop3d.hxx" + #include "Partition_Spliter.ixx" + +-#include "utilities.h" +- + #include + #include + #include +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/occ/occconstruction.cpp netgen-4.5_new/libsrc/occ/occconstruction.cpp +--- netgen-4.5_orig/libsrc/occ/occconstruction.cpp 2005-12-06 18:15:53.000000000 +0300 ++++ netgen-4.5_new/libsrc/occ/occconstruction.cpp 2010-11-25 10:11:30.000000000 +0300 @@ -28,8 +28,8 @@ #include #include @@ -284,9 +595,9 @@ diff -Naur netgen-4.5.old/libsrc/occ/occconstruction.cpp netgen-4.5.new/libsrc/o #include #include namespace netgen -diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/occgenmesh.cpp ---- netgen-4.5.old/libsrc/occ/occgenmesh.cpp 2006-02-07 13:12:48.000000000 +0300 -+++ netgen-4.5.new/libsrc/occ/occgenmesh.cpp 2008-02-12 14:57:01.000000000 +0300 +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/occ/occgenmesh.cpp netgen-4.5_new/libsrc/occ/occgenmesh.cpp +--- netgen-4.5_orig/libsrc/occ/occgenmesh.cpp 2006-02-07 13:12:48.000000000 +0300 ++++ netgen-4.5_new/libsrc/occ/occgenmesh.cpp 2010-11-25 10:11:30.000000000 +0300 @@ -28,7 +28,7 @@ return Point<3> (p.X(), p.Y(), p.Z()); } @@ -296,7 +607,7 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc ARRAY & ps, ARRAY & params, Mesh & mesh) -@@ -49,23 +49,19 @@ +@@ -49,23 +49,18 @@ hvalue[0] = 0; pnt = c->Value(s0); @@ -309,11 +620,12 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc { oldpnt = pnt; pnt = c->Value(s0+(i/double(DIVIDEEDGESECTIONS))*(s1-s0)); -+ double dist = pnt.Distance(oldpnt); - hvalue[i] = hvalue[i-1] + - 1.0/mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z()))* +- hvalue[i] = hvalue[i-1] + +- 1.0/mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z()))* - pnt.Distance(oldpnt); -+ dist; ++ double dist = pnt.Distance(oldpnt); ++ hvalue[i] = hvalue[i-1] + min( 1.0, ++ 1.0/mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z()))*dist); //(*testout) << "mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z())) " << mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z())) // << " pnt.Distance(oldpnt) " << pnt.Distance(oldpnt) << endl; @@ -324,7 +636,7 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc } // nsubedges = int(ceil(hvalue[DIVIDEEDGESECTIONS])); -@@ -74,7 +70,7 @@ +@@ -74,13 +69,16 @@ ps.SetSize(nsubedges-1); params.SetSize(nsubedges+1); @@ -333,7 +645,17 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc int i1 = 0; do { -@@ -112,7 +108,7 @@ + if (hvalue[i1]/hvalue[DIVIDEEDGESECTIONS]*nsubedges >= i) + { +- params[i] = s0+(i1/double(DIVIDEEDGESECTIONS))*(s1-s0); ++ // EAP. For nsubedges comparable to DIVIDEEDGESECTIONS (issue 0021073) ++ double d1 = i1 - (hvalue[i1] - i*hvalue[DIVIDEEDGESECTIONS]/nsubedges)/(hvalue[i1]-hvalue[i1-1]); ++ params[i] = s0+(d1/double(DIVIDEEDGESECTIONS))*(s1-s0); ++ //params[i] = s0+(i1/double(DIVIDEEDGESECTIONS))*(s1-s0); + pnt = c->Value(params[i]); + ps[i-1] = MeshPoint (Point3d(pnt.X(), pnt.Y(), pnt.Z())); + i++; +@@ -112,7 +110,7 @@ static void FindEdges (OCCGeometry & geom, Mesh & mesh) { @@ -342,7 +664,7 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc multithread.task = "Edge meshing"; (*testout) << "edge meshing" << endl; -@@ -124,6 +120,7 @@ +@@ -124,6 +122,7 @@ (*testout) << "nedges = " << nedges << endl; double eps = 1e-6 * geom.GetBoundingBox().Diam(); @@ -350,7 +672,7 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc for (int i = 1; i <= nvertices; i++) { -@@ -133,7 +130,7 @@ +@@ -133,7 +132,7 @@ bool exists = 0; if (merge_solids) for (PointIndex pi = 1; pi <= mesh.GetNP(); pi++) @@ -359,7 +681,7 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc { exists = 1; break; -@@ -163,6 +160,7 @@ +@@ -163,6 +162,7 @@ { TopoDS_Face face = TopoDS::Face(exp1.Current()); int facenr = geom.fmap.FindIndex(face); @@ -367,7 +689,7 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc if (face2solid[0][facenr-1] == 0) face2solid[0][facenr-1] = solidnr; -@@ -184,6 +182,9 @@ +@@ -184,6 +184,9 @@ int facenr = 0; int edgenr = 0; @@ -377,7 +699,7 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc (*testout) << "faces = " << geom.fmap.Extent() << endl; int curr = 0; -@@ -232,6 +233,11 @@ +@@ -232,6 +235,11 @@ continue; } @@ -389,7 +711,7 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc if (geom.vmap.FindIndex(TopExp::FirstVertex (edge)) == geom.vmap.FindIndex(TopExp::LastVertex (edge))) { -@@ -276,8 +282,8 @@ +@@ -276,8 +284,8 @@ pnums.Last() = -1; for (PointIndex pi = 1; pi < first_ep; pi++) { @@ -400,7 +722,7 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc } } -@@ -287,7 +293,7 @@ +@@ -287,7 +295,7 @@ bool exists = 0; int j; for (j = first_ep; j <= mesh.GetNP(); j++) @@ -409,7 +731,7 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc { exists = 1; break; -@@ -394,7 +400,7 @@ +@@ -394,7 +402,7 @@ int i, j, k; int changed; @@ -418,7 +740,7 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc multithread.task = "Surface meshing"; geom.facemeshstatus = 0; -@@ -751,7 +760,7 @@ +@@ -751,7 +759,7 @@ multithread.task = savetask; } @@ -427,7 +749,7 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc { double hret; kappa *= mparam.curvaturesafety; -@@ -779,7 +788,7 @@ +@@ -779,7 +787,7 @@ double nq = n*q; Point<3> p = p0 + 0.5*n; @@ -436,7 +758,7 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc if (lambda >= 0 && lambda <= 1) { -@@ -799,55 +808,55 @@ +@@ -799,55 +807,55 @@ @@ -512,7 +834,7 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc //(*testout) << "curvature " << curvature << endl; -@@ -886,51 +895,47 @@ +@@ -886,51 +894,47 @@ pm1.SetX(0.5*(par0.X()+par2.X())); pm1.SetY(0.5*(par0.Y()+par2.Y())); pm2.SetX(0.5*(par1.X()+par0.X())); pm2.SetY(0.5*(par1.Y()+par0.Y())); @@ -579,7 +901,7 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc (*testout) << pnt.X() << " " << pnt.Y() << " " << pnt.Z() << endl; */ } -@@ -970,7 +975,7 @@ +@@ -970,7 +974,7 @@ if (mparam.uselocalh) { @@ -588,7 +910,7 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc multithread.percent = 0; mesh->SetLocalH (bb.PMin(), bb.PMax(), mparam.grading); -@@ -1075,7 +1080,6 @@ +@@ -1075,7 +1079,6 @@ if (triangulation.IsNull()) continue; BRepAdaptor_Surface sf(face, Standard_True); @@ -596,7 +918,7 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc int ntriangles = triangulation -> NbTriangles(); for (int j = 1; j <= ntriangles; j++) -@@ -1096,7 +1100,7 @@ +@@ -1096,7 +1099,7 @@ maxside = max (maxside, p[1].Distance(p[2])); //cout << "\rFace " << i << " pos11 ntriangles " << ntriangles << " maxside " << maxside << flush; @@ -605,9 +927,9 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgenmesh.cpp netgen-4.5.new/libsrc/occ/oc //cout << "\rFace " << i << " pos12 ntriangles " << ntriangles << flush; } } -diff -Naur netgen-4.5.old/libsrc/occ/occgeom.cpp netgen-4.5.new/libsrc/occ/occgeom.cpp ---- netgen-4.5.old/libsrc/occ/occgeom.cpp 2006-01-25 16:35:50.000000000 +0300 -+++ netgen-4.5.new/libsrc/occ/occgeom.cpp 2008-02-12 14:57:01.000000000 +0300 +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/occ/occgeom.cpp netgen-4.5_new/libsrc/occ/occgeom.cpp +--- netgen-4.5_orig/libsrc/occ/occgeom.cpp 2006-01-25 16:35:50.000000000 +0300 ++++ netgen-4.5_new/libsrc/occ/occgeom.cpp 2010-11-25 10:11:31.000000000 +0300 @@ -7,6 +7,8 @@ #include "ShapeAnalysis_ShapeContents.hxx" #include "ShapeAnalysis_CheckSmallFace.hxx" @@ -650,7 +972,7 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgeom.cpp netgen-4.5.new/libsrc/occ/occge BRepTools::Clean (shape); //WriteOCC_STL("test.stl"); - BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh (shape, vispar.occdeflection, true); -+ BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh (shape, vispar_occdeflection, true); ++ BRepMesh_IncrementalMesh (shape, vispar_occdeflection, true); cout << "done" << endl; @@ -784,9 +1106,29 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgeom.cpp netgen-4.5.new/libsrc/occ/occge return true; } -diff -Naur netgen-4.5.old/libsrc/occ/occgeom.hpp netgen-4.5.new/libsrc/occ/occgeom.hpp ---- netgen-4.5.old/libsrc/occ/occgeom.hpp 2006-01-25 16:35:50.000000000 +0300 -+++ netgen-4.5.new/libsrc/occ/occgeom.hpp 2008-02-12 14:57:01.000000000 +0300 +@@ -1190,16 +1189,16 @@ + return occgeo; + } + +- char * shapesname[] = ++ const char * shapesname[] = + {" ", "CompSolids", "Solids", "Shells", + + "Faces", "Wires", "Edges", "Vertices"}; + +- char * shapename[] = ++ const char * shapename[] = + {" ", "CompSolid", "Solid", "Shell", + "Face", "Wire", "Edge", "Vertex"}; + +- char * orientationstring[] = ++ const char * orientationstring[] = + {"+", "-"}; + + void OCCGeometry :: RecursiveTopologyTree (const TopoDS_Shape & sh, +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/occ/occgeom.hpp netgen-4.5_new/libsrc/occ/occgeom.hpp +--- netgen-4.5_orig/libsrc/occ/occgeom.hpp 2006-01-25 16:35:50.000000000 +0300 ++++ netgen-4.5_new/libsrc/occ/occgeom.hpp 2010-11-25 10:11:31.000000000 +0300 @@ -15,8 +15,6 @@ #include "Geom_Curve.hxx" #include "Geom2d_Curve.hxx" @@ -863,9 +1205,9 @@ diff -Naur netgen-4.5.old/libsrc/occ/occgeom.hpp netgen-4.5.new/libsrc/occ/occge OCCSurface GetSurface (int surfi) { cout << "OCCGeometry::GetSurface using PLANESPACE" << endl; -diff -Naur netgen-4.5.old/libsrc/occ/occmeshsurf.cpp netgen-4.5.new/libsrc/occ/occmeshsurf.cpp ---- netgen-4.5.old/libsrc/occ/occmeshsurf.cpp 2006-01-25 16:36:26.000000000 +0300 -+++ netgen-4.5.new/libsrc/occ/occmeshsurf.cpp 2008-02-12 14:57:01.000000000 +0300 +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/occ/occmeshsurf.cpp netgen-4.5_new/libsrc/occ/occmeshsurf.cpp +--- netgen-4.5_orig/libsrc/occ/occmeshsurf.cpp 2006-01-25 16:36:26.000000000 +0300 ++++ netgen-4.5_new/libsrc/occ/occmeshsurf.cpp 2010-11-25 10:11:31.000000000 +0300 @@ -5,6 +5,8 @@ #include #include @@ -981,9 +1323,9 @@ diff -Naur netgen-4.5.old/libsrc/occ/occmeshsurf.cpp netgen-4.5.new/libsrc/occ/o -diff -Naur netgen-4.5.old/libsrc/occ/occmeshsurf.hpp netgen-4.5.new/libsrc/occ/occmeshsurf.hpp ---- netgen-4.5.old/libsrc/occ/occmeshsurf.hpp 2005-06-09 18:51:10.000000000 +0400 -+++ netgen-4.5.new/libsrc/occ/occmeshsurf.hpp 2008-02-12 14:57:01.000000000 +0300 +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/occ/occmeshsurf.hpp netgen-4.5_new/libsrc/occ/occmeshsurf.hpp +--- netgen-4.5_orig/libsrc/occ/occmeshsurf.hpp 2005-06-09 18:51:10.000000000 +0400 ++++ netgen-4.5_new/libsrc/occ/occmeshsurf.hpp 2010-11-25 10:11:31.000000000 +0300 @@ -151,7 +151,7 @@ MeshOptimize2dOCCSurfaces (const OCCGeometry & ageometry); @@ -1003,9 +1345,20 @@ diff -Naur netgen-4.5.old/libsrc/occ/occmeshsurf.hpp netgen-4.5.new/libsrc/occ/o }; -diff -Naur netgen-4.5.old/libsrc/stlgeom/meshstlsurface.cpp netgen-4.5.new/libsrc/stlgeom/meshstlsurface.cpp ---- netgen-4.5.old/libsrc/stlgeom/meshstlsurface.cpp 2006-01-11 19:08:20.000000000 +0300 -+++ netgen-4.5.new/libsrc/stlgeom/meshstlsurface.cpp 2008-02-12 14:57:01.000000000 +0300 +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/occ/utilities.h netgen-4.5_new/libsrc/occ/utilities.h +--- netgen-4.5_orig/libsrc/occ/utilities.h 2005-02-11 14:35:43.000000000 +0300 ++++ netgen-4.5_new/libsrc/occ/utilities.h 2010-11-25 10:11:31.000000000 +0300 +@@ -33,6 +33,7 @@ + + #include + #include ++#include + #include + // #include "SALOME_Log.hxx" + +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/stlgeom/meshstlsurface.cpp netgen-4.5_new/libsrc/stlgeom/meshstlsurface.cpp +--- netgen-4.5_orig/libsrc/stlgeom/meshstlsurface.cpp 2006-01-11 19:08:20.000000000 +0300 ++++ netgen-4.5_new/libsrc/stlgeom/meshstlsurface.cpp 2010-11-25 10:11:31.000000000 +0300 @@ -946,20 +946,23 @@ } @@ -1054,9 +1407,9 @@ diff -Naur netgen-4.5.old/libsrc/stlgeom/meshstlsurface.cpp netgen-4.5.new/libsr void MeshOptimizeSTLSurface :: GetNormalVector(INDEX surfind, const Point3d & p, Vec3d & n) const { n = geom.GetChartNormalVector(); -diff -Naur netgen-4.5.old/libsrc/stlgeom/meshstlsurface.hpp netgen-4.5.new/libsrc/stlgeom/meshstlsurface.hpp ---- netgen-4.5.old/libsrc/stlgeom/meshstlsurface.hpp 2004-09-30 17:13:56.000000000 +0400 -+++ netgen-4.5.new/libsrc/stlgeom/meshstlsurface.hpp 2008-02-12 14:57:01.000000000 +0300 +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/stlgeom/meshstlsurface.hpp netgen-4.5_new/libsrc/stlgeom/meshstlsurface.hpp +--- netgen-4.5_orig/libsrc/stlgeom/meshstlsurface.hpp 2004-09-30 17:13:56.000000000 +0400 ++++ netgen-4.5_new/libsrc/stlgeom/meshstlsurface.hpp 2010-11-25 10:11:31.000000000 +0300 @@ -79,12 +79,10 @@ virtual void SelectSurfaceOfPoint (const Point3d & p, const PointGeomInfo & gi); @@ -1071,14 +1424,48 @@ diff -Naur netgen-4.5.old/libsrc/stlgeom/meshstlsurface.hpp netgen-4.5.new/libsr virtual void GetNormalVector(INDEX surfind, const Point3d & p, Vec3d & n) const; }; -diff -Naur netgen-4.5.old/makeForSalome.sh netgen-4.5.new/makeForSalome.sh ---- netgen-4.5.old/makeForSalome.sh 1970-01-01 03:00:00.000000000 +0300 -+++ netgen-4.5.new/makeForSalome.sh 2008-02-12 14:57:01.000000000 +0300 -@@ -0,0 +1,31 @@ +diff -Naur --exclude=CVS netgen-4.5_orig/libsrc/stlgeom/stlgeommesh.cpp netgen-4.5_new/libsrc/stlgeom/stlgeommesh.cpp +--- netgen-4.5_orig/libsrc/stlgeom/stlgeommesh.cpp 2004-08-10 03:39:45.000000000 +0400 ++++ netgen-4.5_new/libsrc/stlgeom/stlgeommesh.cpp 2010-11-25 10:11:31.000000000 +0300 +@@ -1437,7 +1437,7 @@ + + if (!optstring || strlen(optstring) == 0) + { +- mparam.optimize2d = "smcm"; ++ mparam.optimize2d = (char*)"smcm"; + } + else + { +@@ -1453,7 +1453,7 @@ + mparam.grading); + mesh -> LoadLocalMeshSize (mparam.meshsizefilename); + mesh -> CalcLocalHFromSurfaceCurvature (stlparam.resthsurfmeshcurvfac); +- mparam.optimize2d = "cmsmSm"; ++ mparam.optimize2d = (char*)"cmsmSm"; + STLSurfaceOptimization (*stlgeometry, *mesh, mparam); + #ifdef STAT_STREAM + (*statout) << GetTime() << " & "; +@@ -1559,7 +1559,7 @@ + + if (!optstring || strlen(optstring) == 0) + { +- mparam.optimize3d = "cmdmstm"; ++ mparam.optimize3d = (char*)"cmdmstm"; + } + else + { +diff -Naur --exclude=CVS netgen-4.5_orig/makeForSalome.sh netgen-4.5_new/makeForSalome.sh +--- netgen-4.5_orig/makeForSalome.sh 1970-01-01 03:00:00.000000000 +0300 ++++ netgen-4.5_new/makeForSalome.sh 2010-11-25 10:11:31.000000000 +0300 +@@ -0,0 +1,35 @@ +#! /bin/sh +cp ngtcltk/ngnewdelete.* libsrc/interface/ + -+MACHINE=LINUX ++if test `uname -m` = "x86_64" ; then ++ MACHINE=LINUX64 ++else ++ MACHINE=LINUX ++fi +export MACHINE +make -C libsrc/csg +make -C libsrc/general @@ -1102,128 +1489,7 @@ diff -Naur netgen-4.5.old/makeForSalome.sh netgen-4.5.new/makeForSalome.sh +fi + +cp libsrc/interface/nglib.h libsrc/general/*.hpp libsrc/csg/*.hpp libsrc/geom2d/*.hpp \ -+ libsrc/gprim/*.hpp libsrc/linalg/*.hpp libsrc/meshing/*.hpp \ -+ libsrc/occ/*.hpp libsrc/opti/*.hpp libsrc/include/mydefs.hpp \ -+ libsrc/stlgeom/*.hpp libsrc/include/mystdlib.h \ -+ install/include -diff -Naur netgen-4.5.old/libsrc/occ/Partition_Inter2d.cxx netgen-4.5.new/libsrc/occ/Partition_Inter2d.cxx ---- netgen-4.5.old/libsrc/occ/Partition_Inter2d.cxx 2005-06-09 18:51:10.000000000 +0400 -+++ netgen-4.5.new/libsrc/occ/Partition_Inter2d.cxx 2008-02-26 12:34:14.000000000 +0300 -@@ -29,10 +29,10 @@ - // $Header$ - - //using namespace std; --#include "Partition_Inter2d.ixx" -- - #include "utilities.h" - -+#include "Partition_Inter2d.ixx" -+ - #include - #include - #include -diff -Naur netgen-4.5.old/libsrc/occ/Partition_Inter3d.cxx netgen-4.5.new/libsrc/occ/Partition_Inter3d.cxx ---- netgen-4.5.old/libsrc/occ/Partition_Inter3d.cxx 2005-06-09 18:51:10.000000000 +0400 -+++ netgen-4.5.new/libsrc/occ/Partition_Inter3d.cxx 2008-02-26 12:36:27.000000000 +0300 -@@ -29,13 +29,17 @@ - // $Header$ - - //using namespace std; -+ -+#include "utilities.h" -+ - #include "Partition_Inter2d.hxx" - #include "Partition_Inter3d.ixx" --#include "utilities.h" - - #include - #include - #include -+//using namespace std; -+ - #include - #include - #include -diff -Naur netgen-4.5.old/libsrc/occ/Partition_Loop2d.cxx netgen-4.5.new/libsrc/occ/Partition_Loop2d.cxx ---- netgen-4.5.old/libsrc/occ/Partition_Loop2d.cxx 2005-06-09 18:51:10.000000000 +0400 -+++ netgen-4.5.new/libsrc/occ/Partition_Loop2d.cxx 2008-02-26 12:37:10.000000000 +0300 -@@ -12,9 +12,11 @@ - // $Header$ - - //using namespace std; --#include "Partition_Loop2d.ixx" -+ - - #include "utilities.h" -+ -+#include "Partition_Loop2d.ixx" - #include - - #include -diff -Naur netgen-4.5.old/libsrc/occ/Partition_Loop3d.cxx netgen-4.5.new/libsrc/occ/Partition_Loop3d.cxx ---- netgen-4.5.old/libsrc/occ/Partition_Loop3d.cxx 2005-06-09 18:51:10.000000000 +0400 -+++ netgen-4.5.new/libsrc/occ/Partition_Loop3d.cxx 2008-02-26 12:39:32.000000000 +0300 -@@ -10,6 +10,11 @@ - // Module : GEOM - - //using namespace std; -+ -+ -+ -+#include "utilities.h" -+ - #include "Partition_Loop3d.ixx" - - #include -diff -Naur netgen-4.5.old/libsrc/occ/Partition_Loop.cxx netgen-4.5.new/libsrc/occ/Partition_Loop.cxx ---- netgen-4.5.old/libsrc/occ/Partition_Loop.cxx 2005-06-09 18:51:10.000000000 +0400 -+++ netgen-4.5.new/libsrc/occ/Partition_Loop.cxx 2008-02-26 12:40:41.000000000 +0300 -@@ -29,12 +29,14 @@ - // $Header$ - - //using namespace std; --#include - --#include "Partition_Loop.ixx" - - #include "utilities.h" - -+#include -+ -+#include "Partition_Loop.ixx" -+ - #include - #include - #include -diff -Naur netgen-4.5.old/libsrc/occ/Partition_Spliter.cxx netgen-4.5.new/libsrc/occ/Partition_Spliter.cxx ---- netgen-4.5.old/libsrc/occ/Partition_Spliter.cxx 2005-07-11 10:33:27.000000000 +0400 -+++ netgen-4.5.new/libsrc/occ/Partition_Spliter.cxx 2008-02-26 12:41:32.000000000 +0300 -@@ -29,14 +29,15 @@ - // $Header$ - - //using namespace std; -+ -+#include "utilities.h" -+ - #include "Partition_Inter2d.hxx" - #include "Partition_Inter3d.hxx" - #include "Partition_Loop2d.hxx" - #include "Partition_Loop3d.hxx" - #include "Partition_Spliter.ixx" - --#include "utilities.h" -- - #include - #include - #include -diff -Naur netgen-4.5.old/libsrc/occ/utilities.h netgen-4.5.new/libsrc/occ/utilities.h ---- netgen-4.5.old/libsrc/occ/utilities.h 2005-02-11 14:35:43.000000000 +0300 -+++ netgen-4.5.new/libsrc/occ/utilities.h 2008-02-26 12:28:02.000000000 +0300 -@@ -33,6 +33,7 @@ - - #include - #include -+#include - #include - // #include "SALOME_Log.hxx" - ++ libsrc/gprim/*.hpp libsrc/linalg/*.hpp libsrc/meshing/*.hpp \ ++ libsrc/occ/*.hpp libsrc/opti/*.hpp libsrc/include/mydefs.hpp \ ++ libsrc/stlgeom/*.hpp libsrc/include/mystdlib.h \ ++ install/include diff --git a/src/NETGEN/netgen49ForSalome.patch b/src/NETGEN/netgen49ForSalome.patch new file mode 100644 index 0000000..0be0d34 --- /dev/null +++ b/src/NETGEN/netgen49ForSalome.patch @@ -0,0 +1,1014 @@ +diff -Naur netgen-4.9.13_orig/libsrc/meshing/meshtype.cpp netgen-4.9.13_new/libsrc/meshing/meshtype.cpp +--- netgen-4.9.13_orig/libsrc/meshing/meshtype.cpp 2009-09-13 14:28:38.000000000 +0400 ++++ netgen-4.9.13_new/libsrc/meshing/meshtype.cpp 2011-12-20 14:50:26.000000000 +0400 +@@ -1,4 +1,5 @@ + #include ++#include // to get DBL_MIN defined + + #include "meshing.hpp" + +@@ -650,7 +651,8 @@ + + double det = trans.Det(); + +- if (det <= 0) ++ // if (det <= 0) ++ if (det <= DBL_MIN) // avoid FPE + err += 1e12; + else + err += frob * frob / det; +@@ -706,7 +708,8 @@ + + double det = trans(0,0)*trans(1,1)-trans(1,0)*trans(0,1); + +- if (det <= 0) ++ // if (det <= 0) ++ if (det <= DBL_MIN) // avoid FPE + { + dd = 0; + return 1e12; +@@ -790,7 +793,8 @@ + = dtrans(0,0) * trans(1,1) - trans(0,1) * dtrans(1,0) + + trans(0,0) * dtrans(1,1) - dtrans(0,1) * trans(1,0); + +- if (det <= 0) ++ // if (det <= 0) ++ if (det <= DBL_MIN) // avoid FPE + err += 1e12; + else + { +@@ -840,7 +844,8 @@ + frob /= 2; + + double det = trans.Det(); +- if (det <= 0) ++ //if (det <= 0) ++ if (det <= DBL_MIN) // avoid FPE + err += 1e12; + else + err += frob * frob / det; +@@ -1857,7 +1862,8 @@ + case PYRAMID: + { + double noz = 1-p(2); +- if (noz == 0.0) noz = 1e-10; ++ //if (noz == 0.0) noz = 1e-10; ++ if (noz <= DBL_MIN) noz = 1e-10; // avoid FPE + + double xi = p(0) / noz; + double eta = p(1) / noz; +@@ -2035,7 +2041,8 @@ + + double det = -trans.Det(); + +- if (det <= 0) ++ //if (det <= 0) ++ if (det <= DBL_MIN) // avoid FPE + err += 1e12; + else + err += frob * frob * frob / det; +@@ -2107,7 +2114,8 @@ + ddet *= -1; + + +- if (det <= 0) ++ //if (det <= 0) ++ if (det <= DBL_MIN) // avoid FPE + err += 1e12; + else + { +@@ -2189,7 +2197,7 @@ + + det *= -1; + +- if (det <= 0) ++ if (det <= DBL_MIN) + err += 1e12; + else + { +@@ -2522,10 +2530,10 @@ + + MeshingParameters :: MeshingParameters () + { +- optimize3d = "cmdmustm"; ++ optimize3d = (char*)"cmdmustm"; // optimize3d = "cmdmustm"; + //optimize3d = "cmdmstm"; + optsteps3d = 3; +- optimize2d = "smsmsmSmSmSm"; ++ optimize2d = (char*)"smsmsmSmSmSm"; // optimize2d = "smsmsmSmSmSm"; + optsteps2d = 3; + opterrpow = 2; + blockfill = 1; +diff -Naur netgen-4.9.13_orig/libsrc/meshing/meshtype.hpp netgen-4.9.13_new/libsrc/meshing/meshtype.hpp +--- netgen-4.9.13_orig/libsrc/meshing/meshtype.hpp 2009-11-09 13:50:43.000000000 +0300 ++++ netgen-4.9.13_new/libsrc/meshing/meshtype.hpp 2011-12-20 14:50:26.000000000 +0400 +@@ -12,6 +12,7 @@ + Classes for NETGEN + */ + ++class Mesh; // added due to compilation errors on some platforms + + enum ELEMENT_TYPE { + SEGMENT = 1, SEGMENT3 = 2, +diff -Naur netgen-4.9.13_orig/libsrc/meshing/smoothing2.cpp netgen-4.9.13_new/libsrc/meshing/smoothing2.cpp +--- netgen-4.9.13_orig/libsrc/meshing/smoothing2.cpp 2009-11-09 13:47:09.000000000 +0300 ++++ netgen-4.9.13_new/libsrc/meshing/smoothing2.cpp 2011-12-20 14:50:26.000000000 +0400 +@@ -302,7 +302,8 @@ + vgrad = 0; + badness = 0; + +- meshthis -> GetNormalVector (surfi, sp1, gi1, n); ++ //normal already computed: meshthis -> GetNormalVector (surfi, sp1, gi1, n); ++ n = normal; + pp1 = sp1 + x(0) * t1 + x(1) * t2; + + // meshthis -> ProjectPoint (surfi, pp1); +@@ -360,7 +361,8 @@ + vgrad = 0; + badness = 0; + +- meshthis -> GetNormalVector (surfi, sp1, gi1, n); ++ //normal already computed: meshthis -> GetNormalVector (surfi, sp1, gi1, n); ++ n = normal; + + pp1 = sp1 + x(0) * t1 + x(1) * t2; + +@@ -514,7 +516,8 @@ + vgrad = 0; + badness = 0; + +- meshthis -> GetNormalVector (surfi, sp1, gi1, n); ++ //normal already computed: meshthis -> GetNormalVector (surfi, sp1, gi1, n); ++ n = normal; + + pp1 = sp1 + x(0) * t1 + x(1) * t2; + +@@ -586,7 +589,8 @@ + vgrad = 0; + badness = 0; + +- meshthis -> GetNormalVector (surfi, sp1, gi1, n); ++ //normal already computed: meshthis -> GetNormalVector (surfi, sp1, gi1, n); ++ n = normal; + + // pp1 = sp1; + // pp1.Add2 (x.Get(1), t1, x.Get(2), t2); +@@ -973,7 +977,7 @@ + { + mesh[pi] = Point<3> (origp); + } +- ++ break; // exit as is not used anymore + } + } + +diff -Naur netgen-4.9.13_orig/libsrc/occ/occconstruction.cpp netgen-4.9.13_new/libsrc/occ/occconstruction.cpp +--- netgen-4.9.13_orig/libsrc/occ/occconstruction.cpp 2009-08-24 06:32:47.000000000 +0400 ++++ netgen-4.9.13_new/libsrc/occ/occconstruction.cpp 2011-12-20 14:50:26.000000000 +0400 +@@ -28,7 +28,7 @@ + #include + #include + #include +-#include ++//#include + //#include + #include + #include +diff -Naur netgen-4.9.13_orig/libsrc/occ/occgenmesh.cpp netgen-4.9.13_new/libsrc/occ/occgenmesh.cpp +--- netgen-4.9.13_orig/libsrc/occ/occgenmesh.cpp 2010-03-16 09:30:07.000000000 +0300 ++++ netgen-4.9.13_new/libsrc/occ/occgenmesh.cpp 2011-12-20 14:50:26.000000000 +0400 +@@ -15,6 +15,8 @@ + + #define DIVIDEEDGESECTIONS 1000 + #define IGNORECURVELENGTH 1e-4 ++// a small value used to avoid FPE ++#define VSMALL 1e-10 + + + bool merge_solids = 1; +@@ -26,7 +28,8 @@ + double nq = n*q; + + Point<3> p = p0 + 0.5*n; +- double lambda = (p-l.p0)*n / nq; ++ // double lambda = (p-l.p0)*n / nq; -- avoid FPE ++ double lambda = (fabs(nq) > 1e-10) ? (p-l.p0)*n / nq : -1; + + if (lambda >= 0 && lambda <= 1) + { +@@ -54,6 +57,8 @@ + + + ++ ++ static // useless out of this file + double ComputeH (double kappa) + { + double hret; +@@ -62,7 +67,8 @@ + if (mparam.maxh * kappa < 1) + hret = mparam.maxh; + else +- hret = 1 / kappa; ++ // hret = 1 / kappa; -- avoid FPE ++ hret = 1 / (kappa + VSMALL); + + if (mparam.maxh < hret) + hret = mparam.maxh; +@@ -71,8 +77,7 @@ + } + + +- +- ++ static // useless out of this file + void RestrictHTriangle (gp_Pnt2d & par0, gp_Pnt2d & par1, gp_Pnt2d & par2, + BRepLProp_SLProps * prop, Mesh & mesh, int depth, double h = 0) + { +@@ -168,8 +173,8 @@ + if(h < 1e-4*maxside) + return; + +- +- if (h > 30) return; ++ // commented to restrict H on a large sphere for example ++ //if (h > 30) return; + } + + if (h < maxside && depth < 10) +@@ -228,6 +233,7 @@ + + + ++ static // useless out of this file + void DivideEdge (TopoDS_Edge & edge, Array & ps, + Array & params, Mesh & mesh) + { +@@ -247,8 +253,8 @@ + hvalue[0] = 0; + pnt = c->Value(s0); + +- double olddist = 0; +- double dist = 0; ++ //double olddist = 0; -- useless variables ++ //double dist = 0; + + int tmpVal = (int)(DIVIDEEDGESECTIONS); + +@@ -256,15 +262,19 @@ + { + oldpnt = pnt; + pnt = c->Value(s0+(i/double(DIVIDEEDGESECTIONS))*(s1-s0)); ++ // -- no more than 1 segment per /DIVIDEEDGESECTIONS + hvalue[i] = hvalue[i-1] + +- 1.0/mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z()))* +- pnt.Distance(oldpnt); ++ // 1.0/mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z()))* ++ // pnt.Distance(oldpnt); ++ min( 1.0, ++ 1.0/mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z()))* ++ pnt.Distance(oldpnt)); + + //(*testout) << "mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z())) " << mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z())) + // << " pnt.Distance(oldpnt) " << pnt.Distance(oldpnt) << endl; + +- olddist = dist; +- dist = pnt.Distance(oldpnt); ++ //olddist = dist; -- useless variables ++ //dist = pnt.Distance(oldpnt); + } + + // nsubedges = int(ceil(hvalue[DIVIDEEDGESECTIONS])); +@@ -279,7 +289,10 @@ + { + if (hvalue[i1]/hvalue[DIVIDEEDGESECTIONS]*nsubedges >= i) + { +- params[i] = s0+(i1/double(DIVIDEEDGESECTIONS))*(s1-s0); ++ // -- for nsubedges comparable to DIVIDEEDGESECTIONS ++ //params[i] = s0+(i1/double(DIVIDEEDGESECTIONS))*(s1-s0); ++ double d1 = i1 - (hvalue[i1] - i*hvalue[DIVIDEEDGESECTIONS]/nsubedges)/(hvalue[i1]-hvalue[i1-1]); ++ params[i] = s0+(d1/double(DIVIDEEDGESECTIONS))*(s1-s0); + pnt = c->Value(params[i]); + ps[i-1] = MeshPoint (Point3d(pnt.X(), pnt.Y(), pnt.Z())); + i++; +@@ -323,6 +336,7 @@ + (*testout) << "nedges = " << nedges << endl; + + double eps = 1e-6 * geom.GetBoundingBox().Diam(); ++ const double eps2 = eps * eps; // -- small optimization + + for (int i = 1; i <= nvertices; i++) + { +@@ -332,7 +346,8 @@ + bool exists = 0; + if (merge_solids) + for (PointIndex pi = 1; pi <= mesh.GetNP(); pi++) +- if ( Dist2 (mesh[pi], Point<3>(mp)) < eps*eps) ++ //if ( Dist2 (mesh[pi], Point<3>(mp)) < eps*eps) ++ if ( Dist2 (mesh[pi], Point<3>(mp)) < eps2 ) // -- small optimization + { + exists = 1; + break; +@@ -362,6 +377,7 @@ + { + TopoDS_Face face = TopoDS::Face(exp1.Current()); + int facenr = geom.fmap.FindIndex(face); ++ if ( facenr < 1 ) continue; // -- to support SALOME sub-meshes + + if (face2solid[0][facenr-1] == 0) + face2solid[0][facenr-1] = solidnr; +@@ -381,6 +397,7 @@ + int facenr = 0; + int edgenr = 0; + ++ edgenr = mesh.GetNSeg(); // to support SALOME sub-meshes + + (*testout) << "faces = " << geom.fmap.Extent() << endl; + int curr = 0; +@@ -442,6 +459,7 @@ + //(*testout) << "ignoring degenerated edge" << endl; + continue; + } ++ if ( geom.emap.FindIndex(edge) < 1 ) continue; // to support SALOME sub-meshes + + if (geom.vmap.FindIndex(TopExp::FirstVertex (edge)) == + geom.vmap.FindIndex(TopExp::LastVertex (edge))) +@@ -479,15 +497,64 @@ + } + else + { +- Point<3> fp = occ2ng (BRep_Tool::Pnt (TopExp::FirstVertex (edge))); +- Point<3> lp = occ2ng (BRep_Tool::Pnt (TopExp::LastVertex (edge))); ++ TopoDS_Iterator vIt( edge, false ); ++ TopoDS_Vertex v1 = TopoDS::Vertex( vIt.Value() ); vIt.Next(); ++ TopoDS_Vertex v2 = TopoDS::Vertex( vIt.Value() ); ++ if ( v1.Orientation() == TopAbs_REVERSED ) ++ std::swap( v1, v2 ); ++ const bool isClosedEdge = v1.IsSame( v2 ); ++ ++ Point<3> fp = occ2ng (BRep_Tool::Pnt (v1)); ++ Point<3> lp = occ2ng (BRep_Tool::Pnt (v2)); ++ double tol2 = std::min( eps*eps, 1e-6 * Dist2( fp, lp )); ++ if ( isClosedEdge ) ++ tol2 = BRep_Tool::Tolerance( v1 ) * BRep_Tool::Tolerance( v1 ); + + pnums[0] = -1; + pnums.Last() = -1; + for (PointIndex pi = 1; pi < first_ep; pi++) + { +- if (Dist2 (mesh[pi], fp) < eps*eps) pnums[0] = pi; +- if (Dist2 (mesh[pi], lp) < eps*eps) pnums.Last() = pi; ++ if (Dist2 (mesh[pi], fp) < tol2) pnums[0] = pi; ++ if (Dist2 (mesh[pi], lp) < tol2) pnums.Last() = pi; ++ } ++ if (( isClosedEdge && pnums[0] != pnums.Last() ) || ++ ( !isClosedEdge && pnums[0] == pnums.Last() )) ++ pnums[0] = pnums.Last() = -1; ++ if ( pnums[0] == -1 || pnums.Last() == -1 ) ++ { ++ // take into account a possible large gap between a vertex and an edge curve ++ // end and a large vertex tolerance covering the whole edge ++ if ( pnums[0] == -1 ) ++ { ++ double tol = BRep_Tool::Tolerance( v1 ); ++ for (PointIndex pi = 1; pi < first_ep; pi++) ++ if (pi != pnums.Last() && Dist2 (mesh[pi], fp) < 2*tol*tol) ++ pnums[0] = pi; ++ ++ if ( pnums[0] == -1 ) ++ pnums[0] = first_ep-1- nvertices + geom.vmap.FindIndex ( v1 ); ++ } ++ if ( isClosedEdge ) ++ { ++ pnums.Last() = pnums[0]; ++ } ++ else ++ { ++ if ( pnums.Last() == -1 ) ++ { ++ double tol = BRep_Tool::Tolerance( v2 ); ++ for (PointIndex pi = 1; pi < first_ep; pi++) ++ if (pi != pnums[0] && Dist2 (mesh[pi], lp) < 2*tol*tol) ++ pnums.Last() = pi; ++ ++ if ( pnums.Last() == -1 ) ++ pnums.Last() = first_ep-1-nvertices + geom.vmap.FindIndex ( v2 ); ++ } ++ ++ if ( Dist2( fp, mesh[PointIndex(pnums[0])]) > ++ Dist2( lp, mesh[PointIndex(pnums.Last())])) ++ std::swap( pnums[0], pnums.Last() ); ++ } + } + } + +@@ -633,7 +700,8 @@ + } + + (*testout) << "mesh face " << k << endl; +- multithread.percent = 100 * k / (mesh.GetNFD()+1e-10); ++ // multithread.percent = 100 * k / (mesh.GetNFD()+1e-10); -- avoid FPE ++ multithread.percent = 100 * k / (mesh.GetNFD() + VSMALL); + geom.facemeshstatus[k-1] = -1; + + +@@ -901,7 +969,8 @@ + // if (k != 36) continue; + + // (*testout) << "optimize face " << k << endl; +- multithread.percent = 100 * k / (mesh.GetNFD()+1e-10); ++ //multithread.percent = 100 * k / (mesh.GetNFD()+1e-10); -- avoid FPE ++ multithread.percent = 100 * k / (mesh.GetNFD() + VSMALL); + + FaceDescriptor & fd = mesh.GetFaceDescriptor(k); + +@@ -1456,3 +1525,4 @@ + } + + #endif ++ +diff -Naur netgen-4.9.13_orig/libsrc/occ/occgeom.cpp netgen-4.9.13_new/libsrc/occ/occgeom.cpp +--- netgen-4.9.13_orig/libsrc/occ/occgeom.cpp 2010-03-05 16:16:21.000000000 +0300 ++++ netgen-4.9.13_new/libsrc/occ/occgeom.cpp 2011-12-20 14:50:26.000000000 +0400 +@@ -8,6 +8,8 @@ + #include "ShapeAnalysis_CheckSmallFace.hxx" + #include "ShapeAnalysis_DataMapOfShapeListOfReal.hxx" + #include "ShapeAnalysis_Surface.hxx" ++#include // -- to optimize Project() and FastProject() ++#include + #include "BRepAlgoAPI_Fuse.hxx" + #include "BRepCheck_Analyzer.hxx" + #include "BRepLib.hxx" +@@ -16,10 +18,17 @@ + #include "ShapeFix_FixSmallFace.hxx" + #include "Partition_Spliter.hxx" + +- + namespace netgen + { +- void OCCGeometry :: PrintNrShapes () ++ // free data used to optimize Project() and FastProject() ++ OCCGeometry::~OCCGeometry() ++ { ++ NCollection_DataMap::Iterator it(fclsmap); ++ for (; it.More(); it.Next()) ++ delete it.Value(); ++ } ++ ++ void OCCGeometry :: PrintNrShapes () + { + TopExp_Explorer e; + int count = 0; +@@ -951,25 +960,58 @@ + } + + ++ // returns a projector and a classifier for the given surface ++ void OCCGeometry::GetFaceTools(int surfi, Handle(ShapeAnalysis_Surface)& proj, ++ BRepTopAdaptor_FClass2d*& cls) const ++ { ++ //MSV: organize caching projector in the map ++ if (fprjmap.IsBound(surfi)) ++ { ++ proj = fprjmap.Find(surfi); ++ cls = fclsmap.Find(surfi); ++ } ++ else ++ { ++ const TopoDS_Face& aFace = TopoDS::Face(fmap(surfi)); ++ Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); ++ proj = new ShapeAnalysis_Surface(aSurf); ++ fprjmap.Bind(surfi, proj); ++ cls = new BRepTopAdaptor_FClass2d(aFace,Precision::Confusion()); ++ fclsmap.Bind(surfi, cls); ++ } ++ } + +- +- void OCCGeometry :: Project (int surfi, Point<3> & p) const ++ // void OCCGeometry :: Project (int surfi, Point<3> & p) const ++ bool OCCGeometry :: Project (int surfi, Point<3> & p, double& u, double& v) const + { + static int cnt = 0; + if (++cnt % 1000 == 0) cout << "Project cnt = " << cnt << endl; + + gp_Pnt pnt(p(0), p(1), p(2)); + +- double u,v; +- Handle( Geom_Surface ) thesurf = BRep_Tool::Surface(TopoDS::Face(fmap(surfi))); +- Handle( ShapeAnalysis_Surface ) su = new ShapeAnalysis_Surface( thesurf ); +- gp_Pnt2d suval = su->ValueOfUV ( pnt, BRep_Tool::Tolerance( TopoDS::Face(fmap(surfi)) ) ); +- suval.Coord( u, v); +- pnt = thesurf->Value( u, v ); +- +- ++ // -- Optimization: use cached projector and classifier ++ // double u,v; ++ // Handle( Geom_Surface ) thesurf = BRep_Tool::Surface(TopoDS::Face(fmap(surfi))); ++ // Handle( ShapeAnalysis_Surface ) su = new ShapeAnalysis_Surface( thesurf ); ++ // gp_Pnt2d suval = su->ValueOfUV ( pnt, BRep_Tool::Tolerance( TopoDS::Face(fmap(surfi)) ) ); ++ // suval.Coord( u, v); ++ // pnt = thesurf->Value( u, v ); ++ ++ Handle(ShapeAnalysis_Surface) proj; ++ BRepTopAdaptor_FClass2d *cls; ++ GetFaceTools(surfi, proj, cls); ++ ++ gp_Pnt2d p2d = proj->ValueOfUV(pnt, Precision::Confusion()); ++ if (cls->Perform(p2d) == TopAbs_OUT) ++ { ++ return false; ++ } ++ pnt = proj->Value(p2d); ++ p2d.Coord(u, v); ++ + p = Point<3> (pnt.X(), pnt.Y(), pnt.Z()); + ++ return true; + } + + +@@ -979,54 +1021,69 @@ + { + gp_Pnt p(ap(0), ap(1), ap(2)); + +- Handle(Geom_Surface) surface = BRep_Tool::Surface(TopoDS::Face(fmap(surfi))); +- +- gp_Pnt x = surface->Value (u,v); +- +- if (p.SquareDistance(x) <= sqr(PROJECTION_TOLERANCE)) return true; +- +- gp_Vec du, dv; +- +- surface->D1(u,v,x,du,dv); +- +- int count = 0; +- +- gp_Pnt xold; +- gp_Vec n; +- double det, lambda, mu; +- +- do { +- count++; +- +- n = du^dv; +- +- det = Det3 (n.X(), du.X(), dv.X(), +- n.Y(), du.Y(), dv.Y(), +- n.Z(), du.Z(), dv.Z()); +- +- if (det < 1e-15) return false; +- +- lambda = Det3 (n.X(), p.X()-x.X(), dv.X(), +- n.Y(), p.Y()-x.Y(), dv.Y(), +- n.Z(), p.Z()-x.Z(), dv.Z())/det; +- +- mu = Det3 (n.X(), du.X(), p.X()-x.X(), +- n.Y(), du.Y(), p.Y()-x.Y(), +- n.Z(), du.Z(), p.Z()-x.Z())/det; +- +- u += lambda; +- v += mu; +- +- xold = x; +- surface->D1(u,v,x,du,dv); +- +- } while (xold.SquareDistance(x) > sqr(PROJECTION_TOLERANCE) && count < 50); +- +- // (*testout) << "FastProject count: " << count << endl; +- +- if (count == 50) return false; +- +- ap = Point<3> (x.X(), x.Y(), x.Z()); ++ // -- Optimization: use cached projector and classifier ++ // Handle(Geom_Surface) surface = BRep_Tool::Surface(TopoDS::Face(fmap(surfi))); ++ // ++ // gp_Pnt x = surface->Value (u,v); ++ // ++ // if (p.SquareDistance(x) <= sqr(PROJECTION_TOLERANCE)) return true; ++ // ++ // gp_Vec du, dv; ++ // ++ // surface->D1(u,v,x,du,dv); ++ // ++ // int count = 0; ++ // ++ // gp_Pnt xold; ++ // gp_Vec n; ++ // double det, lambda, mu; ++ // ++ // do { ++ // count++; ++ // ++ // n = du^dv; ++ // ++ // det = Det3 (n.X(), du.X(), dv.X(), ++ // n.Y(), du.Y(), dv.Y(), ++ // n.Z(), du.Z(), dv.Z()); ++ // ++ // if (det < 1e-15) return false; ++ // ++ // lambda = Det3 (n.X(), p.X()-x.X(), dv.X(), ++ // n.Y(), p.Y()-x.Y(), dv.Y(), ++ // n.Z(), p.Z()-x.Z(), dv.Z())/det; ++ // ++ // mu = Det3 (n.X(), du.X(), p.X()-x.X(), ++ // n.Y(), du.Y(), p.Y()-x.Y(), ++ // n.Z(), du.Z(), p.Z()-x.Z())/det; ++ // ++ // u += lambda; ++ // v += mu; ++ // ++ // xold = x; ++ // surface->D1(u,v,x,du,dv); ++ // ++ // } while (xold.SquareDistance(x) > sqr(PROJECTION_TOLERANCE) && count < 50); ++ // ++ // // (*testout) << "FastProject count: " << count << endl; ++ // ++ // if (count == 50) return false; ++ // ++ // ap = Point<3> (x.X(), x.Y(), x.Z()); ++ Handle(ShapeAnalysis_Surface) proj; ++ BRepTopAdaptor_FClass2d *cls; ++ GetFaceTools(surfi, proj, cls); ++ ++ gp_Pnt2d p2d = proj->NextValueOfUV(gp_Pnt2d(u,v), p, Precision::Confusion()); ++ if (cls->Perform(p2d) == TopAbs_OUT) ++ { ++ //cout << "Projection fails" << endl; ++ return false; ++ } ++ ++ p = proj->Value(p2d); ++ p2d.Coord(u, v); ++ ap = Point<3> (p.X(), p.Y(), p.Z()); + + return true; + } +diff -Naur netgen-4.9.13_orig/libsrc/occ/occgeom.hpp netgen-4.9.13_new/libsrc/occ/occgeom.hpp +--- netgen-4.9.13_orig/libsrc/occ/occgeom.hpp 2010-01-14 19:56:19.000000000 +0300 ++++ netgen-4.9.13_new/libsrc/occ/occgeom.hpp 2011-12-20 14:50:26.000000000 +0400 +@@ -15,8 +15,8 @@ + #include "Geom_Curve.hxx" + #include "Geom2d_Curve.hxx" + #include "Geom_Surface.hxx" +-#include "GeomAPI_ProjectPointOnSurf.hxx" +-#include "GeomAPI_ProjectPointOnCurve.hxx" ++// #include "GeomAPI_ProjectPointOnSurf.hxx" ++// #include "GeomAPI_ProjectPointOnCurve.hxx" + #include "BRepTools.hxx" + #include "TopExp.hxx" + #include "BRepBuilderAPI_MakeVertex.hxx" +@@ -42,8 +42,8 @@ + #include "Geom_Curve.hxx" + #include "Geom2d_Curve.hxx" + #include "Geom_Surface.hxx" +-#include "GeomAPI_ProjectPointOnSurf.hxx" +-#include "GeomAPI_ProjectPointOnCurve.hxx" ++// #include "GeomAPI_ProjectPointOnSurf.hxx" ++// #include "GeomAPI_ProjectPointOnCurve.hxx" + #include "TopoDS_Wire.hxx" + #include "BRepTools_WireExplorer.hxx" + #include "BRepTools.hxx" +@@ -68,7 +68,7 @@ + #include "IGESToBRep_Reader.hxx" + #include "Interface_Static.hxx" + #include "GeomAPI_ExtremaCurveCurve.hxx" +-#include "Standard_ErrorHandler.hxx" ++//#include "Standard_ErrorHandler.hxx" + #include "Standard_Failure.hxx" + #include "ShapeUpgrade_ShellSewing.hxx" + #include "ShapeFix_Shape.hxx" +@@ -80,6 +80,10 @@ + #include "ShapeAnalysis.hxx" + #include "ShapeBuild_ReShape.hxx" + ++// -- Optimization: to use cached projector and classifier ++#include ++class Handle_ShapeAnalysis_Surface; ++class BRepTopAdaptor_FClass2d; + + // Philippose - 29/01/2009 + // OpenCascade XDE Support +@@ -190,6 +194,9 @@ + class OCCGeometry : public NetgenGeometry + { + Point<3> center; ++ // -- Optimization: to use cached projector and classifier ++ mutable NCollection_DataMap fprjmap; ++ mutable NCollection_DataMap fclsmap; + + public: + TopoDS_Shape shape; +@@ -241,6 +248,8 @@ + vmap.Clear(); + } + ++ ~OCCGeometry(); // -- to free cached projector and classifier ++ + void BuildFMap(); + + Box<3> GetBoundingBox() +@@ -260,9 +269,14 @@ + Point<3> Center() + { return center;} + +- void Project (int surfi, Point<3> & p) const; ++ // void Project (int surfi, Point<3> & p) const; -- optimization ++ bool Project (int surfi, Point<3> & p, double& u, double& v) const; + bool FastProject (int surfi, Point<3> & ap, double& u, double& v) const; + ++ // -- Optimization: to use cached projector and classifier ++ void GetFaceTools(int surfi, Handle(ShapeAnalysis_Surface)& proj, ++ BRepTopAdaptor_FClass2d*& cls) const; ++ + OCCSurface GetSurface (int surfi) + { + cout << "OCCGeometry::GetSurface using PLANESPACE" << endl; +diff -Naur netgen-4.9.13_orig/libsrc/occ/occmeshsurf.cpp netgen-4.9.13_new/libsrc/occ/occmeshsurf.cpp +--- netgen-4.9.13_orig/libsrc/occ/occmeshsurf.cpp 2009-08-24 06:32:47.000000000 +0400 ++++ netgen-4.9.13_new/libsrc/occ/occmeshsurf.cpp 2011-12-20 14:50:26.000000000 +0400 +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include // -- moved here from occgeom.hpp + + + namespace netgen +@@ -434,23 +435,33 @@ + + void MeshOptimize2dOCCSurfaces :: ProjectPoint (INDEX surfind, Point<3> & p) const + { +- geometry.Project (surfind, p); ++ // geometry.Project (surfind, p); -- signature of Project() changed for optimization ++ double u, v; ++ geometry.Project (surfind, p, u, v); + } + + + int MeshOptimize2dOCCSurfaces :: ProjectPointGI (INDEX surfind, Point<3> & p, PointGeomInfo & gi) const + { +- double u = gi.u; +- double v = gi.v; ++ //double u = gi.u; ++ //double v = gi.v; + + Point<3> hp = p; +- if (geometry.FastProject (surfind, hp, u, v)) +- { +- p = hp; +- return 1; +- } +- ProjectPoint (surfind, p); +- return CalcPointGeomInfo (surfind, gi, p); ++ // -- u and v are computed by FastProject() and Project(), no need to call CalcPointGeomInfo() ++ // if (geometry.FastProject (surfind, hp, u, v)) ++ // { ++ // p = hp; ++ // return 1; ++ // } ++ // ProjectPoint (surfind, p); ++ // return CalcPointGeomInfo (surfind, gi, p); ++ bool ok; ++ if (gi.trignum > 0) ++ ok = geometry.FastProject (surfind, hp, gi.u, gi.v); ++ else ++ ok = geometry.Project (surfind, hp, gi.u, gi.v); ++ p = hp; ++ return ok; + } + + +@@ -680,7 +691,8 @@ + if (!geometry.FastProject (surfi, hnewp, u, v)) + { + // cout << "Fast projection to surface fails! Using OCC projection" << endl; +- geometry.Project (surfi, hnewp); ++ // geometry.Project (surfi, hnewp); -- Project() changed for optimization ++ geometry.Project (surfi, hnewp, u, v); + } + + newgi.trignum = 1; +@@ -689,7 +701,7 @@ + } + + newp = hnewp; +- } ++ }//; -- to compile with -Wall -pedantic + + + void OCCRefinementSurfaces :: +@@ -708,14 +720,18 @@ + hnewp = Point<3> (pnt.X(), pnt.Y(), pnt.Z()); + newp = hnewp; + newgi = ap1; +- }; ++ } + + + void OCCRefinementSurfaces :: ProjectToSurface (Point<3> & p, int surfi) + { + if (surfi > 0) +- geometry.Project (surfi, p); +- }; ++ // geometry.Project (surfi, p); -- Project() changed for optimization ++ { ++ double u, v; ++ geometry.Project (surfi, p, u, v); ++ } ++ }//; -- to compile with -Wall -pedantic + + void OCCRefinementSurfaces :: ProjectToSurface (Point<3> & p, int surfi, PointGeomInfo & gi) + { +@@ -723,9 +739,10 @@ + if (!geometry.FastProject (surfi, p, gi.u, gi.v)) + { + cout << "Fast projection to surface fails! Using OCC projection" << endl; +- geometry.Project (surfi, p); ++ double u, v; ++ geometry.Project (surfi, p, u, v); + } +- }; ++ } + + + +diff -Naur netgen-4.9.13_orig/libsrc/occ/Partition_Inter3d.cxx netgen-4.9.13_new/libsrc/occ/Partition_Inter3d.cxx +--- netgen-4.9.13_orig/libsrc/occ/Partition_Inter3d.cxx 2009-08-24 06:12:24.000000000 +0400 ++++ netgen-4.9.13_new/libsrc/occ/Partition_Inter3d.cxx 2011-12-20 14:50:26.000000000 +0400 +@@ -86,6 +86,9 @@ + #include + #include + #include ++ ++#include ++ + #include + + //======================================================================= +@@ -243,7 +246,12 @@ + Standard_Integer i, nbExt = anExtPS.NbExt(); + Extrema_POnSurf aPOnSurf; + for (i = 1; i <= nbExt; ++i ) ++#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060400 ++// porting to OCCT6.5.1 ++ if (anExtPS.SquareDistance( i ) <= TolE * TolE) { ++#else + if (anExtPS.Value( i ) <= TolE) { ++#endif + aPOnSurf = anExtPS.Point( i ); + break; + } +diff -Naur netgen-4.9.13_orig/libsrc/occ/Partition_Loop2d.cxx netgen-4.9.13_new/libsrc/occ/Partition_Loop2d.cxx +--- netgen-4.9.13_orig/libsrc/occ/Partition_Loop2d.cxx 2009-08-24 06:12:24.000000000 +0400 ++++ netgen-4.9.13_new/libsrc/occ/Partition_Loop2d.cxx 2011-12-20 14:53:39.000000000 +0400 +@@ -22,7 +22,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -51,6 +50,15 @@ + #include + #include + ++#include ++ ++#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060400 ++// porting to OCCT6.5.1 ++#include ++#else ++#include ++#endif ++ + //======================================================================= + //function : Partition_Loop2d + //purpose : +@@ -209,7 +217,7 @@ + Cc->D1(uc, PC, CTg1); + if (!isForward) CTg1.Reverse(); + +- Standard_Real anglemin = 3 * PI, tolAng = 1.e-8; ++ Standard_Real anglemin = 3 * M_PI, tolAng = 1.e-8; + + // select an edge whose first derivative is most left of CTg1 + // ie an angle between Tg1 and CTg1 is least +@@ -233,7 +241,7 @@ + // -PI < angle < PI + Standard_Real angle = Tg1.Angle(CTg1); + +- if (PI - Abs(angle) <= tolAng) ++ if (M_PI - Abs(angle) <= tolAng) + { + // an angle is too close to PI; assure that an angle sign really + // reflects an edge position: +PI - an edge is worst, +@@ -519,7 +527,12 @@ + DC.Initialize( DegEdge, F ); + + // avoid intersecting twice the same edge ++#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060400 ++// porting to OCCT6.5.1 ++ TopTools_DataMapOfShapeReal EUMap ( EdgesList.Extent() ); ++#else + BRepOffset_DataMapOfShapeReal EUMap ( EdgesList.Extent() ); ++#endif + + Standard_Real U, f, l; + BRep_Tool::Range (DegEdge, f, l); +diff -Naur netgen-4.9.13_orig/libsrc/occ/Partition_Loop.cxx netgen-4.9.13_new/libsrc/occ/Partition_Loop.cxx +--- netgen-4.9.13_orig/libsrc/occ/Partition_Loop.cxx 2009-08-24 06:12:24.000000000 +0400 ++++ netgen-4.9.13_new/libsrc/occ/Partition_Loop.cxx 2011-12-20 14:53:05.000000000 +0400 +@@ -178,7 +178,7 @@ + } + } + +- Standard_Real anglemax = - PI; ++ Standard_Real anglemax = - M_PI; + TopoDS_Edge SelectedEdge; + for ( itl.Initialize(LE); itl.More(); itl.Next()) { + const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); +diff -Naur netgen-4.9.13_orig/libsrc/occ/Partition_Spliter.cxx netgen-4.9.13_new/libsrc/occ/Partition_Spliter.cxx +--- netgen-4.9.13_orig/libsrc/occ/Partition_Spliter.cxx 2009-08-24 06:12:24.000000000 +0400 ++++ netgen-4.9.13_new/libsrc/occ/Partition_Spliter.cxx 2011-12-20 14:50:26.000000000 +0400 +@@ -79,6 +79,8 @@ + #include + #include + ++#include ++ + #ifdef DEB + //# define PART_PERF + #endif +@@ -1169,7 +1171,12 @@ + for (; j<=nbj && ok; ++j) { + if (Extrema.IsMin(j)) { + hasMin = Standard_True; ++#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060400 ++// porting to OCCT6.5.1 ++ ok = Extrema.SquareDistance(j) <= tol * tol; ++#else + ok = Extrema.Value(j) <= tol; ++#endif + } + } + } +diff -Naur netgen-4.9.13_orig/libsrc/occ/utilities.h netgen-4.9.13_new/libsrc/occ/utilities.h +--- netgen-4.9.13_orig/libsrc/occ/utilities.h 2009-08-24 06:12:24.000000000 +0400 ++++ netgen-4.9.13_new/libsrc/occ/utilities.h 2011-12-20 14:50:26.000000000 +0400 +@@ -33,6 +33,7 @@ + + #include + #include ++#include + #include + // #include "SALOME_Log.hxx" + +diff -Naur netgen-4.9.13_orig/libsrc/stlgeom/stlgeommesh.cpp netgen-4.9.13_new/libsrc/stlgeom/stlgeommesh.cpp +--- netgen-4.9.13_orig/libsrc/stlgeom/stlgeommesh.cpp 2009-08-10 15:40:51.000000000 +0400 ++++ netgen-4.9.13_new/libsrc/stlgeom/stlgeommesh.cpp 2011-12-20 14:50:26.000000000 +0400 +@@ -1435,7 +1435,8 @@ + + if (!optstring || strlen(optstring) == 0) + { +- mparam.optimize2d = "smcm"; ++ //mparam.optimize2d = (char*)"smcm"; ++ mparam.optimize2d = (char*)"smcm"; + } + else + { +@@ -1451,7 +1452,8 @@ + mparam.grading); + mesh -> LoadLocalMeshSize (mparam.meshsizefilename); + mesh -> CalcLocalHFromSurfaceCurvature (stlparam.resthsurfmeshcurvfac); +- mparam.optimize2d = "cmsmSm"; ++ //mparam.optimize2d = (char*)"cmsmSm"; ++ mparam.optimize2d = (char*)"cmsmSm"; + STLSurfaceOptimization (*stlgeometry, *mesh, mparam); + #ifdef STAT_STREAM + (*statout) << GetTime() << " & "; +@@ -1557,7 +1559,8 @@ + + if (!optstring || strlen(optstring) == 0) + { +- mparam.optimize3d = "cmdmstm"; ++ //mparam.optimize3d = "cmdmstm"; ++ mparam.optimize3d = (char*)"cmdmstm"; + } + else + { +diff -Naur netgen-4.9.13_orig/nglib/nglib.h netgen-4.9.13_new/nglib/nglib.h +--- netgen-4.9.13_orig/nglib/nglib.h 2010-05-18 15:20:25.000000000 +0400 ++++ netgen-4.9.13_new/nglib/nglib.h 2011-12-20 14:50:26.000000000 +0400 +@@ -24,7 +24,7 @@ + // Philippose - 14.02.2009 + // Modifications for creating a DLL in Windows + #ifdef WIN32 +- #ifdef NGLIB_EXPORTS || nglib_EXPORTS ++ #if defined NGLIB_EXPORTS || defined nglib_EXPORTS + #define DLL_HEADER __declspec(dllexport) + #else + #define DLL_HEADER __declspec(dllimport) diff --git a/src/NETGEN/netgen_copy_include_for_salome b/src/NETGEN/netgen_copy_include_for_salome new file mode 100755 index 0000000..f54ade7 --- /dev/null +++ b/src/NETGEN/netgen_copy_include_for_salome @@ -0,0 +1,39 @@ +#!/bin/sh + +src_dir=$1 +install_dir=$2 + +if ! test -d $src_dir/libsrc ; then + echo "No dir $src_dir/libsrc ... Bye" + exit 1 +fi +if ! test -d $install_dir/share/netgen ; then + echo "No dir $install_dir/share/netgen ... Bye" + exit 1 +fi + +dest_dir=$install_dir/share/netgen/include +mkdir -p $dest_dir > /dev/null 2>&1 +cp -af $src_dir/libsrc/csg/*.hpp $dest_dir +cp -af $src_dir/libsrc/general/*.hpp $dest_dir +cp -af $src_dir/libsrc/geom2d/*.hpp $dest_dir +cp -af $src_dir/libsrc/gprim/*.hpp $dest_dir +cp -af $src_dir/libsrc/interface/*.hpp $dest_dir +cp -af $src_dir/libsrc/linalg/*.hpp $dest_dir +cp -af $src_dir/libsrc/meshing/*.hpp $dest_dir +cp -af $src_dir/libsrc/stlgeom/*.hpp $dest_dir +cp -af $src_dir/libsrc/visualization/*.hpp $dest_dir + +cp -af $src_dir/libsrc/occ/*.hpp $dest_dir +cp -af $src_dir/libsrc/occ/*.hxx $dest_dir +cp -af $src_dir/libsrc/occ/*.ixx $dest_dir +cp -af $src_dir/libsrc/occ/*.jxx $dest_dir +cp -af $src_dir/libsrc/occ/*.h $dest_dir + +cp -af $src_dir/libsrc/include/mystdlib.h $dest_dir +cp -af $src_dir/libsrc/include/mydefs.hpp $dest_dir +# cp -af $src_dir/libsrc/include/parallel.hpp $dest_dir + +rm -f $dest_dir/ngexception.hpp +rm -f $dest_dir/paralleltop.hpp +rm -f $dest_dir/soldata.hpp diff --git a/src/NETGENPlugin/Makefile.am b/src/NETGENPlugin/Makefile.am index de09762..a580ac9 100644 --- a/src/NETGENPlugin/Makefile.am +++ b/src/NETGENPlugin/Makefile.am @@ -1,24 +1,22 @@ -# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE # -# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. # -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License. +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. # -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # + # -* Makefile *- # Author : Edward AGAPOV (OCC) # Modified by : Alexander BORODIN (OCN) - autotools usage @@ -41,6 +39,8 @@ salomeinclude_HEADERS = \ NETGENPlugin_Hypothesis_i.hxx \ NETGENPlugin_Hypothesis_2D.hxx \ NETGENPlugin_Hypothesis_2D_i.hxx \ + NETGENPlugin_Hypothesis_3D_i.hxx \ + NETGENPlugin_Hypothesis_2D_ONLY_i.hxx \ NETGENPlugin_SimpleHypothesis_2D.hxx \ NETGENPlugin_SimpleHypothesis_3D.hxx \ NETGENPlugin_SimpleHypothesis_2D_i.hxx \ @@ -64,6 +64,8 @@ dist_libNETGENEngine_la_SOURCES = \ NETGENPlugin_Hypothesis_i.cxx \ NETGENPlugin_Hypothesis_2D.cxx \ NETGENPlugin_Hypothesis_2D_i.cxx \ + NETGENPlugin_Hypothesis_3D_i.cxx \ + NETGENPlugin_Hypothesis_2D_ONLY_i.cxx \ NETGENPlugin_Mesher.cxx \ NETGENPlugin_SimpleHypothesis_2D.cxx \ NETGENPlugin_SimpleHypothesis_3D.cxx \ @@ -77,16 +79,28 @@ libNETGENEngine_la_CPPFLAGS = \ $(MED_CXXFLAGS) \ $(GEOM_CXXFLAGS) \ $(CAS_CPPFLAGS) \ + $(VTK_INCLUDES) \ $(NETGEN_INCLUDES) \ $(SMESH_CXXFLAGS) \ $(CORBA_CXXFLAGS) \ $(CORBA_INCLUDES) \ $(BOOST_CPPFLAGS) \ - -I$(top_builddir)/idl \ - -I$(top_builddir)/salome_adm/unix + -I$(top_builddir)/idl -libNETGENEngine_la_LDFLAGS = \ - ../NETGEN/libNETGEN.la \ +if ! NETGEN_NEW +libNETGENEngine_la_LDFLAGS = ../NETGEN/libNETGEN.la +else +libNETGENEngine_la_LDFLAGS = $(NETGEN_LIBS) +endif + +libNETGENEngine_la_LDFLAGS += \ ../../idl/libSalomeIDLNETGENPLUGIN.la \ - $(SMESH_LDFLAGS) -lSMESHimpl -lSMESHEngine -lStdMeshersEngine \ - $(KERNEL_LDFLAGS) -lSalomeGenericObj + $(CAS_LDPATH) -lTKernel -lTKBRep -lTKShHealing -lTKSTEP -lTKXSBase -lTKIGES -lTKMesh -lTKSTL -lTKG3d -lTKTopAlgo -lTKG2d -lTKBool -lTKGeomAlgo -lTKOffset -lTKGeomBase -lTKBO \ + -lTKMath -lTKFillet -lTKMeshVS -lTKPrim -lTKSTEPBase -lTKSTEPAttr -lTKSTEP209 -lTKXDESTEP -lTKXDEIGES -lTKXCAF -lTKLCAF -lFWOSPlugin \ + $(GEOM_LDFLAGS) -lGEOMbasic \ + $(MED_LDFLAGS) -lSalomeIDLMED \ + $(SMESH_LDFLAGS) -lSMESHimpl -lSMESHEngine -lSMESHUtils -lStdMeshersEngine -lStdMeshers -lSMESHDS -lSMDS -lSMESHControls \ + $(KERNEL_LDFLAGS) -lSalomeGenericObj -lSalomeNS -lSALOMELocalTrace -lOpUtil + +# Scripts to be installed. +dist_salomescript_DATA= NETGENPluginDC.py diff --git a/src/NETGENPlugin/NETGENPluginDC.py b/src/NETGENPlugin/NETGENPluginDC.py new file mode 100644 index 0000000..9568df6 --- /dev/null +++ b/src/NETGENPlugin/NETGENPluginDC.py @@ -0,0 +1,306 @@ +# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +from smesh import Mesh_Algorithm, AssureGeomPublished, ParseParameters, IsEqual + +# import NETGENPlugin module if possible +noNETGENPlugin = 0 +try: + import NETGENPlugin +except ImportError: + noNETGENPlugin = 1 + pass + +# Types of algorithms +NETGEN_3D = "NETGEN_3D" +NETGEN_1D2D3D = "NETGEN_2D3D" +NETGEN_1D2D = "NETGEN_2D" +NETGEN_2D = "NETGEN_2D_ONLY" +NETGEN_FULL = NETGEN_1D2D3D +NETGEN = NETGEN_3D +FULL_NETGEN = NETGEN_FULL + +SOLE = 0 +SIMPLE = 1 + +# Fineness enumeration +VeryCoarse = 0 +Coarse = 1 +Moderate = 2 +Fine = 3 +VeryFine = 4 +Custom = 5 + +## Base of all NETGEN algorithms. +# +class NETGEN_Algorithm(Mesh_Algorithm): + + def __init__(self, mesh, geom=0): + Mesh_Algorithm.__init__(self) + if noNETGENPlugin: print "Warning: NETGENPlugin module unavailable" + self.Create(mesh, geom, self.algoType, "libNETGENEngine.so") + self.params = None + + ## Sets MaxSize + # + def SetMaxSize(self, theSize): + if self.Parameters(): + self.params.SetMaxSize(theSize) + + ## Sets MinSize + # + def SetMinSize(self, theSize): + if self.Parameters(): + self.params.SetMinSize(theSize) + + + ## Sets Optimize flag + # + def SetOptimize(self, theVal): + if self.Parameters(): + self.params.SetOptimize(theVal) + + ## Sets Fineness + # @param theFineness is: + # VeryCoarse, Coarse, Moderate, Fine, VeryFine or Custom + # + def SetFineness(self, theFineness): + if self.Parameters(): + self.params.SetFineness(theFineness) + + ## Sets GrowthRate + # + def SetGrowthRate(self, theRate): + if self.Parameters(): + self.params.SetGrowthRate(theRate) + + ## Defines hypothesis having several parameters + # + def Parameters(self, which=SOLE): + if self.algoType == NETGEN_1D2D: + if which == SIMPLE: + hypType = "NETGEN_SimpleParameters_2D" + else: + hypType = "NETGEN_Parameters_2D" + elif self.algoType == NETGEN_1D2D3D: + if which == SIMPLE: + hypType = "NETGEN_SimpleParameters_3D" + else: + hypType = "NETGEN_Parameters" + elif self.algoType == NETGEN_2D: + hypType = "NETGEN_Parameters_2D_ONLY" + else: + hypType = "NETGEN_Parameters_3D" + + if self.params and self.params.GetName() != hypType: + self.mesh.RemoveHypothesis( self.params, self.geom ) + self.params = None + if not self.params: + self.params = self.Hypothesis(hypType, [],"libNETGENEngine.so",UseExisting=0) + + return self.params + + + +## Defines a tetrahedron 1D-2D-3D algorithm +# It is created by calling Mesh.Triangle( NETGEN_1D2D3D, geom=0 ) +# +class NETGEN_1D2D3D_Algorithm(NETGEN_Algorithm): + + meshMethod = "Tetrahedron" + algoType = NETGEN_1D2D3D + + ## Private constructor. + def __init__(self, mesh, geom=0): + NETGEN_Algorithm.__init__(self, mesh, geom) + + ## Sets SecondOrder flag + # + def SetSecondOrder(self, theVal): + if self.Parameters(): + self.params.SetSecondOrder(theVal) + + ## Sets NbSegPerEdge + # + def SetNbSegPerEdge(self, theVal): + if self.Parameters(): + self.params.SetNbSegPerEdge(theVal) + + ## Sets NbSegPerRadius + # + def SetNbSegPerRadius(self, theVal): + if self.Parameters(): + self.params.SetNbSegPerRadius(theVal) + + ## Sets QuadAllowed flag. + def SetQuadAllowed(self, toAllow=True): + if self.Parameters(): + self.params.SetQuadAllowed(toAllow) + + + ## Sets number of segments overriding the value set by SetLocalLength() + # + def SetNumberOfSegments(self, theVal): + self.Parameters(SIMPLE).SetNumberOfSegments(theVal) + + ## Sets number of segments overriding the value set by SetNumberOfSegments() + # + def SetLocalLength(self, theVal): + self.Parameters(SIMPLE).SetLocalLength(theVal) + + ## Defines "MaxElementArea" parameter of NETGEN_SimpleParameters_3D hypothesis. + # Overrides value set by LengthFromEdges() + def MaxElementArea(self, area): + self.Parameters(SIMPLE).SetMaxElementArea(area) + + ## Defines "LengthFromEdges" parameter of NETGEN_SimpleParameters_3D hypothesis + # Overrides value set by MaxElementArea() + def LengthFromEdges(self): + self.Parameters(SIMPLE).LengthFromEdges() + + ## Defines "LengthFromFaces" parameter of NETGEN_SimpleParameters_3D hypothesis + # Overrides value set by MaxElementVolume() + def LengthFromFaces(self): + self.Parameters(SIMPLE).LengthFromFaces() + + ## Defines "MaxElementVolume" parameter of NETGEN_SimpleParameters_3D hypothesis + # Overrides value set by LengthFromFaces() + def MaxElementVolume(self, vol): + self.Parameters(SIMPLE).SetMaxElementVolume(vol) + + +## Triangle NETGEN 1D-2D algorithm. +# It is created by calling Mesh.Triangle( NETGEN_1D2D, geom=0 ) +# +class NETGEN_1D2D_Algorithm(NETGEN_1D2D3D_Algorithm): + + meshMethod = "Triangle" + algoType = NETGEN_1D2D + + ## Private constructor. + def __init__(self, mesh, geom=0): + NETGEN_1D2D3D_Algorithm.__init__(self, mesh, geom) + + + +## Triangle NETGEN 2D algorithm +# It is created by calling Mesh.Triangle( NETGEN_2D, geom=0 ) +# +class NETGEN_2D_Only_Algorithm(NETGEN_Algorithm): + + meshMethod = "Triangle" + algoType = NETGEN_2D + + ## Private constructor. + def __init__(self, mesh, geom=0): + NETGEN_Algorithm.__init__(self, mesh, geom) + + ## Sets QuadAllowed flag. + def SetQuadAllowed(self, toAllow=True): + if self.Parameters(): + self.params.SetQuadAllowed(toAllow) + + ## Defines "MaxElementArea" hypothesis basing on the definition of the maximum area of each triangle + # @param area for the maximum area of each triangle + # @param UseExisting if ==true - searches for an existing hypothesis created with the + # same parameters, else (default) - creates a new one + # + def MaxElementArea(self, area, UseExisting=0): + compFun = lambda hyp, args: IsEqual(hyp.GetMaxElementArea(), args[0]) + hyp = self.Hypothesis("MaxElementArea", [area], UseExisting=UseExisting, + CompareMethod=compFun) + hyp.SetMaxElementArea(area) + return hyp + + ## Defines "LengthFromEdges" hypothesis to build triangles + # based on the length of the edges taken from the wire + # + def LengthFromEdges(self): + hyp = self.Hypothesis("LengthFromEdges", UseExisting=1, CompareMethod=self.CompareEqualHyp) + return hyp + + ## Sets QuadAllowed flag. + def SetQuadAllowed(self, toAllow=True): + if not self.params: + # use simple hyps + hasSimpleHyps = False + simpleHyps = ["QuadranglePreference","LengthFromEdges","MaxElementArea"] + for hyp in self.mesh.GetHypothesisList( self.geom ): + if hyp.GetName() in simpleHyps: + hasSimpleHyps = True + if hyp.GetName() == "QuadranglePreference": + if not toAllow: # remove QuadranglePreference + self.mesh.RemoveHypothesis( self.geom, hyp ) + else: + return hyp + return None + pass + pass + if hasSimpleHyps: + if toAllow: # add QuadranglePreference + return self.Hypothesis("QuadranglePreference", UseExisting=1, CompareMethod=self.CompareEqualHyp) + return None + pass + self.Parameters().SetQuadAllowed( toAllow ) + return self.params + +## Defines a tetrahedron 3D algorithm +# It is created by calling Mesh.Tetrahedron() +# +class NETGEN_3D_Algorithm(NETGEN_Algorithm): + + meshMethod = "Tetrahedron" + algoType = NETGEN + isDefault = True + + ## Private constructor. + def __init__(self, mesh, geom=0): + NETGEN_Algorithm.__init__(self, mesh, geom) + + ## Defines "MaxElementVolume" hypothesis to give the maximun volume of each tetrahedron + # @param vol for the maximum volume of each tetrahedron + # @param UseExisting if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + def MaxElementVolume(self, vol, UseExisting=0): + compFun = lambda hyp, args: IsEqual(hyp.GetMaxElementVolume(), args[0]) + hyp = self.Hypothesis("MaxElementVolume", [vol], UseExisting=UseExisting, + CompareMethod=compFun) + hyp.SetMaxElementVolume(vol) + return hyp + + +# Class just to create NETGEN_1D2D by calling Mesh.Triangle(NETGEN) +class NETGEN_1D2D_Algorithm_2(NETGEN_1D2D_Algorithm): + + algoType = NETGEN + + ## Private constructor. + def __init__(self, mesh, geom=0): + self.algoType = NETGEN_1D2D + NETGEN_1D2D_Algorithm.__init__(self,mesh, geom) + + +# Class just to create NETGEN_1D2D3D by calling Mesh.Netgen() +class NETGEN_1D2D3D_Algorithm_2(NETGEN_1D2D3D_Algorithm): + + meshMethod = "Netgen" + + ## Private constructor. + def __init__(self, mesh, geom=0): + NETGEN_1D2D3D_Algorithm.__init__(self,mesh, geom) diff --git a/src/NETGENPlugin/NETGENPlugin_Defs.hxx b/src/NETGENPlugin/NETGENPlugin_Defs.hxx index 2eb36ac..f1297ee 100755 --- a/src/NETGENPlugin/NETGENPlugin_Defs.hxx +++ b/src/NETGENPlugin/NETGENPlugin_Defs.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + //============================================================================= // File : NETGENPlugin_Defs.hxx // Author : Alexander A. BORODIN @@ -27,7 +28,7 @@ #define _NETGENPlugin_DEFS_HXX_ #ifdef WIN32 - #ifdef NETGENPLUGIN_EXPORTS + #if defined NETGENPLUGIN_EXPORTS || defined NETGENEngine_EXPORTS #define NETGENPLUGIN_EXPORT __declspec( dllexport ) #else #define NETGENPLUGIN_EXPORT __declspec( dllimport ) diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis.cxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis.cxx index 75100b5..853e76c 100644 --- a/src/NETGENPlugin/NETGENPlugin_Hypothesis.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis.cxx @@ -1,31 +1,36 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_Hypothesis.cxx // Author : Michael Sazonov (OCN) // Date : 28/03/2006 // Project : SALOME // -#include +#include "NETGENPlugin_Hypothesis.hxx" + +#include "NETGENPlugin_Mesher.hxx" +#include "SMESH_Mesh.hxx" + #include using namespace std; @@ -39,15 +44,19 @@ NETGENPlugin_Hypothesis::NETGENPlugin_Hypothesis (int hypId, int studyId, SMESH_Gen * gen) : SMESH_Hypothesis(hypId, studyId, gen), _maxSize (GetDefaultMaxSize()), + _minSize (0), _growthRate (GetDefaultGrowthRate()), _nbSegPerEdge (GetDefaultNbSegPerEdge()), _nbSegPerRadius(GetDefaultNbSegPerRadius()), _fineness (GetDefaultFineness()), _secondOrder (GetDefaultSecondOrder()), - _optimize (GetDefaultOptimize()) + _optimize (GetDefaultOptimize()), + _localSize (GetDefaultLocalSize()), + _quadAllowed (GetDefaultQuadAllowed()) { _name = "NETGEN_Parameters"; _param_algo_dim = 3; + _localSize.clear(); } //============================================================================= @@ -64,6 +73,20 @@ void NETGENPlugin_Hypothesis::SetMaxSize(double theSize) } } +//============================================================================= +/*! + * + */ +//============================================================================= +void NETGENPlugin_Hypothesis::SetMinSize(double theSize) +{ + if (theSize != _minSize) + { + _minSize = theSize; + NotifySubMeshesHypothesisModification(); + } +} + //============================================================================= /*! * @@ -183,6 +206,69 @@ void NETGENPlugin_Hypothesis::SetNbSegPerRadius(double theVal) } } +//============================================================================= +/*! + * + */ +//============================================================================= +void NETGENPlugin_Hypothesis::SetLocalSizeOnEntry(const std::string& entry, double localSize) +{ + if(_localSize[entry] != localSize) + { + _localSize[entry] = localSize; + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +/*! + * + */ +//============================================================================= +double NETGENPlugin_Hypothesis::GetLocalSizeOnEntry(const std::string& entry) +{ + TLocalSize::iterator it = _localSize.find( entry ); + if ( it != _localSize.end() ) + return it->second; + else + return -1.0; +} + +//============================================================================= +/*! + * + */ +//============================================================================= +void NETGENPlugin_Hypothesis::UnsetLocalSizeOnEntry(const std::string& entry) +{ + _localSize.erase(entry); + NotifySubMeshesHypothesisModification(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= +void NETGENPlugin_Hypothesis::SetQuadAllowed(bool theVal) +{ + if (theVal != _quadAllowed) + { + _quadAllowed = theVal; + NotifySubMeshesHypothesisModification(); + } +} + +//============================================================================= +/*! + * + */ +//============================================================================= +bool NETGENPlugin_Hypothesis::GetDefaultQuadAllowed() +{ + return false; +} + //============================================================================= /*! * @@ -197,6 +283,18 @@ ostream & NETGENPlugin_Hypothesis::SaveTo(ostream & save) save << " " << (int)_secondOrder << " " << (int)_optimize; + TLocalSize::iterator it_sm = _localSize.begin(); + if (it_sm != _localSize.end()) { + save << " " << "__LOCALSIZE_BEGIN__"; + for ( ; it_sm != _localSize.end(); ++it_sm ) { + save << " " << it_sm->first + << " " << it_sm->second << "%#"; // "%#" is a mark of value end + } + save << " " << "__LOCALSIZE_END__"; + } + save << " " << _minSize; + save << " " << _quadAllowed; + return save; } @@ -255,6 +353,38 @@ istream & NETGENPlugin_Hypothesis::LoadFrom(istream & load) _optimize = (bool) is; else load.clear(ios::badbit | load.rdstate()); + + std::string option_or_sm; + bool hasLocalSize = false; + + isOK = (load >> option_or_sm); + if (isOK) + if (option_or_sm == "__LOCALSIZE_BEGIN__") + hasLocalSize = true; + + std::string smEntry, smValue; + while (isOK && hasLocalSize) { + isOK = (load >> smEntry); + if (isOK) { + if (smEntry == "__LOCALSIZE_END__") + break; + isOK = (load >> smValue); + } + if (isOK) { + std::istringstream tmp(smValue); + double val; + tmp >> val; + _localSize[ smEntry ] = val; + } + } + + if ( !hasLocalSize && !option_or_sm.empty() ) + _minSize = atof( option_or_sm.c_str() ); + + isOK = ( load >> _quadAllowed ); + if ( !isOK ) + _quadAllowed = GetDefaultQuadAllowed(); + return load; } @@ -301,10 +431,16 @@ bool NETGENPlugin_Hypothesis::SetParametersByMesh(const SMESH_Mesh* theMesh, //================================================================================ bool NETGENPlugin_Hypothesis::SetParametersByDefaults(const TDefaults& dflts, - const SMESH_Mesh* /*theMesh*/) + const SMESH_Mesh* theMesh) { _nbSegPerEdge = dflts._nbSegments; _maxSize = dflts._elemLength; + + if ( dflts._shape && !dflts._shape->IsNull() ) + _minSize = NETGENPlugin_Mesher::GetDefaultMinSize( *dflts._shape, _maxSize ); + else if ( theMesh && theMesh->HasShapeToMesh() ) + _minSize = NETGENPlugin_Mesher::GetDefaultMinSize( theMesh->GetShapeToMesh(), _maxSize ); + return _nbSegPerEdge && _maxSize > 0; } diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis.hxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis.hxx index 3654f86..c96c8c8 100644 --- a/src/NETGENPlugin/NETGENPlugin_Hypothesis.hxx +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_Hypothesis.hxx // Author : Michael Sazonov (OCN) @@ -33,6 +34,8 @@ #include "SMESH_Hypothesis.hxx" #include "Utils_SALOME_Exception.hxx" +#include + // Parameters for work of NETGEN // @@ -47,6 +50,9 @@ public: void SetMaxSize(double theSize); double GetMaxSize() const { return _maxSize; } + void SetMinSize(double theSize); + double GetMinSize() const { return _minSize; } + void SetSecondOrder(bool theVal); bool GetSecondOrder() const { return _secondOrder; } @@ -77,6 +83,16 @@ public: void SetNbSegPerRadius(double theVal); double GetNbSegPerRadius() const { return _nbSegPerRadius; } + typedef std::map TLocalSize; + static TLocalSize GetDefaultLocalSize() { return TLocalSize(); } + void SetLocalSizeOnEntry(const std::string& entry, double localSize); + double GetLocalSizeOnEntry(const std::string& entry); + const TLocalSize& GetLocalSizesAndEntries() const { return _localSize; } + void UnsetLocalSizeOnEntry(const std::string& entry); + + void SetQuadAllowed(bool theVal); + bool GetQuadAllowed() const { return _quadAllowed; } + // the default values (taken from NETGEN 4.5 sources) static double GetDefaultMaxSize(); @@ -86,6 +102,7 @@ public: static double GetDefaultNbSegPerRadius(); static bool GetDefaultSecondOrder(); static bool GetDefaultOptimize(); + static bool GetDefaultQuadAllowed(); // Persistence virtual ostream & SaveTo(ostream & save); @@ -108,13 +125,15 @@ public: virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0); private: - double _maxSize; + double _maxSize, _minSize; double _growthRate; double _nbSegPerEdge; double _nbSegPerRadius; Fineness _fineness; bool _secondOrder; bool _optimize; + TLocalSize _localSize; + bool _quadAllowed; }; #endif diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D.cxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D.cxx index eac7350..0a488ad 100644 --- a/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D.cxx @@ -1,33 +1,33 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_Hypothesis_2D.cxx // Author : Michael Sazonov (OCN) // Date : 28/03/2006 // Project : SALOME -// $Header$ //============================================================================= // -#include +#include "NETGENPlugin_Hypothesis_2D.hxx" #include using namespace std; diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D.hxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D.hxx index 07f1195..babfc87 100644 --- a/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D.hxx +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D.hxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_Hypothesis_2D.hxx // Author : Michael Sazonov (OCN) // Date : 27/03/2006 // Project : SALOME -// $Header$ //============================================================================= // #ifndef _NETGENPlugin_Hypothesis_2D_HXX_ diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D_ONLY_i.cxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D_ONLY_i.cxx new file mode 100644 index 0000000..b4152b4 --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D_ONLY_i.cxx @@ -0,0 +1,72 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// NETGENPlugin : C++ implementation +// File : NETGENPlugin_Hypothesis_2D_ONLY_i.cxx +// Project : SALOME +//============================================================================= +// +#include "NETGENPlugin_Hypothesis_2D_ONLY_i.hxx" +#include "SMESH_Gen.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +//============================================================================= +/*! + * Constructor + */ +//============================================================================= +NETGENPlugin_Hypothesis_2D_ONLY_i:: +NETGENPlugin_Hypothesis_2D_ONLY_i (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + NETGENPlugin_Hypothesis_2D_i( thePOA, theStudyId, theGenImpl ) +{ + MESSAGE( "NETGENPlugin_Hypothesis_2D_ONLY_i::NETGENPlugin_Hypothesis_2D_ONLY_i" ); + myBaseImpl = new ::NETGENPlugin_Hypothesis_2D (theGenImpl->GetANewId(), + theStudyId, + theGenImpl); +} + +//============================================================================= +/*! + * Destructor + */ +//============================================================================= + +NETGENPlugin_Hypothesis_2D_ONLY_i::~NETGENPlugin_Hypothesis_2D_ONLY_i() +{ + MESSAGE( "NETGENPlugin_Hypothesis_2D_ONLY_i::~NETGENPlugin_Hypothesis_2D_ONLY_i" ); +} +//================================================================================ +/*! + * \brief Redefine hypothesis type + */ +//================================================================================ + +char* NETGENPlugin_Hypothesis_2D_ONLY_i::GetName() +{ + return CORBA::string_dup("NETGEN_Parameters_2D_ONLY"); +} diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D_ONLY_i.hxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D_ONLY_i.hxx new file mode 100644 index 0000000..616dbc9 --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D_ONLY_i.hxx @@ -0,0 +1,57 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// NETGENPlugin : C++ implementation +// File : NETGENPlugin_Hypothesis_2D_ONLY_i.hxx +// Project : SALOME +//============================================================================= +// +#ifndef _NETGENPlugin_Hypothesis_2D_ONLY_i_HXX_ +#define _NETGENPlugin_Hypothesis_2D_ONLY_i_HXX_ + +#include "NETGENPlugin_Defs.hxx" + +#include +#include CORBA_SERVER_HEADER(NETGENPlugin_Algorithm) + +#include "NETGENPlugin_Hypothesis_2D_i.hxx" + +class SMESH_Gen; + +// NETGENPlugin parameters hypothesis ("2D only" case) + +class NETGENPLUGIN_EXPORT NETGENPlugin_Hypothesis_2D_ONLY_i: + public virtual POA_NETGENPlugin::NETGENPlugin_Hypothesis_2D_ONLY, + public NETGENPlugin_Hypothesis_2D_i +{ + public: + // Constructor + NETGENPlugin_Hypothesis_2D_ONLY_i (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl); + // Destructor + virtual ~NETGENPlugin_Hypothesis_2D_ONLY_i(); + + char* GetName(); +}; + +#endif diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D_i.cxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D_i.cxx index cdb595c..86e5888 100644 --- a/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D_i.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D_i.cxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_Hypothesis_2D_i.cxx // Author : Michael Sazonov (OCN) // Date : 03/04/2006 // Project : SALOME -// $Header$ //============================================================================= // #include "NETGENPlugin_Hypothesis_2D_i.hxx" @@ -78,13 +78,16 @@ NETGENPlugin_Hypothesis_2D_i::~NETGENPlugin_Hypothesis_2D_i() * Set QuadAllowed flag */ //============================================================================= -void NETGENPlugin_Hypothesis_2D_i::SetQuadAllowed (CORBA::Boolean theValue) -{ - MESSAGE("NETGENPlugin_Hypothesis_2D_i::SetQuadAllowed"); - ASSERT(myBaseImpl); - this->GetImpl()->SetQuadAllowed(theValue); - SMESH::TPythonDump() << _this() << ".SetQuadAllowed( " << theValue << " )"; -} +// void NETGENPlugin_Hypothesis_2D_i::SetQuadAllowed (CORBA::Boolean theValue) +// { +// if ( NETGENPlugin_Hypothesis_i::isToSetParameter( GetQuadAllowed(), +// theValue, +// METH_SetQuadAllowed )) +// { +// this->GetImpl()->SetQuadAllowed(theValue); +// SMESH::TPythonDump() << _this() << ".SetQuadAllowed( " << theValue << " )"; +// } +// } //============================================================================= /*! @@ -93,12 +96,10 @@ void NETGENPlugin_Hypothesis_2D_i::SetQuadAllowed (CORBA::Boolean theValue) * Get QuadAllowed flag */ //============================================================================= -CORBA::Boolean NETGENPlugin_Hypothesis_2D_i::GetQuadAllowed() -{ - MESSAGE("NETGENPlugin_Hypothesis_2D_i::GetQuadAllowed"); - ASSERT(myBaseImpl); - return this->GetImpl()->GetQuadAllowed(); -} +// CORBA::Boolean NETGENPlugin_Hypothesis_2D_i::GetQuadAllowed() +// { +// return this->GetImpl()->GetQuadAllowed(); +// } //============================================================================= /*! @@ -109,7 +110,6 @@ CORBA::Boolean NETGENPlugin_Hypothesis_2D_i::GetQuadAllowed() //============================================================================= ::NETGENPlugin_Hypothesis_2D* NETGENPlugin_Hypothesis_2D_i::GetImpl() { - MESSAGE("NETGENPlugin_Hypothesis_2D_i::GetImpl"); return (::NETGENPlugin_Hypothesis_2D*)myBaseImpl; } diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D_i.hxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D_i.hxx index 1a94bc6..e6d0c55 100644 --- a/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D_i.hxx +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis_2D_i.hxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_Hypothesis_2D_i.hxx // Author : Michael Sazonov (OCN) // Date : 03/04/2006 // Project : SALOME -// $Header$ //============================================================================= // #ifndef _NETGENPlugin_Hypothesis_2D_i_HXX_ @@ -54,14 +54,20 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Hypothesis_2D_i: // Destructor virtual ~NETGENPlugin_Hypothesis_2D_i(); - void SetQuadAllowed(CORBA::Boolean theVal); - CORBA::Boolean GetQuadAllowed(); - // Get implementation ::NETGENPlugin_Hypothesis_2D* GetImpl(); // Verify whether hypothesis supports given entity type CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + + protected: + + // to remember whether a parameter is already set (issue 0021364) + // enum SettingMethod + // { + // METH_SetQuadAllowed = NETGENPlugin_Hypothesis_i::METH_LAST * 2, + // METH_LAST = METH_SetQuadAllowed + // }; }; #endif diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis_3D_i.cxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis_3D_i.cxx new file mode 100644 index 0000000..051d337 --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis_3D_i.cxx @@ -0,0 +1,71 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// NETGENPlugin : C++ implementation +// File : NETGENPlugin_Hypothesis_3D_i.cxx +// Project : SALOME +//============================================================================= +// +#include "NETGENPlugin_Hypothesis_3D_i.hxx" +#include "SMESH_Gen.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +using namespace std; + +//============================================================================= +/*! + * Constructor + */ +//============================================================================= +NETGENPlugin_Hypothesis_3D_i:: +NETGENPlugin_Hypothesis_3D_i (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + NETGENPlugin_Hypothesis_i( thePOA, theStudyId, theGenImpl ) +{ + MESSAGE( "NETGENPlugin_Hypothesis_3D_i::NETGENPlugin_Hypothesis_3D_i" ); +} + +//============================================================================= +/*! + * Destructor + */ +//============================================================================= +NETGENPlugin_Hypothesis_3D_i::~NETGENPlugin_Hypothesis_3D_i() +{ + MESSAGE( "NETGENPlugin_Hypothesis_3D_i::~NETGENPlugin_Hypothesis_3D_i" ); +} + +//================================================================================ +/*! + * \brief Redefine hypothesis type + */ +//================================================================================ + +char* NETGENPlugin_Hypothesis_3D_i::GetName() +{ + return CORBA::string_dup("NETGEN_Parameters_3D"); +} diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis_3D_i.hxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis_3D_i.hxx new file mode 100644 index 0000000..0cb7b9f --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis_3D_i.hxx @@ -0,0 +1,59 @@ +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// NETGENPlugin : C++ implementation +// File : NETGENPlugin_Hypothesis_2D_i.hxx +// Project : SALOME +//============================================================================= +// +#ifndef _NETGENPlugin_Hypothesis_3D_i_HXX_ +#define _NETGENPlugin_Hypothesis_3D_i_HXX_ + +#include "NETGENPlugin_Defs.hxx" + +#include +#include CORBA_SERVER_HEADER(NETGENPlugin_Algorithm) + +#include "NETGENPlugin_Hypothesis_i.hxx" + +class SMESH_Gen; + +// NETGENPlugin parameters hypothesis (3D "only" case) + +class NETGENPLUGIN_EXPORT NETGENPlugin_Hypothesis_3D_i: + public virtual POA_NETGENPlugin::NETGENPlugin_Hypothesis_3D, + public NETGENPlugin_Hypothesis_i +{ + public: + // Constructor + NETGENPlugin_Hypothesis_3D_i (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl); + + // Get type name of hypothesis + char* GetName(); + + // Destructor + virtual ~NETGENPlugin_Hypothesis_3D_i(); +}; + +#endif diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.cxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.cxx index f13e9db..17bdd35 100644 --- a/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.cxx @@ -1,41 +1,56 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_Hypothesis_i.cxx // Author : Michael Sazonov (OCN) // Date : 03/04/2006 // Project : SALOME -// $Header$ //============================================================================= // #include "NETGENPlugin_Hypothesis_i.hxx" #include "SMESH_Gen.hxx" #include "SMESH_PythonDump.hxx" +#include "GEOM_Object.hxx" #include "Utils_CorbaException.hxx" #include "utilities.h" using namespace std; +//============================================================================= +/*! + * Specialization of isToSetParameter for double + */ +//============================================================================= + +template<> +bool NETGENPlugin_Hypothesis_i::isToSetParameter(double curValue, + double newValue, + /*SettingMethod*/int meth) +{ + return isToSetParameter(true, (fabs(curValue - newValue) < 1e-20), meth); +} + //============================================================================= /*! * NETGENPlugin_Hypothesis_i::NETGENPlugin_Hypothesis_i @@ -48,7 +63,8 @@ NETGENPlugin_Hypothesis_i (PortableServer::POA_ptr thePOA, int theStudyId, ::SMESH_Gen* theGenImpl) : SALOME::GenericObj_i( thePOA ), - SMESH_Hypothesis_i( thePOA ) + SMESH_Hypothesis_i( thePOA ), + mySetMethodFlags(0) { MESSAGE( "NETGENPlugin_Hypothesis_i::NETGENPlugin_Hypothesis_i" ); myBaseImpl = new ::NETGENPlugin_Hypothesis (theGenImpl->GetANewId(), @@ -77,10 +93,11 @@ NETGENPlugin_Hypothesis_i::~NETGENPlugin_Hypothesis_i() //============================================================================= void NETGENPlugin_Hypothesis_i::SetMaxSize (CORBA::Double theValue) { - MESSAGE("NETGENPlugin_Hypothesis_i::SetMaxSize"); - ASSERT(myBaseImpl); - this->GetImpl()->SetMaxSize(theValue); - SMESH::TPythonDump() << _this() << ".SetMaxSize( " << theValue << " )"; + if ( isToSetParameter( GetMaxSize(), theValue, METH_SetMaxSize )) + { + this->GetImpl()->SetMaxSize(theValue); + SMESH::TPythonDump() << _this() << ".SetMaxSize( " << SMESH::TVar(theValue) << " )"; + } } //============================================================================= @@ -92,11 +109,37 @@ void NETGENPlugin_Hypothesis_i::SetMaxSize (CORBA::Double theValue) //============================================================================= CORBA::Double NETGENPlugin_Hypothesis_i::GetMaxSize() { - MESSAGE("NETGENPlugin_Hypothesis_i::GetMaxSize"); - ASSERT(myBaseImpl); return this->GetImpl()->GetMaxSize(); } +//============================================================================= +/*! + * NETGENPlugin_Hypothesis_i::SetMinSize + * + * Set MinSize + */ +//============================================================================= +void NETGENPlugin_Hypothesis_i::SetMinSize (CORBA::Double theValue) +{ + if ( isToSetParameter( GetMinSize(), theValue, METH_SetMinSize )) + { + this->GetImpl()->SetMinSize(theValue); + SMESH::TPythonDump() << _this() << ".SetMinSize( " << SMESH::TVar(theValue) << " )"; + } +} + +//============================================================================= +/*! + * NETGENPlugin_Hypothesis_i::GetMinSize + * + * Get MinSize + */ +//============================================================================= +CORBA::Double NETGENPlugin_Hypothesis_i::GetMinSize() +{ + return this->GetImpl()->GetMinSize(); +} + //============================================================================= /*! * NETGENPlugin_Hypothesis_i::SetSecondOrder @@ -106,10 +149,11 @@ CORBA::Double NETGENPlugin_Hypothesis_i::GetMaxSize() //============================================================================= void NETGENPlugin_Hypothesis_i::SetSecondOrder (CORBA::Boolean theValue) { - MESSAGE("NETGENPlugin_Hypothesis_i::SetSecondOrder"); - ASSERT(myBaseImpl); - this->GetImpl()->SetSecondOrder(theValue); - SMESH::TPythonDump() << _this() << ".SetSecondOrder( " << theValue << " )"; + if ( isToSetParameter( GetSecondOrder(), theValue, METH_SetSecondOrder )) + { + this->GetImpl()->SetSecondOrder(theValue); + SMESH::TPythonDump() << _this() << ".SetSecondOrder( " << theValue << " )"; + } } //============================================================================= @@ -121,8 +165,6 @@ void NETGENPlugin_Hypothesis_i::SetSecondOrder (CORBA::Boolean theValue) //============================================================================= CORBA::Boolean NETGENPlugin_Hypothesis_i::GetSecondOrder() { - MESSAGE("NETGENPlugin_Hypothesis_i::GetSecondOrder"); - ASSERT(myBaseImpl); return this->GetImpl()->GetSecondOrder(); } @@ -135,10 +177,11 @@ CORBA::Boolean NETGENPlugin_Hypothesis_i::GetSecondOrder() //============================================================================= void NETGENPlugin_Hypothesis_i::SetOptimize (CORBA::Boolean theValue) { - MESSAGE("NETGENPlugin_Hypothesis_i::SetOptimize"); - ASSERT(myBaseImpl); - this->GetImpl()->SetOptimize(theValue); - SMESH::TPythonDump() << _this() << ".SetOptimize( " << theValue << " )"; + if ( isToSetParameter( GetOptimize(), theValue, METH_SetOptimize )) + { + this->GetImpl()->SetOptimize(theValue); + SMESH::TPythonDump() << _this() << ".SetOptimize( " << theValue << " )"; + } } //============================================================================= @@ -150,8 +193,6 @@ void NETGENPlugin_Hypothesis_i::SetOptimize (CORBA::Boolean theValue) //============================================================================= CORBA::Boolean NETGENPlugin_Hypothesis_i::GetOptimize() { - MESSAGE("NETGENPlugin_Hypothesis_i::GetOptimize"); - ASSERT(myBaseImpl); return this->GetImpl()->GetOptimize(); } @@ -164,10 +205,11 @@ CORBA::Boolean NETGENPlugin_Hypothesis_i::GetOptimize() //============================================================================= void NETGENPlugin_Hypothesis_i::SetFineness (CORBA::Long theValue) { - MESSAGE("NETGENPlugin_Hypothesis_i::SetFineness"); - ASSERT(myBaseImpl); - this->GetImpl()->SetFineness((::NETGENPlugin_Hypothesis::Fineness)theValue); - SMESH::TPythonDump() << _this() << ".SetFineness( " << theValue << " )"; + if ( isToSetParameter( GetFineness(), theValue, METH_SetFineness )) + { + this->GetImpl()->SetFineness((::NETGENPlugin_Hypothesis::Fineness)theValue); + SMESH::TPythonDump() << _this() << ".SetFineness( " << theValue << " )"; + } } //============================================================================= @@ -179,8 +221,6 @@ void NETGENPlugin_Hypothesis_i::SetFineness (CORBA::Long theValue) //============================================================================= CORBA::Long NETGENPlugin_Hypothesis_i::GetFineness() { - MESSAGE("NETGENPlugin_Hypothesis_i::GetFineness"); - ASSERT(myBaseImpl); return this->GetImpl()->GetFineness(); } @@ -193,10 +233,11 @@ CORBA::Long NETGENPlugin_Hypothesis_i::GetFineness() //============================================================================= void NETGENPlugin_Hypothesis_i::SetGrowthRate (CORBA::Double theValue) { - MESSAGE("NETGENPlugin_Hypothesis_i::SetGrowthRate"); - ASSERT(myBaseImpl); - this->GetImpl()->SetGrowthRate(theValue); - SMESH::TPythonDump() << _this() << ".SetGrowthRate( " << theValue << " )"; + if ( isToSetParameter( GetGrowthRate(), theValue, METH_SetGrowthRate )) + { + this->GetImpl()->SetGrowthRate(theValue); + SMESH::TPythonDump() << _this() << ".SetGrowthRate( " << SMESH::TVar(theValue) << " )"; + } } //============================================================================= @@ -208,8 +249,6 @@ void NETGENPlugin_Hypothesis_i::SetGrowthRate (CORBA::Double theValue) //============================================================================= CORBA::Double NETGENPlugin_Hypothesis_i::GetGrowthRate() { - MESSAGE("NETGENPlugin_Hypothesis_i::GetGrowthRate"); - ASSERT(myBaseImpl); return this->GetImpl()->GetGrowthRate(); } @@ -222,10 +261,11 @@ CORBA::Double NETGENPlugin_Hypothesis_i::GetGrowthRate() //============================================================================= void NETGENPlugin_Hypothesis_i::SetNbSegPerEdge (CORBA::Double theValue) { - MESSAGE("NETGENPlugin_Hypothesis_i::SetNbSegPerEdge"); - ASSERT(myBaseImpl); - this->GetImpl()->SetNbSegPerEdge(theValue); - SMESH::TPythonDump() << _this() << ".SetNbSegPerEdge( " << theValue << " )"; + if ( isToSetParameter( GetNbSegPerEdge(), theValue, METH_SetNbSegPerEdge )) + { + this->GetImpl()->SetNbSegPerEdge(theValue); + SMESH::TPythonDump() << _this() << ".SetNbSegPerEdge( " << SMESH::TVar(theValue) << " )"; + } } //============================================================================= @@ -237,8 +277,6 @@ void NETGENPlugin_Hypothesis_i::SetNbSegPerEdge (CORBA::Double theValue) //============================================================================= CORBA::Double NETGENPlugin_Hypothesis_i::GetNbSegPerEdge() { - MESSAGE("NETGENPlugin_Hypothesis_i::GetNbSegPerEdge"); - ASSERT(myBaseImpl); return this->GetImpl()->GetNbSegPerEdge(); } @@ -251,10 +289,11 @@ CORBA::Double NETGENPlugin_Hypothesis_i::GetNbSegPerEdge() //============================================================================= void NETGENPlugin_Hypothesis_i::SetNbSegPerRadius (CORBA::Double theValue) { - MESSAGE("NETGENPlugin_Hypothesis_i::SetNbSegPerRadius"); - ASSERT(myBaseImpl); - this->GetImpl()->SetNbSegPerRadius(theValue); - SMESH::TPythonDump() << _this() << ".SetNbSegPerRadius( " << theValue << " )"; + if ( isToSetParameter( GetNbSegPerRadius(), theValue, METH_SetNbSegPerRadius )) + { + this->GetImpl()->SetNbSegPerRadius(theValue); + SMESH::TPythonDump() << _this() << ".SetNbSegPerRadius( " << SMESH::TVar(theValue) << " )"; + } } //============================================================================= @@ -266,11 +305,84 @@ void NETGENPlugin_Hypothesis_i::SetNbSegPerRadius (CORBA::Double theValue) //============================================================================= CORBA::Double NETGENPlugin_Hypothesis_i::GetNbSegPerRadius() { - MESSAGE("NETGENPlugin_Hypothesis_i::GetNbSegPerRadius"); - ASSERT(myBaseImpl); return this->GetImpl()->GetNbSegPerRadius(); } +//============================================================================= + +void NETGENPlugin_Hypothesis_i::SetLocalSizeOnShape(GEOM::GEOM_Object_ptr GeomObj, + CORBA::Double localSize) +{ + string entry; + entry = GeomObj->GetStudyEntry(); + SetLocalSizeOnEntry(entry.c_str(), localSize); +} + +//============================================================================= + +void NETGENPlugin_Hypothesis_i::SetLocalSizeOnEntry(const char* entry, + CORBA::Double localSize) +{ + if ( isToSetParameter( GetLocalSizeOnEntry(entry), localSize, METH_SetLocalSizeOnEntry )) + { + this->GetImpl()->SetLocalSizeOnEntry(entry, localSize); + SMESH::TPythonDump() + << _this() << ".SetLocalSizeOnShape(" << entry << ", " << localSize << ")"; + } +} + +//============================================================================= + +CORBA::Double NETGENPlugin_Hypothesis_i::GetLocalSizeOnEntry(const char* entry) +{ + return this->GetImpl()->GetLocalSizeOnEntry(entry); +} + +//============================================================================= + +NETGENPlugin::string_array* NETGENPlugin_Hypothesis_i::GetLocalSizeEntries() +{ + NETGENPlugin::string_array_var result = new NETGENPlugin::string_array(); + const ::NETGENPlugin_Hypothesis::TLocalSize localSizes = + this->GetImpl()->GetLocalSizesAndEntries(); + result->length(localSizes.size()); + ::NETGENPlugin_Hypothesis::TLocalSize::const_iterator it = localSizes.begin(); + for (int i=0 ; it != localSizes.end() ; i++, it++) + { + string entry = (*it).first; + result[i] = CORBA::string_dup(entry.c_str()); + } + return result._retn(); +} + +//============================================================================= + +void NETGENPlugin_Hypothesis_i::UnsetLocalSizeOnEntry(const char* entry) +{ + this->GetImpl()->UnsetLocalSizeOnEntry(entry); + SMESH::TPythonDump() << _this() << ".UnsetLocalSizeOnEntry(" << entry << ")"; +} + +//============================================================================= + +void NETGENPlugin_Hypothesis_i::SetQuadAllowed (CORBA::Boolean theValue) +{ + if ( NETGENPlugin_Hypothesis_i::isToSetParameter( GetQuadAllowed(), + theValue, + METH_SetQuadAllowed )) + { + this->GetImpl()->SetQuadAllowed(theValue); + SMESH::TPythonDump() << _this() << ".SetQuadAllowed( " << theValue << " )"; + } +} + +//============================================================================= + +CORBA::Boolean NETGENPlugin_Hypothesis_i::GetQuadAllowed() +{ + return this->GetImpl()->GetQuadAllowed(); +} + //============================================================================= /*! * NETGENPlugin_Hypothesis_i::GetImpl @@ -280,7 +392,6 @@ CORBA::Double NETGENPlugin_Hypothesis_i::GetNbSegPerRadius() //============================================================================= ::NETGENPlugin_Hypothesis* NETGENPlugin_Hypothesis_i::GetImpl() { - MESSAGE("NETGENPlugin_Hypothesis_i::GetImpl"); return (::NETGENPlugin_Hypothesis*)myBaseImpl; } @@ -297,3 +408,42 @@ CORBA::Boolean NETGENPlugin_Hypothesis_i::IsDimSupported( SMESH::Dimension type { return type == SMESH::DIM_3D; } + +//================================================================================ +/*! + * \brief method intended to remove explicit treatment of Netgen hypotheses from SMESH_NoteBook + */ +//================================================================================ + +int NETGENPlugin_Hypothesis_i::getParamIndex(const TCollection_AsciiString& method, + int nbVars) const +{ + if ( method == "SetMaxSize" ) return 0; + if ( method == "SetGrowthRate" ) return 1; + if ( method == "SetNbSegPerEdge" ) return 2; + if ( method == "SetNbSegPerRadius" ) return 3; + if ( method == "SetMinSize" ) return nbVars-1; + + return SMESH_Hypothesis_i::getParamIndex( method, nbVars ); // return default value +} + +//================================================================================ +/*! + * \brief Method used to convert variable parameters stored in an old study + * into myMethod2VarParams. It should return a method name for an index of + * variable parameters. Index is countered from zero + */ +//================================================================================ + +std::string NETGENPlugin_Hypothesis_i::getMethodOfParameter(const int paramIndex, + int nbVars) const +{ + switch ( paramIndex ) { + case 0: return "SetMaxSize"; + case 1: return nbVars == 2 ? "SetMinSize" : "SetGrowthRate"; + case 2: return "SetNbSegPerEdge"; + case 3: return "SetNbSegPerRadius"; + case 4: return "SetMinSize"; + } + return ""; +} diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.hxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.hxx index 94ad126..95435b0 100644 --- a/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.hxx +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.hxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_Hypothesis_i.hxx // Author : Michael Sazonov (OCN) // Date : 03/04/2006 // Project : SALOME -// $Header$ //============================================================================= // #ifndef _NETGENPlugin_Hypothesis_i_HXX_ @@ -39,6 +39,7 @@ #include "NETGENPlugin_Hypothesis.hxx" class SMESH_Gen; +//class GEOM_Object; // NETGENPlugin parameters hypothesis @@ -57,6 +58,9 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Hypothesis_i: void SetMaxSize(CORBA::Double theSize); CORBA::Double GetMaxSize(); + void SetMinSize(CORBA::Double theSize); + CORBA::Double GetMinSize(); + void SetSecondOrder(CORBA::Boolean theVal); CORBA::Boolean GetSecondOrder(); @@ -75,11 +79,64 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Hypothesis_i: void SetNbSegPerRadius(CORBA::Double theVal); CORBA::Double GetNbSegPerRadius(); + void SetLocalSizeOnShape(GEOM::GEOM_Object_ptr GeomObj, CORBA::Double localSize); + void SetLocalSizeOnEntry(const char* entry, CORBA::Double localSize); + CORBA::Double GetLocalSizeOnEntry(const char* entry); + NETGENPlugin::string_array* GetLocalSizeEntries(); + void UnsetLocalSizeOnEntry(const char* entry); + + void SetQuadAllowed(CORBA::Boolean theVal); + CORBA::Boolean GetQuadAllowed(); + // Get implementation ::NETGENPlugin_Hypothesis* GetImpl(); // Verify whether hypothesis supports given entity type CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + + protected: + + // to remember whether a parameter is already set (issue 0021364) + enum SettingMethod + { + METH_SetMaxSize = 1, + METH_SetMinSize = 2, + METH_SetSecondOrder = 4, + METH_SetOptimize = 8, + METH_SetFineness = 16, + METH_SetGrowthRate = 32, + METH_SetNbSegPerEdge = 64, + METH_SetNbSegPerRadius = 128, + METH_SetLocalSizeOnEntry = 256, + METH_SetQuadAllowed = METH_SetLocalSizeOnEntry * 2, + METH_LAST = METH_SetQuadAllowed + }; + int mySetMethodFlags; + + // Return true if a parameter is not yet set, else return true if a parameter changes. + // PythonDumping depends on the result of this function. + // Checking only change of a parameter is not enough because then the default values are + // not dumped and if the defaults will change then the behaviour of scripts + // created without dump of the default parameters will also change what is not good. + template + bool isToSetParameter(T curValue, T newValue, /*SettingMethod*/int meth) + { + if ( mySetMethodFlags & meth ) // already set, check if a value is changing + return ( curValue != newValue ); + else + return ( mySetMethodFlags |= meth ); // == return true + } + + public: + // method intended to remove explicit treatment of Netgen hypotheses from + // SMESH_NoteBook to assure backward compatibility after implemeneting + // issue 0021308: Remove hard-coded dependency of the external mesh plugins + virtual int getParamIndex(const TCollection_AsciiString& method, int nbVars) const; + + // method used to convert variable parameters stored in an old study + // into myMethod2VarParams. It should return a method name for an index of + // variable parameters. Index is countered from zero + virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const; }; #endif diff --git a/src/NETGENPlugin/NETGENPlugin_Mesher.cxx b/src/NETGENPlugin/NETGENPlugin_Mesher.cxx index 0d86eca..9249d95 100644 --- a/src/NETGENPlugin/NETGENPlugin_Mesher.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Mesher.cxx @@ -1,74 +1,108 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_Mesher.cxx // Author : Michael Sazonov (OCN) // Date : 31/03/2006 // Project : SALOME -// $Header$ //============================================================================= -// + #include "NETGENPlugin_Mesher.hxx" #include "NETGENPlugin_Hypothesis_2D.hxx" #include "NETGENPlugin_SimpleHypothesis_3D.hxx" -#include +#include +#include +#include +#include +#include #include #include -#include +#include +#include +#include #include -#include -#include -#include -#include +#include +#include -#include +#include +#include #include +#include +#include +#include #include #include +#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include // Netgen include files -namespace nglib { -#include -} +#ifndef OCCGEOMETRY #define OCCGEOMETRY +#endif #include #include //#include namespace netgen { extern int OCCGenerateMesh (OCCGeometry&, Mesh*&, int, int, char*); + //extern void OCCSetLocalMeshSize(OCCGeometry & geom, Mesh & mesh); extern MeshingParameters mparam; + extern volatile multithreadt multithread; } +#include +#include + +using namespace nglib; using namespace std; +#ifdef _DEBUG_ +#define nodeVec_ACCESS(index) ((SMDS_MeshNode*) nodeVec.at((index))) +#else +#define nodeVec_ACCESS(index) ((SMDS_MeshNode*) nodeVec[index]) +#endif + +#ifdef NETGEN_NEW +#define NGPOINT_COORDS(p) p(0),p(1),p(2) +#else +#define NGPOINT_COORDS(p) p.X(),p.Y(),p.Z() +#endif + +// dump elements added to ng mesh +//#define DUMP_SEGMENTS +//#define DUMP_TRIANGLES +//#define DUMP_TRIANGLES_SCRIPT "/tmp/trias.py" //!< debug addIntVerticesInSolids() + +TopTools_IndexedMapOfShape ShapesWithLocalSize; +std::map VertexId2LocalSize; +std::map EdgeId2LocalSize; +std::map FaceId2LocalSize; + //============================================================================= /*! * @@ -82,9 +116,14 @@ NETGENPlugin_Mesher::NETGENPlugin_Mesher (SMESH_Mesh* mesh, _shape (aShape), _isVolume(isVolume), _optimize(true), + _fineness(NETGENPlugin_Hypothesis::GetDefaultFineness()), _simpleHyp(NULL) { defaultParameters(); + ShapesWithLocalSize.Clear(); + VertexId2LocalSize.clear(); + EdgeId2LocalSize.clear(); + FaceId2LocalSize.clear(); } //================================================================================ @@ -95,13 +134,10 @@ NETGENPlugin_Mesher::NETGENPlugin_Mesher (SMESH_Mesh* mesh, void NETGENPlugin_Mesher::defaultParameters() { -#ifdef WNT - netgen::MeshingParameters& mparams = netgen::GlobalMeshingParameters(); -#else netgen::MeshingParameters& mparams = netgen::mparam; -#endif // maximal mesh edge size - mparams.maxh = NETGENPlugin_Hypothesis::GetDefaultMaxSize(); + mparams.maxh = 0;//NETGENPlugin_Hypothesis::GetDefaultMaxSize(); + mparams.minh = 0; // minimal number of segments per edge mparams.segmentsperedge = NETGENPlugin_Hypothesis::GetDefaultNbSegPerEdge(); // rate of growth of size between elements @@ -115,6 +151,35 @@ void NETGENPlugin_Mesher::defaultParameters() mparams.quad = 0; else mparams.quad = NETGENPlugin_Hypothesis_2D::GetDefaultQuadAllowed() ? 1 : 0; + _fineness = NETGENPlugin_Hypothesis::GetDefaultFineness(); +} + +//============================================================================= +/*! + * + */ +//============================================================================= +void SetLocalSize(TopoDS_Shape GeomShape, double LocalSize) +{ + TopAbs_ShapeEnum GeomType = GeomShape.ShapeType(); + if (GeomType == TopAbs_COMPOUND) { + for (TopoDS_Iterator it (GeomShape); it.More(); it.Next()) { + SetLocalSize(it.Value(), LocalSize); + } + return; + } + int key; + if (! ShapesWithLocalSize.Contains(GeomShape)) + key = ShapesWithLocalSize.Add(GeomShape); + else + key = ShapesWithLocalSize.FindIndex(GeomShape); + if (GeomType == TopAbs_VERTEX) { + VertexId2LocalSize[key] = LocalSize; + } else if (GeomType == TopAbs_EDGE) { + EdgeId2LocalSize[key] = LocalSize; + } else if (GeomType == TopAbs_FACE) { + FaceId2LocalSize[key] = LocalSize; + } } //============================================================================= @@ -126,14 +191,12 @@ void NETGENPlugin_Mesher::SetParameters(const NETGENPlugin_Hypothesis* hyp) { if (hyp) { -#ifdef WNT - netgen::MeshingParameters& mparams = netgen::GlobalMeshingParameters(); -#else netgen::MeshingParameters& mparams = netgen::mparam; -#endif // Initialize global NETGEN parameters: // maximal mesh segment size mparams.maxh = hyp->GetMaxSize(); + // maximal mesh element linear size + mparams.minh = hyp->GetMinSize(); // minimal number of segments per edge mparams.segmentsperedge = hyp->GetNbSegPerEdge(); // rate of growth of size between elements @@ -143,12 +206,40 @@ void NETGENPlugin_Mesher::SetParameters(const NETGENPlugin_Hypothesis* hyp) // create elements of second order mparams.secondorder = hyp->GetSecondOrder() ? 1 : 0; // quad-dominated surface meshing - // only triangles are allowed for volumic mesh - if (!_isVolume) - mparams.quad = static_cast - (hyp)->GetQuadAllowed() ? 1 : 0; + // only triangles are allowed for volumic mesh (before realizing IMP 0021676) + //if (!_isVolume) + mparams.quad = hyp->GetQuadAllowed() ? 1 : 0; _optimize = hyp->GetOptimize(); + _fineness = hyp->GetFineness(); _simpleHyp = NULL; + + SMESH_Gen_i* smeshGen_i = SMESH_Gen_i::GetSMESHGen(); + CORBA::Object_var anObject = smeshGen_i->GetNS()->Resolve("/myStudyManager"); + SALOMEDS::StudyManager_var aStudyMgr = SALOMEDS::StudyManager::_narrow(anObject); + SALOMEDS::Study_var myStudy = aStudyMgr->GetStudyByID(hyp->GetStudyId()); + + const NETGENPlugin_Hypothesis::TLocalSize localSizes = hyp->GetLocalSizesAndEntries(); + NETGENPlugin_Hypothesis::TLocalSize::const_iterator it = localSizes.begin(); + for (it ; it != localSizes.end() ; it++) + { + std::string entry = (*it).first; + double val = (*it).second; + // -- + GEOM::GEOM_Object_var aGeomObj; + 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() ); + // -- + SetLocalSize(S, val); + } } } @@ -188,6 +279,171 @@ Standard_Boolean IsEqual(const Link& aLink1, const Link& aLink2) aLink1.n1 == aLink2.n2 && aLink1.n2 == aLink2.n1); } +namespace +{ + //================================================================================ + /*! + * \brief return id of netgen point corresponding to SMDS node + */ + //================================================================================ + typedef map< const SMDS_MeshNode*, int > TNode2IdMap; + + int ngNodeId( const SMDS_MeshNode* node, + netgen::Mesh& ngMesh, + TNode2IdMap& nodeNgIdMap) + { + int newNgId = ngMesh.GetNP() + 1; + + TNode2IdMap::iterator node_id = nodeNgIdMap.insert( make_pair( node, newNgId )).first; + + if ( node_id->second == newNgId) + { +#if defined(DUMP_SEGMENTS) || defined(DUMP_TRIANGLES) + cout << "Ng " << newNgId << " - " << node; +#endif + netgen::MeshPoint p( netgen::Point<3> (node->X(), node->Y(), node->Z()) ); + ngMesh.AddPoint( p ); + } + return node_id->second; + } + + //================================================================================ + /*! + * \brief Return computed EDGEs connected to the given one + */ + //================================================================================ + + list< TopoDS_Edge > getConnectedEdges( const TopoDS_Edge& edge, + const TopoDS_Face& face, + const set< SMESH_subMesh* > & computedSM, + const SMESH_MesherHelper& helper, + map< SMESH_subMesh*, set< int > >& addedEdgeSM2Faces) + { + // get ordered EDGEs + TopoDS_Vertex v1; + list< TopoDS_Edge > edges; + list< int > nbEdgesInWire; + int nbWires = SMESH_Block::GetOrderedEdges( face, v1, edges, nbEdgesInWire); + + // find within + list< TopoDS_Edge >::iterator eItFwd = edges.begin(); + for ( ; eItFwd != edges.end(); ++eItFwd ) + if ( edge.IsSame( *eItFwd )) + break; + if ( eItFwd == edges.end()) return list< TopoDS_Edge>(); + + if ( eItFwd->Orientation() >= TopAbs_INTERNAL ) + { + // connected INTERNAL edges returned from GetOrderedEdges() are wrongly oriented + // so treat each INTERNAL edge separately + TopoDS_Edge e = *eItFwd; + edges.clear(); + edges.push_back( e ); + return edges; + } + + // get all computed EDGEs connected to + + list< TopoDS_Edge >::iterator eItBack = eItFwd, ePrev; + TopoDS_Vertex vCommon; + TopTools_MapOfShape eAdded; // map used not to add a seam edge twice to + eAdded.Add( edge ); + + // put edges before to back + while ( edges.begin() != eItFwd ) + edges.splice( edges.end(), edges, edges.begin() ); + + // search forward + ePrev = eItFwd; + while ( ++eItFwd != edges.end() ) + { + SMESH_subMesh* sm = helper.GetMesh()->GetSubMesh( *eItFwd ); + + bool connected = TopExp::CommonVertex( *ePrev, *eItFwd, vCommon ); + bool computed = sm->IsMeshComputed(); + bool added = addedEdgeSM2Faces[ sm ].count( helper.GetSubShapeID() ); + bool doubled = !eAdded.Add( *eItFwd ); + bool orientOK = (( ePrev ->Orientation() < TopAbs_INTERNAL ) == + ( eItFwd->Orientation() < TopAbs_INTERNAL ) ); + if ( !connected || !computed || !orientOK || added || doubled ) + { + // stop advancement; move edges from tail to head + while ( edges.back() != *ePrev ) + edges.splice( edges.begin(), edges, --edges.end() ); + break; + } + ePrev = eItFwd; + } + // search backward + while ( eItBack != edges.begin() ) + { + ePrev = eItBack; + --eItBack; + SMESH_subMesh* sm = helper.GetMesh()->GetSubMesh( *eItBack ); + + bool connected = TopExp::CommonVertex( *ePrev, *eItBack, vCommon ); + bool computed = sm->IsMeshComputed(); + bool added = addedEdgeSM2Faces[ sm ].count( helper.GetSubShapeID() ); + bool doubled = !eAdded.Add( *eItBack ); + bool orientOK = (( ePrev ->Orientation() < TopAbs_INTERNAL ) == + ( eItBack->Orientation() < TopAbs_INTERNAL ) ); + if ( !connected || !computed || !orientOK || added || doubled) + { + // stop advancement + edges.erase( edges.begin(), ePrev ); + break; + } + } + if ( edges.front() != edges.back() ) + { + // assure that the 1st vertex is meshed + TopoDS_Edge eLast = edges.back(); + while ( !SMESH_Algo::VertexNode( SMESH_MesherHelper::IthVertex( 0, edges.front()), helper.GetMeshDS()) + && + edges.front() != eLast ) + edges.splice( edges.end(), edges, edges.begin() ); + } + return edges; + } + + //================================================================================ + /*! + * \brief Make triangulation of a shape precise enough + */ + //================================================================================ + + void updateTriangulation( const TopoDS_Shape& shape ) + { + // static set< Poly_Triangulation* > updated; + + // TopLoc_Location loc; + // TopExp_Explorer fExp( shape, TopAbs_FACE ); + // for ( ; fExp.More(); fExp.Next() ) + // { + // Handle(Poly_Triangulation) triangulation = + // BRep_Tool::Triangulation ( TopoDS::Face( fExp.Current() ), loc); + // if ( triangulation.IsNull() || + // updated.insert( triangulation.operator->() ).second ) + // { + // BRepTools::Clean (shape); + try { +#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 + OCC_CATCH_SIGNALS; +#endif + BRepMesh_IncrementalMesh e(shape, 0.01, true); + + } + catch (Standard_Failure) + { + } + // updated.erase( triangulation.operator->() ); + // triangulation = BRep_Tool::Triangulation ( TopoDS::Face( fExp.Current() ), loc); + // updated.insert( triangulation.operator->() ); + // } + // } + } +} + //================================================================================ /*! * \brief Initialize netgen::OCCGeometry with OCCT shape @@ -197,16 +453,11 @@ Standard_Boolean IsEqual(const Link& aLink1, const Link& aLink2) void NETGENPlugin_Mesher::PrepareOCCgeometry(netgen::OCCGeometry& occgeo, const TopoDS_Shape& shape, SMESH_Mesh& mesh, - list< SMESH_subMesh* > * meshedSM) + list< SMESH_subMesh* > * meshedSM, + NETGENPlugin_Internals* intern) { - BRepTools::Clean (shape); - try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 - OCC_CATCH_SIGNALS; -#endif - BRepMesh_IncrementalMesh::BRepMesh_IncrementalMesh (shape, 0.01, true); - } catch (Standard_Failure) { - } + updateTriangulation( shape ); + Bnd_Box bb; BRepBndLib::Add (shape, bb); double x1,y1,z1,x2,y2,z2; @@ -220,7 +471,6 @@ void NETGENPlugin_Mesher::PrepareOCCgeometry(netgen::OCCGeometry& occgeo, occgeo.shape = shape; occgeo.changed = 1; - //occgeo.BuildFMap(); // fill maps of shapes of occgeo with not yet meshed subshapes @@ -243,12 +493,18 @@ void NETGENPlugin_Mesher::PrepareOCCgeometry(netgen::OCCGeometry& occgeo, // to find a right orientation of subshapes (PAL20462) TopTools_IndexedMapOfShape subShapes; TopExp::MapShapes(root->GetSubShape(), subShapes); - while ( smIt->more() ) { + while ( smIt->more() ) + { SMESH_subMesh* sm = smIt->next(); - if ( sm->IsEmpty() ) { - TopoDS_Shape shape = sm->GetSubShape(); + TopoDS_Shape shape = sm->GetSubShape(); + if ( intern && intern->isShapeToPrecompute( shape )) + continue; + if ( !meshedSM || sm->IsEmpty() ) + { if ( shape.ShapeType() != TopAbs_VERTEX ) - shape = subShapes( subShapes.FindIndex( shape ));// - shape->index->oriented shape + shape = subShapes( subShapes.FindIndex( shape ));// shape -> index -> oriented shape + if ( shape.Orientation() >= TopAbs_INTERNAL ) + shape.Orientation( TopAbs_FORWARD ); // isuue 0020676 switch ( shape.ShapeType() ) { case TopAbs_FACE : occgeo.fmap.Add( shape ); break; case TopAbs_EDGE : occgeo.emap.Add( shape ); break; @@ -258,36 +514,91 @@ void NETGENPlugin_Mesher::PrepareOCCgeometry(netgen::OCCGeometry& occgeo, } } // collect submeshes of meshed shapes - else if (meshedSM) { - meshedSM->push_back( sm ); + else if (meshedSM) + { + const int dim = SMESH_Gen::GetShapeDim( shape ); + meshedSM[ dim ].push_back( sm ); } } } occgeo.facemeshstatus.SetSize (occgeo.fmap.Extent()); occgeo.facemeshstatus = 0; - +#ifdef NETGEN_NEW + occgeo.face_maxh_modified.SetSize(occgeo.fmap.Extent()); + occgeo.face_maxh_modified = 0; + occgeo.face_maxh.SetSize(occgeo.fmap.Extent()); + occgeo.face_maxh = netgen::mparam.maxh; +#endif } //================================================================================ /*! - * \brief return id of netgen point corresponding to SMDS node + * \brief Return a default min size value suitable for the given geometry. */ //================================================================================ -static int ngNodeId( const SMDS_MeshNode* node, - netgen::Mesh& ngMesh, - map< const SMDS_MeshNode*, int >& nodeNgIdMap) +double NETGENPlugin_Mesher::GetDefaultMinSize(const TopoDS_Shape& geom, + const double maxSize) { - int newNgId = ngMesh.GetNP() + 1; + updateTriangulation( geom ); + + TopLoc_Location loc; + int i1, i2, i3; + const int* pi[4] = { &i1, &i2, &i3, &i1 }; + double minh = 1e100; + Bnd_B3d bb; + TopExp_Explorer fExp( geom, TopAbs_FACE ); + for ( ; fExp.More(); fExp.Next() ) + { + Handle(Poly_Triangulation) triangulation = + BRep_Tool::Triangulation ( TopoDS::Face( fExp.Current() ), loc); + if ( triangulation.IsNull() ) continue; + const double fTol = BRep_Tool::Tolerance( TopoDS::Face( fExp.Current() )); + const TColgp_Array1OfPnt& points = triangulation->Nodes(); + const Poly_Array1OfTriangle& trias = triangulation->Triangles(); + for ( int iT = trias.Lower(); iT <= trias.Upper(); ++iT ) + { + trias(iT).Get( i1, i2, i3 ); + for ( int j = 0; j < 3; ++j ) + { + double dist2 = points(*pi[j]).SquareDistance( points( *pi[j+1] )); + if ( dist2 < minh && fTol*fTol < dist2 ) + minh = dist2; + bb.Add( points(*pi[j])); + } + } + } + if ( minh > 0.25 * bb.SquareExtent() ) // simple geometry, rough triangulation + { + minh = 1e-3 * sqrt( bb.SquareExtent()); + //cout << "BND BOX minh = " <ShapeToIndex( face ) << endl + << "\tface index: " << seg.si << endl + << "\tp1: " << seg[0] << endl + << "\tp2: " << seg[1] << endl + << "\tp0 param: " << seg.epgeominfo[ 0 ].dist << endl + << "\tp0 uv: " << seg.epgeominfo[ 0 ].u <<", "<< seg.epgeominfo[ 0 ].v << endl + //<< "\tp0 edge: " << seg.epgeominfo[ 0 ].edgenr << endl + << "\tp1 param: " << seg.epgeominfo[ 1 ].dist << endl + << "\tp1 uv: " << seg.epgeominfo[ 1 ].u <<", "<< seg.epgeominfo[ 1 ].v << endl; + //<< "\tp1 edge: " << seg.epgeominfo[ 1 ].edgenr << endl; +#endif if ( isSeam ) { - if ( helper.GetPeriodicIndex() == 1 ) { + if ( helper.GetPeriodicIndex() && 1 ) { seg.epgeominfo[ 0 ].u = otherSeamParam; seg.epgeominfo[ 1 ].u = otherSeamParam; swap (seg.epgeominfo[0].v, seg.epgeominfo[1].v); @@ -400,10 +760,26 @@ bool NETGENPlugin_Mesher::fillNgMesh(netgen::OCCGeometry& occgeom, seg.epgeominfo[ 1 ].v = otherSeamParam; swap (seg.epgeominfo[0].u, seg.epgeominfo[1].u); } - swap (seg.p1, seg.p2); + swap (seg[0], seg[1]); swap (seg.epgeominfo[0].dist, seg.epgeominfo[1].dist); seg.edgenr = ngMesh.GetNSeg() + 1; // segment id ngMesh.AddSegment (seg); +#ifdef DUMP_SEGMENTS + cout << "Segment: " << seg.edgenr << endl + << "\t is SEAM (reverse) of the previous. " + << " Other " << (helper.GetPeriodicIndex() && 1 ? "U" : "V") + << " = " << otherSeamParam << endl; +#endif + } + else if ( fOri == TopAbs_INTERNAL ) + { + swap (seg[0], seg[1]); + swap( seg.epgeominfo[0], seg.epgeominfo[1] ); + seg.edgenr = ngMesh.GetNSeg() + 1; // segment id + ngMesh.AddSegment (seg); +#ifdef DUMP_SEGMENTS + cout << "Segment: " << seg.edgenr << endl << "\t is REVERSE of the previous" << endl; +#endif } } } // loop on geomEdge ancestors @@ -415,69 +791,135 @@ bool NETGENPlugin_Mesher::fillNgMesh(netgen::OCCGeometry& occgeom, // ---------------------- const TopoDS_Face& geomFace = TopoDS::Face( sm->GetSubShape() ); helper.SetSubShape( geomFace ); + bool isInternalFace = ( geomFace.Orientation() == TopAbs_INTERNAL ); - // find solids geomFace bounds + // Find solids the geomFace bounds int solidID1 = 0, solidID2 = 0; - const TopTools_ListOfShape& ancestors = _mesh->GetAncestors( geomFace ); - TopTools_ListIteratorOfListOfShape ancestorIt ( ancestors ); - for ( ; ancestorIt.More(); ancestorIt.Next() ) + StdMeshers_QuadToTriaAdaptor* quadAdaptor = + dynamic_cast( proxyMesh.get() ); + if ( quadAdaptor ) { - const TopoDS_Shape & solid = ancestorIt.Value(); - if ( solid.ShapeType() == TopAbs_SOLID ) { - int id = occgeom.somap.FindIndex ( solid ); + solidID1 = occgeom.somap.FindIndex( quadAdaptor->GetShape() ); + } + else + { + PShapeIteratorPtr solidIt = helper.GetAncestors( geomFace, *sm->GetFather(), TopAbs_SOLID); + while ( const TopoDS_Shape * solid = solidIt->next() ) + { + int id = occgeom.somap.FindIndex ( *solid ); if ( solidID1 && id != solidID1 ) solidID2 = id; else solidID1 = id; } } - faceID++; - _faceDescriptors[ faceID ].first = solidID1; - _faceDescriptors[ faceID ].second = solidID2; + // Add ng face descriptors of meshed faces + faceNgID++; + ngMesh.AddFaceDescriptor (netgen::FaceDescriptor(faceNgID, solidID1, solidID2, 0)); + + // if second oreder is required, even already meshed faces must be passed to NETGEN + int fID = occgeom.fmap.Add( geomFace ); + while ( fID < faceNgID ) // geomFace is already in occgeom.fmap, add a copy + fID = occgeom.fmap.Add( BRepBuilderAPI_Copy( geomFace, /*copyGeom=*/false )); + // Problem with the second order in a quadrangular mesh remains. + // 1) All quadrangles geberated by NETGEN are moved to an inexistent face + // by FillSMesh() (find AddFaceDescriptor) + // 2) Temporary triangles generated by StdMeshers_QuadToTriaAdaptor + // are on faces where quadrangles were. + // Due to these 2 points, wrong geom faces are used while conversion to qudratic + // of the mentioned above quadrangles and triangles + + // Orient the face correctly in solidID1 (issue 0020206) + bool reverse = false; + if ( solidID1 ) { + TopoDS_Shape solid = occgeom.somap( solidID1 ); + TopAbs_Orientation faceOriInSolid = helper.GetSubShapeOri( solid, geomFace ); + if ( faceOriInSolid >= 0 ) + reverse = SMESH_Algo::IsReversedSubMesh + ( TopoDS::Face( geomFace.Oriented( faceOriInSolid )), helper.GetMeshDS() ); + } - // add surface elements - SMDS_ElemIteratorPtr faces = smDS->GetElements(); - while ( faces->more() ) { + // Add surface elements + + netgen::Element2d tri(3); + tri.SetIndex ( faceNgID ); + + +#ifdef DUMP_TRIANGLES + cout << "SMESH face " << helper.GetMeshDS()->ShapeToIndex( geomFace ) + << " internal="<GetSubMesh( geomFace ); + SMDS_ElemIteratorPtr faces = smDS->GetElements(); + while ( faces->more() ) + { const SMDS_MeshElement* f = faces->next(); - if ( f->NbNodes() % 3 != 0 ) { // not triangle - for ( ancestorIt.Initialize(ancestors); ancestorIt.More(); ancestorIt.Next() ) - if ( ancestorIt.Value().ShapeType() == TopAbs_SOLID ) { - sm = _mesh->GetSubMesh( ancestorIt.Value() ); - break; - } + if ( f->NbNodes() % 3 != 0 ) // not triangle + { + PShapeIteratorPtr solidIt=helper.GetAncestors(geomFace,*sm->GetFather(),TopAbs_SOLID); + if ( const TopoDS_Shape * solid = solidIt->next() ) + sm = _mesh->GetSubMesh( *solid ); SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); smError.reset( new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH,"Not triangle submesh")); smError->myBadElements.push_back( f ); return false; } - netgen::Element2d tri(3); - tri.SetIndex ( faceID ); - - for ( int i = 0; i < 3; ++i ) { + for ( int i = 0; i < 3; ++i ) + { const SMDS_MeshNode* node = f->GetNode( i ), * inFaceNode=0; - if ( helper.IsSeamShape( node->GetPosition()->GetShapeId() )) - if ( helper.IsSeamShape( f->GetNode( i+1 )->GetPosition()->GetShapeId() )) - inFaceNode = f->GetNode( i-1 ); + + // get node UV on face + int shapeID = node->getshapeId(); + if ( helper.IsSeamShape( shapeID )) + if ( helper.IsSeamShape( f->GetNodeWrap( i+1 )->getshapeId() )) + inFaceNode = f->GetNodeWrap( i-1 ); else - inFaceNode = f->GetNode( i+1 ); - + inFaceNode = f->GetNodeWrap( i+1 ); gp_XY uv = helper.GetNodeUV( geomFace, node, inFaceNode ); - tri.GeomInfoPi(i+1).u = uv.X(); - tri.GeomInfoPi(i+1).v = uv.Y(); - tri.PNum(i+1) = ngNodeId( node, ngMesh, nodeNgIdMap ); + + int ind = reverse ? 3-i : i+1; + tri.GeomInfoPi(ind).u = uv.X(); + tri.GeomInfoPi(ind).v = uv.Y(); + tri.PNum (ind) = ngNodeId( node, ngMesh, nodeNgIdMap ); } ngMesh.AddSurfaceElement (tri); +#ifdef DUMP_TRIANGLES + cout << tri << endl; +#endif + if ( isInternalFace ) + { + swap( tri[1], tri[2] ); + ngMesh.AddSurfaceElement (tri); +#ifdef DUMP_TRIANGLES + cout << tri << endl; +#endif + } } break; - } // + } // case TopAbs_FACE case TopAbs_VERTEX: { // VERTEX // -------------------------- - SMDS_NodeIteratorPtr nodeIt = smDS->GetNodes(); - if ( nodeIt->more() ) - ngNodeId( nodeIt->next(), ngMesh, nodeNgIdMap ); + // issue 0021405. Add node only if a VERTEX is shared by a not meshed EDGE, + // else netgen removes a free node and nodeVector becomes invalid + PShapeIteratorPtr ansIt = helper.GetAncestors( sm->GetSubShape(), + *sm->GetFather(), + TopAbs_EDGE ); + bool toAdd = false; + while ( const TopoDS_Shape* e = ansIt->next() ) + { + SMESH_subMesh* eSub = helper.GetMesh()->GetSubMesh( *e ); + if (( toAdd = eSub->IsEmpty() )) break; + } + if ( toAdd ) + { + SMDS_NodeIteratorPtr nodeIt = smDS->GetNodes(); + if ( nodeIt->more() ) + ngNodeId( nodeIt->next(), ngMesh, nodeNgIdMap ); + } break; } default:; @@ -486,454 +928,2192 @@ bool NETGENPlugin_Mesher::fillNgMesh(netgen::OCCGeometry& occgeom, // fill nodeVec nodeVec.resize( ngMesh.GetNP() + 1 ); - map< const SMDS_MeshNode*, int >::iterator node_NgId, nodeNgIdEnd = nodeNgIdMap.end(); + TNode2IdMap::iterator node_NgId, nodeNgIdEnd = nodeNgIdMap.end(); for ( node_NgId = nodeNgIdMap.begin(); node_NgId != nodeNgIdEnd; ++node_NgId) - nodeVec[ node_NgId->second ] = (SMDS_MeshNode*) node_NgId->first; + nodeVec[ node_NgId->second ] = node_NgId->first; return true; } -//============================================================================= +//================================================================================ /*! - * Here we are going to use the NETGEN mesher + * \brief Duplicate mesh faces on internal geom faces */ -//============================================================================= -bool NETGENPlugin_Mesher::Compute() +//================================================================================ + +void NETGENPlugin_Mesher::fixIntFaces(const netgen::OCCGeometry& occgeom, + netgen::Mesh& ngMesh, + NETGENPlugin_Internals& internalShapes) { -#ifdef WNT - netgen::MeshingParameters& mparams = netgen::GlobalMeshingParameters(); -#else - netgen::MeshingParameters& mparams = netgen::mparam; -#endif - MESSAGE("Compute with:\n" - " max size = " << mparams.maxh << "\n" - " segments per edge = " << mparams.segmentsperedge); - MESSAGE("\n" - " growth rate = " << mparams.grading << "\n" - " elements per radius = " << mparams.curvaturesafety << "\n" - " second order = " << mparams.secondorder << "\n" - " quad allowed = " << mparams.quad); + SMESHDS_Mesh* meshDS = internalShapes.getMesh().GetMeshDS(); + + // find ng indices of internal faces + set ngFaceIds; + for ( int ngFaceID = 1; ngFaceID <= occgeom.fmap.Extent(); ++ngFaceID ) + { + int smeshID = meshDS->ShapeToIndex( occgeom.fmap( ngFaceID )); + if ( internalShapes.isInternalShape( smeshID )) + ngFaceIds.insert( ngFaceID ); + } + if ( !ngFaceIds.empty() ) + { + // duplicate faces + int i, nbFaces = ngMesh.GetNSE(); + for (int i = 1; i <= nbFaces; ++i) + { + netgen::Element2d elem = ngMesh.SurfaceElement(i); + if ( ngFaceIds.count( elem.GetIndex() )) + { + swap( elem[1], elem[2] ); + ngMesh.AddSurfaceElement (elem); + } + } + } +} - SMESH_ComputeErrorPtr error = SMESH_ComputeError::New(); - nglib::Ng_Init(); +namespace +{ + //================================================================================ + // define gp_XY_Subtracted pointer to function calling gp_XY::Subtracted(gp_XY) + gp_XY_FunPtr(Subtracted); + //gp_XY_FunPtr(Added); + + //================================================================================ + /*! + * \brief Evaluate distance between two 2d points along the surface + */ + //================================================================================ + + double evalDist( const gp_XY& uv1, + const gp_XY& uv2, + const Handle(Geom_Surface)& surf, + const int stopHandler=-1) + { + if ( stopHandler > 0 ) // continue recursion + { + gp_XY mid = SMESH_MesherHelper::GetMiddleUV( surf, uv1, uv2 ); + return evalDist( uv1,mid, surf, stopHandler-1 ) + evalDist( mid,uv2, surf, stopHandler-1 ); + } + double dist3D = surf->Value( uv1.X(), uv1.Y() ).Distance( surf->Value( uv2.X(), uv2.Y() )); + if ( stopHandler == 0 ) // stop recursion + return dist3D; + + // start recursion if necessary + double dist2D = SMESH_MesherHelper::applyIn2D(surf, uv1, uv2, gp_XY_Subtracted, 0).Modulus(); + if ( fabs( dist3D - dist2D ) < dist2D * 1e-10 ) + return dist3D; // equal parametrization of a planar surface + + return evalDist( uv1, uv2, surf, 3 ); // start recursion + } - // ------------------------- - // Prepare OCC geometry - // ------------------------- + //================================================================================ + /*! + * \brief Data of vertex internal in geom face + */ + //================================================================================ - netgen::OCCGeometry occgeo; - list< SMESH_subMesh* > meshedSM; - PrepareOCCgeometry( occgeo, _shape, *_mesh, &meshedSM ); + struct TIntVData + { + gp_XY uv; //!< UV in face parametric space + int ngId; //!< ng id of corrsponding node + gp_XY uvClose; //!< UV of closest boundary node + int ngIdClose; //!< ng id of closest boundary node + }; + + //================================================================================ + /*! + * \brief Data of vertex internal in solid + */ + //================================================================================ + + struct TIntVSoData + { + int ngId; //!< ng id of corresponding node + int ngIdClose; //!< ng id of closest 2d mesh element + int ngIdCloseN; //!< ng id of closest node of the closest 2d mesh element + }; - // ------------------------- - // Generate the mesh - // ------------------------- + inline double dist2(const netgen::MeshPoint& p1, const netgen::MeshPoint& p2) + { + return gp_Pnt( NGPOINT_COORDS(p1)).SquareDistance( gp_Pnt( NGPOINT_COORDS(p2))); + } +} - netgen::Mesh *ngMesh = NULL; +//================================================================================ +/*! + * \brief Make netgen take internal vertices in faces into account by adding + * segments including internal vertices + * + * This function works in supposition that 1D mesh is already computed in ngMesh + */ +//================================================================================ - SMESH_Comment comment; - int err = 0; - int nbInitNod = 0; - int nbInitSeg = 0; - int nbInitFac = 0; - // vector of nodes in which node index == netgen ID - vector< SMDS_MeshNode* > nodeVec; - try +void NETGENPlugin_Mesher::addIntVerticesInFaces(const netgen::OCCGeometry& occgeom, + netgen::Mesh& ngMesh, + vector& nodeVec, + NETGENPlugin_Internals& internalShapes) +{ + if ( nodeVec.size() < ngMesh.GetNP() ) + nodeVec.resize( ngMesh.GetNP(), 0 ); + + SMESHDS_Mesh* meshDS = internalShapes.getMesh().GetMeshDS(); + SMESH_MesherHelper helper( internalShapes.getMesh() ); + + const map >& face2Vert = internalShapes.getFacesWithVertices(); + map >::const_iterator f2v = face2Vert.begin(); + for ( ; f2v != face2Vert.end(); ++f2v ) { - // ---------------- - // compute 1D mesh - // ---------------- - // pass 1D simple parameters to NETGEN - if ( _simpleHyp ) { - if ( int nbSeg = _simpleHyp->GetNumberOfSegments() ) { - // nb of segments - mparams.segmentsperedge = nbSeg + 0.1; - mparams.maxh = occgeo.boundingbox.Diam(); - mparams.grading = 0; + const TopoDS_Face& face = TopoDS::Face( meshDS->IndexToShape( f2v->first )); + if ( face.IsNull() ) continue; + int faceNgID = occgeom.fmap.FindIndex (face); + if ( faceNgID < 0 ) continue; + + TopLoc_Location loc; + Handle(Geom_Surface) surf = BRep_Tool::Surface(face,loc); + + helper.SetSubShape( face ); + helper.SetElementsOnShape( true ); + + // Get data of internal vertices and add them to ngMesh + + multimap< double, TIntVData > dist2VData; // sort vertices by distance from boundary nodes + + int i, nbSegInit = ngMesh.GetNSeg(); + + // boundary characteristics + double totSegLen2D = 0; + int totNbSeg = 0; + + const list& iVertices = f2v->second; + list::const_iterator iv = iVertices.begin(); + for ( int nbV = 0; iv != iVertices.end(); ++iv, nbV++ ) + { + TIntVData vData; + // get node on vertex + const TopoDS_Vertex V = TopoDS::Vertex( meshDS->IndexToShape( *iv )); + const SMDS_MeshNode * nV = SMESH_Algo::VertexNode( V, meshDS ); + if ( !nV ) + { + SMESH_subMesh* sm = helper.GetMesh()->GetSubMesh( V ); + sm->ComputeStateEngine( SMESH_subMesh::COMPUTE ); + nV = SMESH_Algo::VertexNode( V, meshDS ); + if ( !nV ) continue; } - else { - // segment length - mparams.segmentsperedge = 1; - mparams.maxh = _simpleHyp->GetLocalLength(); + // add ng node + netgen::MeshPoint mp( netgen::Point<3> (nV->X(), nV->Y(), nV->Z()) ); + ngMesh.AddPoint ( mp, 1, netgen::EDGEPOINT ); + vData.ngId = ngMesh.GetNP(); + nodeVec.push_back( nV ); + + // get node UV + bool uvOK = false; + vData.uv = helper.GetNodeUV( face, nV, 0, &uvOK ); + if ( !uvOK ) helper.CheckNodeUV( face, nV, vData.uv, BRep_Tool::Tolerance(V),/*force=*/1); + + // loop on all segments of the face to find the node closest to vertex and to count + // average segment 2d length + double closeDist2 = numeric_limits::max(), dist2; + int ngIdLast = 0; + for (i = 1; i <= ngMesh.GetNSeg(); ++i) + { + netgen::Segment & seg = ngMesh.LineSegment(i); + if ( seg.si != faceNgID ) continue; + gp_XY uv[2]; + for ( int iEnd = 0; iEnd < 2; ++iEnd) + { + uv[iEnd].SetCoord( seg.epgeominfo[iEnd].u, seg.epgeominfo[iEnd].v ); + if ( ngIdLast == seg[ iEnd ] ) continue; + dist2 = helper.applyIn2D(surf, uv[iEnd], vData.uv, gp_XY_Subtracted,0).SquareModulus(); + if ( dist2 < closeDist2 ) + vData.ngIdClose = seg[ iEnd ], vData.uvClose = uv[iEnd], closeDist2 = dist2; + ngIdLast = seg[ iEnd ]; + } + if ( !nbV ) + { + totSegLen2D += helper.applyIn2D(surf, uv[0], uv[1], gp_XY_Subtracted, false).Modulus(); + totNbSeg++; + } } + dist2VData.insert( make_pair( closeDist2, vData )); } - // let netgen create ngMesh and calculate element size on not meshed shapes - char *optstr = 0; - int startWith = netgen::MESHCONST_ANALYSE; - int endWith = netgen::MESHCONST_ANALYSE; - err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr); - if (err) comment << "Error in netgen::OCCGenerateMesh() at MESHCONST_ANALYSE step"; - // fill ngMesh with nodes and elements of computed submeshes - err = ! fillNgMesh(occgeo, *ngMesh, nodeVec, meshedSM); - nbInitNod = ngMesh->GetNP(); - nbInitSeg = ngMesh->GetNSeg(); - nbInitFac = ngMesh->GetNSE(); + if ( totNbSeg == 0 ) break; + double avgSegLen2d = totSegLen2D / totNbSeg; - // compute mesh - if (!err) + // Loop on vertices to add segments + + multimap< double, TIntVData >::iterator dist_vData = dist2VData.begin(); + for ( ; dist_vData != dist2VData.end(); ++dist_vData ) { - startWith = endWith = netgen::MESHCONST_MESHEDGES; - err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr); - if (err) comment << "Error in netgen::OCCGenerateMesh() at 1D mesh generation"; - } - // --------------------- - // compute surface mesh - // --------------------- - if (!err) - { - // pass 2D simple parameters to NETGEN - if ( _simpleHyp ) { - if ( double area = _simpleHyp->GetMaxElementArea() ) { - // face area - mparams.maxh = sqrt(2. * area/sqrt(3.0)); - mparams.grading = 0.4; // moderate size growth - } - else { - // length from edges - double length = 0; - for ( TopExp_Explorer exp( _shape, TopAbs_EDGE ); exp.More(); exp.Next() ) - length += SMESH_Algo::EdgeLength( TopoDS::Edge( exp.Current() )); - if ( ngMesh->GetNSeg() ) - mparams.maxh = length / ngMesh->GetNSeg(); - else - mparams.maxh = 1000; - mparams.grading = 0.2; // slow size growth + double closeDist2 = dist_vData->first, dist2; + TIntVData & vData = dist_vData->second; + + // try to find more close node among segments added for internal vertices + for (i = nbSegInit+1; i <= ngMesh.GetNSeg(); ++i) + { + netgen::Segment & seg = ngMesh.LineSegment(i); + if ( seg.si != faceNgID ) continue; + gp_XY uv[2]; + for ( int iEnd = 0; iEnd < 2; ++iEnd) + { + uv[iEnd].SetCoord( seg.epgeominfo[iEnd].u, seg.epgeominfo[iEnd].v ); + dist2 = helper.applyIn2D(surf, uv[iEnd], vData.uv, gp_XY_Subtracted,0).SquareModulus(); + if ( dist2 < closeDist2 ) + vData.ngIdClose = seg[ iEnd ], vData.uvClose = uv[iEnd], closeDist2 = dist2; } - mparams.maxh = min( mparams.maxh, occgeo.boundingbox.Diam()/2 ); - ngMesh->SetGlobalH (mparams.maxh); - netgen::Box<3> bb = occgeo.GetBoundingBox(); - bb.Increase (bb.Diam()/20); - ngMesh->SetLocalH (bb.PMin(), bb.PMax(), mparams.grading); } - // let netgen compute 2D mesh - startWith = netgen::MESHCONST_MESHSURFACE; - endWith = _optimize ? netgen::MESHCONST_OPTSURFACE : netgen::MESHCONST_MESHSURFACE; - err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr); - if (err) comment << "Error in netgen::OCCGenerateMesh() at surface mesh generation"; + // decide whether to use the closest node as the second end of segment or to + // create a new point + int segEnd1 = vData.ngId; + int segEnd2 = vData.ngIdClose; // to use closest node + gp_XY uvV = vData.uv, uvP = vData.uvClose; + double segLenHint = ngMesh.GetH( ngMesh.Point( vData.ngId )); + double nodeDist2D = sqrt( closeDist2 ); + double nodeDist3D = evalDist( vData.uv, vData.uvClose, surf ); + bool avgLenOK = ( avgSegLen2d < 0.75 * nodeDist2D ); + bool hintLenOK = ( segLenHint < 0.75 * nodeDist3D ); + //cout << "uvV " << uvV.X() <<","<Value( uvP.X(), uvP.Y() ).Transformed( loc ); + + netgen::MeshPoint mp( netgen::Point<3> (P.X(), P.Y(), P.Z())); + ngMesh.AddPoint ( mp, 1, netgen::EDGEPOINT ); + segEnd2 = ngMesh.GetNP(); + //cout << "Middle " << r << " uv " << uvP.X() << "," << uvP.Y() << "( " << ngMesh.Point(segEnd2).X()<<","< segEnd2 ) swap( segEnd1, segEnd2 ), swap( uvV, uvP ); + seg[0] = segEnd1; // ng node id + seg[1] = segEnd2; // ng node id + seg.edgenr = ngMesh.GetNSeg() + 1;// segment id + seg.si = faceNgID; + + seg.epgeominfo[ 0 ].dist = 0; // param on curve + seg.epgeominfo[ 0 ].u = uvV.X(); + seg.epgeominfo[ 0 ].v = uvV.Y(); + seg.epgeominfo[ 1 ].dist = 1; // param on curve + seg.epgeominfo[ 1 ].u = uvP.X(); + seg.epgeominfo[ 1 ].v = uvP.Y(); + +// seg.epgeominfo[ 0 ].edgenr = 10; // = geom.emap.FindIndex(edge); +// seg.epgeominfo[ 1 ].edgenr = 10; // = geom.emap.FindIndex(edge); + + ngMesh.AddSegment (seg); + + // add reverse segment + swap (seg[0], seg[1]); + swap( seg.epgeominfo[0], seg.epgeominfo[1] ); + seg.edgenr = ngMesh.GetNSeg() + 1; // segment id + ngMesh.AddSegment (seg); } - // --------------------- - // generate volume mesh - // --------------------- - if (!err && _isVolume) + + } +} + +//================================================================================ +/*! + * \brief Make netgen take internal vertices in solids into account by adding + * faces including internal vertices + * + * This function works in supposition that 2D mesh is already computed in ngMesh + */ +//================================================================================ + +void NETGENPlugin_Mesher::addIntVerticesInSolids(const netgen::OCCGeometry& occgeom, + netgen::Mesh& ngMesh, + vector& nodeVec, + NETGENPlugin_Internals& internalShapes) +{ +#ifdef DUMP_TRIANGLES_SCRIPT + // create a python script making a mesh containing triangles added for internal vertices + ofstream py(DUMP_TRIANGLES_SCRIPT); + py << "from smesh import * "<< endl + << "m = Mesh(name='triangles')" << endl; +#endif + if ( nodeVec.size() < ngMesh.GetNP() ) + nodeVec.resize( ngMesh.GetNP(), 0 ); + + SMESHDS_Mesh* meshDS = internalShapes.getMesh().GetMeshDS(); + SMESH_MesherHelper helper( internalShapes.getMesh() ); + + const map >& so2Vert = internalShapes.getSolidsWithVertices(); + map >::const_iterator s2v = so2Vert.begin(); + for ( ; s2v != so2Vert.end(); ++s2v ) + { + const TopoDS_Shape& solid = meshDS->IndexToShape( s2v->first ); + if ( solid.IsNull() ) continue; + int solidNgID = occgeom.somap.FindIndex (solid); + if ( solidNgID < 0 && !occgeom.somap.IsEmpty() ) continue; + + helper.SetSubShape( solid ); + helper.SetElementsOnShape( true ); + + // find ng indices of faces within the solid + set ngFaceIds; + for (TopExp_Explorer fExp(solid, TopAbs_FACE); fExp.More(); fExp.Next() ) + ngFaceIds.insert( occgeom.fmap.FindIndex( fExp.Current() )); + if ( ngFaceIds.size() == 1 && *ngFaceIds.begin() == 0 ) + ngFaceIds.insert( 1 ); + + // Get data of internal vertices and add them to ngMesh + + multimap< double, TIntVSoData > dist2VData; // sort vertices by distance from ng faces + + int i, nbFaceInit = ngMesh.GetNSE(); + + // boundary characteristics + double totSegLen = 0; + int totNbSeg = 0; + + const list& iVertices = s2v->second; + list::const_iterator iv = iVertices.begin(); + for ( int nbV = 0; iv != iVertices.end(); ++iv, nbV++ ) { - // add ng face descriptors of meshed faces - std::map< int, std::pair >::iterator fId_soIds = _faceDescriptors.begin(); - for ( ; fId_soIds != _faceDescriptors.end(); ++fId_soIds ) { - int faceID = fId_soIds->first; - int solidID1 = fId_soIds->second.first; - int solidID2 = fId_soIds->second.second; - ngMesh->AddFaceDescriptor (netgen::FaceDescriptor(faceID, solidID1, solidID2, 0)); + TIntVSoData vData; + const TopoDS_Vertex V = TopoDS::Vertex( meshDS->IndexToShape( *iv )); + + // get node on vertex + const SMDS_MeshNode * nV = SMESH_Algo::VertexNode( V, meshDS ); + if ( !nV ) + { + SMESH_subMesh* sm = helper.GetMesh()->GetSubMesh( V ); + sm->ComputeStateEngine( SMESH_subMesh::COMPUTE ); + nV = SMESH_Algo::VertexNode( V, meshDS ); + if ( !nV ) continue; } - // pass 3D simple parameters to NETGEN - const NETGENPlugin_SimpleHypothesis_3D* simple3d = - dynamic_cast< const NETGENPlugin_SimpleHypothesis_3D* > ( _simpleHyp ); - if ( simple3d ) { - if ( double vol = simple3d->GetMaxElementVolume() ) { - // max volume - mparams.maxh = pow( 72, 1/6. ) * pow( vol, 1/3. ); - mparams.maxh = min( mparams.maxh, occgeo.boundingbox.Diam()/2 ); - } - else { - // length from faces - mparams.maxh = ngMesh->AverageH(); + // add ng node + netgen::MeshPoint mpV( netgen::Point<3> (nV->X(), nV->Y(), nV->Z()) ); + ngMesh.AddPoint ( mpV, 1, netgen::FIXEDPOINT ); + vData.ngId = ngMesh.GetNP(); + nodeVec.push_back( nV ); + + // loop on all 2d elements to find the one closest to vertex and to count + // average segment length + double closeDist2 = numeric_limits::max(), avgDist2; + for (i = 1; i <= ngMesh.GetNSE(); ++i) + { + const netgen::Element2d& elem = ngMesh.SurfaceElement(i); + if ( !ngFaceIds.count( elem.GetIndex() )) continue; + avgDist2 = 0; + multimap< double, int> dist2nID; // sort nodes of element by distance from V + for ( int j = 0; j < elem.GetNP(); ++j) + { + netgen::MeshPoint mp = ngMesh.Point( elem[j] ); + double d2 = dist2( mpV, mp ); + dist2nID.insert( make_pair( d2, elem[j] )); + avgDist2 += d2 / elem.GetNP(); + if ( !nbV ) + totNbSeg++, totSegLen+= sqrt( dist2( mp, ngMesh.Point( elem[(j+1)%elem.GetNP()]))); } -// netgen::ARRAY maxhdom; -// maxhdom.SetSize (occgeo.NrSolids()); -// maxhdom = mparams.maxh; -// ngMesh->SetMaxHDomain (maxhdom); - ngMesh->SetGlobalH (mparams.maxh); - mparams.grading = 0.4; - ngMesh->CalcLocalH(); + double dist = dist2nID.begin()->first; //avgDist2; + if ( dist < closeDist2 ) + vData.ngIdClose= i, vData.ngIdCloseN= dist2nID.begin()->second, closeDist2= dist; } - // let netgen compute 3D mesh - startWith = netgen::MESHCONST_MESHVOLUME; - endWith = _optimize ? netgen::MESHCONST_OPTVOLUME : netgen::MESHCONST_MESHVOLUME; - err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr); - if (err) comment << "Error in netgen::OCCGenerateMesh()"; - } - if (!err && mparams.secondorder > 0) - { - netgen::OCCRefinementSurfaces ref (occgeo); - ref.MakeSecondOrder (*ngMesh); + dist2VData.insert( make_pair( closeDist2, vData )); } - } - catch (netgen::NgException exc) - { - error->myName = err = COMPERR_ALGO_FAILED; - comment << exc.What(); - } - int nbNod = ngMesh->GetNP(); - int nbSeg = ngMesh->GetNSeg(); - int nbFac = ngMesh->GetNSE(); - int nbVol = ngMesh->GetNE(); + if ( totNbSeg == 0 ) break; + double avgSegLen = totSegLen / totNbSeg; - MESSAGE((err ? "Mesh Generation failure" : "End of Mesh Generation") << - ", nb nodes: " << nbNod << - ", nb segments: " << nbSeg << - ", nb faces: " << nbFac << - ", nb volumes: " << nbVol); + // Loop on vertices to add triangles - // ----------------------------------------------------------- - // Feed back the SMESHDS with the generated Nodes and Elements - // ----------------------------------------------------------- + multimap< double, TIntVSoData >::iterator dist_vData = dist2VData.begin(); + for ( ; dist_vData != dist2VData.end(); ++dist_vData ) + { + double closeDist2 = dist_vData->first; + TIntVSoData & vData = dist_vData->second; - SMESHDS_Mesh* meshDS = _mesh->GetMeshDS(); - bool isOK = ( !err && (_isVolume ? (nbVol > 0) : (nbFac > 0)) ); - if ( true /*isOK*/ ) // get whatever built - { - // map of nodes assigned to submeshes - NCollection_Map pindMap; - // create and insert nodes into nodeVec - nodeVec.resize( nbNod + 1 ); - int i; - for (i = nbInitNod+1; i <= nbNod /*&& isOK*/; ++i ) - { - const netgen::MeshPoint& ngPoint = ngMesh->Point(i); - SMDS_MeshNode* node = NULL; - bool newNodeOnVertex = false; - TopoDS_Vertex aVert; - if (i-nbInitNod <= occgeo.vmap.Extent()) - { - // point on vertex - aVert = TopoDS::Vertex(occgeo.vmap(i-nbInitNod)); - SMESHDS_SubMesh * submesh = meshDS->MeshElements(aVert); - if (submesh) + const netgen::MeshPoint& mpV = ngMesh.Point( vData.ngId ); + + // try to find more close face among ones added for internal vertices + for (i = nbFaceInit+1; i <= ngMesh.GetNSE(); ++i) + { + double avgDist2 = 0; + multimap< double, int> dist2nID; + const netgen::Element2d& elem = ngMesh.SurfaceElement(i); + for ( int j = 0; j < elem.GetNP(); ++j) + { + double d = dist2( mpV, ngMesh.Point( elem[j] )); + dist2nID.insert( make_pair( d, elem[j] )); + avgDist2 += d / elem.GetNP(); + if ( avgDist2 < closeDist2 ) + vData.ngIdClose= i, vData.ngIdCloseN= dist2nID.begin()->second, closeDist2= avgDist2; + } + } + // sort nodes of the closest face by angle with vector from V to the closest node + const double tol = numeric_limits::min(); + map< double, int > angle2ID; + const netgen::Element2d& closeFace = ngMesh.SurfaceElement( vData.ngIdClose ); + netgen::MeshPoint mp[2]; + mp[0] = ngMesh.Point( vData.ngIdCloseN ); + gp_XYZ p1( NGPOINT_COORDS( mp[0] )); + gp_XYZ pV( NGPOINT_COORDS( mpV )); + gp_Vec v2p1( pV, p1 ); + double distN1 = v2p1.Magnitude(); + if ( distN1 <= tol ) continue; + v2p1 /= distN1; + for ( int j = 0; j < closeFace.GetNP(); ++j) + { + mp[1] = ngMesh.Point( closeFace[j] ); + gp_Vec v2p( pV, gp_Pnt( NGPOINT_COORDS( mp[1] )) ); + angle2ID.insert( make_pair( v2p1.Angle( v2p ), closeFace[j])); + } + // get node with angle of 60 degrees or greater + map< double, int >::iterator angle_id = angle2ID.lower_bound( 60. * M_PI / 180. ); + if ( angle_id == angle2ID.end() ) angle_id = --angle2ID.end(); + const double minAngle = 30. * M_PI / 180.; + const double angle = angle_id->first; + bool angleOK = ( angle > minAngle ); + + // find points to create a triangle + netgen::Element2d tri(3); + tri.SetIndex ( 1 ); + tri[0] = vData.ngId; + tri[1] = vData.ngIdCloseN; // to use the closest nodes + tri[2] = angle_id->second; // to use the node with best angle + + // decide whether to use the closest node and the node with best angle or to create new ones + for ( int isBestAngleN = 0; isBestAngleN < 2; ++isBestAngleN ) + { + bool createNew = !angleOK, distOK = true; + double distFromV; + int triInd = isBestAngleN ? 2 : 1; + mp[isBestAngleN] = ngMesh.Point( tri[triInd] ); + if ( isBestAngleN ) { - SMDS_NodeIteratorPtr it = submesh->GetNodes(); - if (it->more()) + if ( angleOK ) { - node = const_cast (it->next()); - pindMap.Add(i); + double distN2 = sqrt( dist2( mpV, mp[isBestAngleN])); + createNew = ( fabs( distN2 - distN1 ) > 0.25 * distN1 ); } + else if ( angle < tol ) + { + v2p1.SetX( v2p1.X() + 1e-3 ); + } + distFromV = distN1; + } + else + { + double segLenHint = ngMesh.GetH( ngMesh.Point( vData.ngId )); + bool avgLenOK = ( avgSegLen < 0.75 * distN1 ); + bool hintLenOK = ( segLenHint < 0.75 * distN1 ); + createNew = (createNew || avgLenOK || hintLenOK ); + // we create a new node not closer than 0.5 to the closest face + // in order not to clash with other close face + double r = min( 0.5, ( hintLenOK ? segLenHint : avgSegLen ) / distN1 ); + distFromV = r * distN1; + } + if ( createNew ) + { + // create a new point, between the node and the vertex if angleOK + gp_XYZ p( NGPOINT_COORDS( mp[isBestAngleN] )); + gp_Vec v2p( pV, p ); v2p.Normalize(); + if ( isBestAngleN && !angleOK ) + p = p1 + gp_Dir( v2p.XYZ() - v2p1.XYZ()).XYZ() * distN1 * 0.95; + else + p = pV + v2p.XYZ() * distFromV; + + if ( !isBestAngleN ) p1 = p, distN1 = distFromV; + + mp[isBestAngleN].SetPoint( netgen::Point<3> (p.X(), p.Y(), p.Z())); + ngMesh.AddPoint ( mp[isBestAngleN], 1, netgen::SURFACEPOINT ); + tri[triInd] = ngMesh.GetNP(); + nodeVec.push_back( helper.AddNode( p.X(), p.Y(), p.Z()) ); } - if (!node) - newNodeOnVertex = true; } - if (!node) - node = meshDS->AddNode(ngPoint.X(), ngPoint.Y(), ngPoint.Z()); - if (!node) + ngMesh.AddSurfaceElement (tri); + swap( tri[1], tri[2] ); + ngMesh.AddSurfaceElement (tri); + +#ifdef DUMP_TRIANGLES_SCRIPT + py << "n1 = m.AddNode( "<< mpV.X()<<", "<< mpV.Y()<<", "<< mpV.Z()<<") "<< endl + << "n2 = m.AddNode( "<< mp[0].X()<<", "<< mp[0].Y()<<", "<< mp[0].Z()<<") "<< endl + << "n3 = m.AddNode( "<< mp[1].X()<<", "<< mp[1].Y()<<", "<< mp[1].Z()<<" )" << endl + << "m.AddFace([n1,n2,n3])" << endl; +#endif + } // loop on internal vertices of a solid + + } // loop on solids with internal vertices +} + +//================================================================================ +/*! + * \brief Fill SMESH mesh according to contents of netgen mesh + * \param occgeo - container of OCCT geometry to mesh + * \param ngMesh - netgen mesh + * \param initState - bn of entities in netgen mesh before computing + * \param sMesh - SMESH mesh to fill in + * \param nodeVec - vector of nodes in which node index == netgen ID + * \retval int - error + */ +//================================================================================ + +int NETGENPlugin_Mesher::FillSMesh(const netgen::OCCGeometry& occgeo, + netgen::Mesh& ngMesh, + const NETGENPlugin_ngMeshInfo& initState, + SMESH_Mesh& sMesh, + std::vector& nodeVec, + SMESH_Comment& comment) +{ + int nbNod = ngMesh.GetNP(); + int nbSeg = ngMesh.GetNSeg(); + int nbFac = ngMesh.GetNSE(); + int nbVol = ngMesh.GetNE(); + + SMESHDS_Mesh* meshDS = sMesh.GetMeshDS(); + + // ------------------------------------- + // Create and insert nodes into nodeVec + // ------------------------------------- + + nodeVec.resize( nbNod + 1 ); + int i, nbInitNod = initState._nbNodes; + for (i = nbInitNod+1; i <= nbNod; ++i ) + { + const netgen::MeshPoint& ngPoint = ngMesh.Point(i); + SMDS_MeshNode* node = NULL; + TopoDS_Vertex aVert; + // First, netgen creates nodes on vertices in occgeo.vmap, + // so node index corresponds to vertex index + // but (issue 0020776) netgen does not create nodes with equal coordinates + if ( i-nbInitNod <= occgeo.vmap.Extent() ) + { + gp_Pnt p ( NGPOINT_COORDS(ngPoint) ); + for (int iV = i-nbInitNod; aVert.IsNull() && iV <= occgeo.vmap.Extent(); ++iV) { - MESSAGE("Cannot create a mesh node"); - if ( !comment.size() ) comment << "Cannot create a mesh node"; - nbSeg = nbFac = nbVol = isOK = 0; - break; + aVert = TopoDS::Vertex( occgeo.vmap( iV ) ); + gp_Pnt pV = BRep_Tool::Pnt( aVert ); + if ( p.SquareDistance( pV ) > 1e-20 ) + aVert.Nullify(); + else + node = const_cast( SMESH_Algo::VertexNode( aVert, meshDS )); } - nodeVec.at(i) = node; - if (newNodeOnVertex) - { - // point on vertex + } + if (!node) // node not found on vertex + { + node = meshDS->AddNode( NGPOINT_COORDS( ngPoint )); + if (!aVert.IsNull()) meshDS->SetNodeOnVertex(node, aVert); - pindMap.Add(i); - } } + nodeVec[i] = node; + } - // create mesh segments along geometric edges - NCollection_Map linkMap; - for (i = nbInitSeg+1; i <= nbSeg/* && isOK*/; ++i ) + // ------------------------------------------- + // Create mesh segments along geometric edges + // ------------------------------------------- + + int nbInitSeg = initState._nbSegments; + for (i = nbInitSeg+1; i <= nbSeg; ++i ) + { + const netgen::Segment& seg = ngMesh.LineSegment(i); + TopoDS_Edge aEdge; +#ifdef NETGEN_NEW + int pinds[3] = { seg.pnums[0], seg.pnums[1], seg.pnums[2] }; +#else + int pinds[3] = { seg.p1, seg.p2, seg.pmid }; +#endif + int nbp = 0; + double param2 = 0; + for (int j=0; j < 3; ++j) { - const netgen::Segment& seg = ngMesh->LineSegment(i); - Link link(seg.p1, seg.p2); - if (linkMap.Contains(link)) - continue; - linkMap.Add(link); - TopoDS_Edge aEdge; - int pinds[3] = { seg.p1, seg.p2, seg.pmid }; - int nbp = 0; - double param2 = 0; - for (int j=0; j < 3; ++j) - { - int pind = pinds[j]; - if (pind <= 0) continue; - ++nbp; - double param; - if (j < 2) + int pind = pinds[j]; + if (pind <= 0 || !nodeVec_ACCESS(pind)) + break; + ++nbp; + double param; + if (j < 2) + { + if (aEdge.IsNull()) { - if (aEdge.IsNull()) - { - int aGeomEdgeInd = seg.epgeominfo[j].edgenr; - if (aGeomEdgeInd > 0 && aGeomEdgeInd <= occgeo.emap.Extent()) - aEdge = TopoDS::Edge(occgeo.emap(aGeomEdgeInd)); - } - param = seg.epgeominfo[j].dist; - param2 += param; + int aGeomEdgeInd = seg.epgeominfo[j].edgenr; + if (aGeomEdgeInd > 0 && aGeomEdgeInd <= occgeo.emap.Extent()) + aEdge = TopoDS::Edge(occgeo.emap(aGeomEdgeInd)); } - else - param = param2 * 0.5; - if (pind <= nbInitNod || pindMap.Contains(pind)) + param = seg.epgeominfo[j].dist; + param2 += param; + } + else // middle point + { + param = param2 * 0.5; + } + if (!aEdge.IsNull() && nodeVec_ACCESS(pind)->getshapeId() < 1) + { + meshDS->SetNodeOnEdge(nodeVec_ACCESS(pind), aEdge, param); + } + } + if ( nbp > 1 ) + { + SMDS_MeshEdge* edge = 0; + if (nbp == 2) // second order ? + { + if ( meshDS->FindEdge( nodeVec_ACCESS(pinds[0]), nodeVec_ACCESS(pinds[1]))) continue; - if (!aEdge.IsNull()) - { - meshDS->SetNodeOnEdge(nodeVec.at(pind), aEdge, param); - pindMap.Add(pind); - } + edge = meshDS->AddEdge(nodeVec_ACCESS(pinds[0]), nodeVec_ACCESS(pinds[1])); } - SMDS_MeshEdge* edge; - if (nbp < 3) // second order ? - edge = meshDS->AddEdge(nodeVec.at(pinds[0]), nodeVec.at(pinds[1])); else - edge = meshDS->AddEdge(nodeVec.at(pinds[0]), nodeVec.at(pinds[1]), - nodeVec.at(pinds[2])); + { + if ( meshDS->FindEdge( nodeVec_ACCESS(pinds[0]), nodeVec_ACCESS(pinds[1]), + nodeVec_ACCESS(pinds[2]))) + continue; + edge = meshDS->AddEdge(nodeVec_ACCESS(pinds[0]), nodeVec_ACCESS(pinds[1]), + nodeVec_ACCESS(pinds[2])); + } if (!edge) { - if ( !comment.size() ) comment << "Cannot create a mesh edge"; + if ( comment.empty() ) comment << "Cannot create a mesh edge"; MESSAGE("Cannot create a mesh edge"); - nbSeg = nbFac = nbVol = isOK = 0; + nbSeg = nbFac = nbVol = 0; break; } - if (!aEdge.IsNull()) + if ( !aEdge.IsNull() && edge->getshapeId() < 1 ) meshDS->SetMeshElementOnShape(edge, aEdge); } + else if ( comment.empty() ) + { + comment << "Invalid netgen segment #" << i; + } + } + + // ---------------------------------------- + // Create mesh faces along geometric faces + // ---------------------------------------- + + int nbInitFac = initState._nbFaces; + int quadFaceID = ngMesh.GetNFD() + 1; + if ( nbInitFac < nbFac ) + // add a faces descriptor to exclude qudrangle elements generated by NETGEN + // from computation of 3D mesh + ngMesh.AddFaceDescriptor (netgen::FaceDescriptor(quadFaceID, /*solid1=*/0, /*solid2=*/0, 0)); - // create mesh faces along geometric faces - for (i = nbInitFac+1; i <= nbFac/* && isOK*/; ++i ) + for (i = nbInitFac+1; i <= nbFac; ++i ) + { + const netgen::Element2d& elem = ngMesh.SurfaceElement(i); + int aGeomFaceInd = elem.GetIndex(); + TopoDS_Face aFace; + if (aGeomFaceInd > 0 && aGeomFaceInd <= occgeo.fmap.Extent()) + aFace = TopoDS::Face(occgeo.fmap(aGeomFaceInd)); + vector nodes; + for (int j=1; j <= elem.GetNP(); ++j) { - const netgen::Element2d& elem = ngMesh->SurfaceElement(i); - int aGeomFaceInd = elem.GetIndex(); - TopoDS_Face aFace; - if (aGeomFaceInd > 0 && aGeomFaceInd <= occgeo.fmap.Extent()) - aFace = TopoDS::Face(occgeo.fmap(aGeomFaceInd)); - vector nodes; - for (int j=1; j <= elem.GetNP(); ++j) + int pind = elem.PNum(j); + if ( pind < 1 || pind >= nodeVec.size() ) + break; + if ( SMDS_MeshNode* node = nodeVec_ACCESS(pind)) { - int pind = elem.PNum(j); - SMDS_MeshNode* node = nodeVec.at(pind); nodes.push_back(node); - if (pind <= nbInitNod || pindMap.Contains(pind)) - continue; - if (!aFace.IsNull()) + if (!aFace.IsNull() && node->getshapeId() < 1) { const netgen::PointGeomInfo& pgi = elem.GeomInfoPi(j); meshDS->SetNodeOnFace(node, aFace, pgi.u, pgi.v); - pindMap.Add(pind); } } - SMDS_MeshFace* face = NULL; - switch (elem.GetType()) - { - case netgen::TRIG: - face = meshDS->AddFace(nodes[0],nodes[1],nodes[2]); - break; - case netgen::QUAD: - face = meshDS->AddFace(nodes[0],nodes[1],nodes[2],nodes[3]); - break; - case netgen::TRIG6: - face = meshDS->AddFace(nodes[0],nodes[1],nodes[2],nodes[5],nodes[3],nodes[4]); - break; - case netgen::QUAD8: - face = meshDS->AddFace(nodes[0],nodes[1],nodes[2],nodes[3], - nodes[4],nodes[7],nodes[5],nodes[6]); - break; - default: - MESSAGE("NETGEN created a face of unexpected type, ignoring"); - continue; - } - if (!face) - { - if ( !comment.size() ) comment << "Cannot create a mesh face"; - MESSAGE("Cannot create a mesh face"); - nbSeg = nbFac = nbVol = isOK = 0; - break; - } - if (!aFace.IsNull()) - meshDS->SetMeshElementOnShape(face, aFace); } + if ( nodes.size() != elem.GetNP() ) + { + if ( comment.empty() ) + comment << "Invalid netgen 2d element #" << i; + continue; // bad node ids + } + SMDS_MeshFace* face = NULL; + switch (elem.GetType()) + { + case netgen::TRIG: + face = meshDS->AddFace(nodes[0],nodes[1],nodes[2]); + break; + case netgen::QUAD: + face = meshDS->AddFace(nodes[0],nodes[1],nodes[2],nodes[3]); + // exclude qudrangle elements from computation of 3D mesh + const_cast< netgen::Element2d& >( elem ).SetIndex( quadFaceID ); + break; + case netgen::TRIG6: + face = meshDS->AddFace(nodes[0],nodes[1],nodes[2],nodes[5],nodes[3],nodes[4]); + break; + case netgen::QUAD8: + face = meshDS->AddFace(nodes[0],nodes[1],nodes[2],nodes[3], + nodes[4],nodes[7],nodes[5],nodes[6]); + // exclude qudrangle elements from computation of 3D mesh + const_cast< netgen::Element2d& >( elem ).SetIndex( quadFaceID ); + break; + default: + MESSAGE("NETGEN created a face of unexpected type, ignoring"); + continue; + } + if (!face) + { + if ( comment.empty() ) comment << "Cannot create a mesh face"; + MESSAGE("Cannot create a mesh face"); + nbSeg = nbFac = nbVol = 0; + break; + } + if (!aFace.IsNull()) + meshDS->SetMeshElementOnShape(face, aFace); + } - // create tetrahedra - for (i = 1; i <= nbVol/* && isOK*/; ++i) + // ------------------ + // Create tetrahedra + // ------------------ + + for (i = 1; i <= nbVol; ++i) + { + const netgen::Element& elem = ngMesh.VolumeElement(i); + int aSolidInd = elem.GetIndex(); + TopoDS_Solid aSolid; + if (aSolidInd > 0 && aSolidInd <= occgeo.somap.Extent()) + aSolid = TopoDS::Solid(occgeo.somap(aSolidInd)); + vector nodes; + for (int j=1; j <= elem.GetNP(); ++j) { - const netgen::Element& elem = ngMesh->VolumeElement(i); - int aSolidInd = elem.GetIndex(); - TopoDS_Solid aSolid; - if (aSolidInd > 0 && aSolidInd <= occgeo.somap.Extent()) - aSolid = TopoDS::Solid(occgeo.somap(aSolidInd)); - vector nodes; - for (int j=1; j <= elem.GetNP(); ++j) + int pind = elem.PNum(j); + if ( pind < 1 || pind >= nodeVec.size() ) + break; + if ( SMDS_MeshNode* node = nodeVec_ACCESS(pind) ) { - int pind = elem.PNum(j); - SMDS_MeshNode* node = nodeVec.at(pind); nodes.push_back(node); - if (pind <= nbInitNod || pindMap.Contains(pind)) - continue; - if (!aSolid.IsNull()) - { - // point in solid + if ( !aSolid.IsNull() && node->getshapeId() < 1 ) meshDS->SetNodeInVolume(node, aSolid); - pindMap.Add(pind); - } - } - SMDS_MeshVolume* vol = NULL; - switch (elem.GetType()) - { - case netgen::TET: - vol = meshDS->AddVolume(nodes[0],nodes[1],nodes[2],nodes[3]); - break; - case netgen::TET10: - vol = meshDS->AddVolume(nodes[0],nodes[1],nodes[2],nodes[3], - nodes[4],nodes[7],nodes[5],nodes[6],nodes[8],nodes[9]); - break; - default: - MESSAGE("NETGEN created a volume of unexpected type, ignoring"); - continue; } - if (!vol) + } + if ( nodes.size() != elem.GetNP() ) + { + if ( comment.empty() ) + comment << "Invalid netgen 3d element #" << i; + continue; + } + SMDS_MeshVolume* vol = NULL; + switch (elem.GetType()) + { + case netgen::TET: + vol = meshDS->AddVolume(nodes[0],nodes[1],nodes[2],nodes[3]); + break; + case netgen::TET10: + vol = meshDS->AddVolume(nodes[0],nodes[1],nodes[2],nodes[3], + nodes[4],nodes[7],nodes[5],nodes[6],nodes[8],nodes[9]); + break; + default: + MESSAGE("NETGEN created a volume of unexpected type, ignoring"); + continue; + } + if (!vol) + { + if ( comment.empty() ) comment << "Cannot create a mesh volume"; + MESSAGE("Cannot create a mesh volume"); + nbSeg = nbFac = nbVol = 0; + break; + } + if (!aSolid.IsNull()) + meshDS->SetMeshElementOnShape(vol, aSolid); + } + return comment.empty() ? 0 : 1; +} + +namespace +{ + //================================================================================ + /*! + * \brief Restrict size of elements on the given edge + */ + //================================================================================ + + void setLocalSize(const TopoDS_Edge& edge, + double size, + netgen::Mesh& mesh) + { + const int nb = 1000; + Standard_Real u1, u2; + Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, u1, u2); + if ( curve.IsNull() ) + { + TopoDS_Iterator vIt( edge ); + if ( !vIt.More() ) return; + gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( vIt.Value() )); + NETGENPlugin_Mesher::RestrictLocalSize( mesh, p.XYZ(), size ); + } + else + { + Standard_Real delta = (u2-u1)/nb; + for(int i=0; iValue(u); + NETGENPlugin_Mesher::RestrictLocalSize( mesh, p.XYZ(), size ); + netgen::Point3d pi(p.X(), p.Y(), p.Z()); + double resultSize = mesh.GetH(pi); + if ( resultSize - size > 0.1*size ) + // netgen does restriction iff oldH/newH > 1.2 (localh.cpp:136) + NETGENPlugin_Mesher::RestrictLocalSize( mesh, p.XYZ(), resultSize/1.201 ); } - if (!aSolid.IsNull()) - meshDS->SetMeshElementOnShape(vol, aSolid); } } - if ( error->IsOK() && ( !isOK || comment.size() > 0 )) - error->myName = COMPERR_ALGO_FAILED; - if ( !comment.empty() ) - error->myComment = comment; + //================================================================================ + /*! + * \brief Convert error into text + */ + //================================================================================ - // set bad compute error to subshapes of all failed subshapes shapes - if ( !error->IsOK() && err ) + std::string text(int err) { - for (int i = 1; i <= occgeo.fmap.Extent(); i++) { - int status = occgeo.facemeshstatus[i-1]; - if (status == 1 ) continue; - if ( SMESH_subMesh* sm = _mesh->GetSubMeshContaining( occgeo.fmap( i ))) { - SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); - if ( !smError || smError->IsOK() ) { - if ( status == -1 ) - smError.reset( new SMESH_ComputeError( error->myName, error->myComment )); - else - smError.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED, "Ignored" )); - } - } - } + if ( !err ) + return string(""); + return + SMESH_Comment("Error in netgen::OCCGenerateMesh() at ") << netgen::multithread.task; } - nglib::Ng_DeleteMesh((nglib::Ng_Mesh*)ngMesh); - nglib::Ng_Exit(); + //================================================================================ + /*! + * \brief Convert exception into text + */ + //================================================================================ - RemoveTmpFiles(); + std::string text(Standard_Failure& ex) + { + SMESH_Comment str("Exception in netgen::OCCGenerateMesh()"); + str << " at " << netgen::multithread.task + << ": " << ex.DynamicType()->Name(); + if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) + str << ": " << ex.GetMessageString(); + return str; + } + //================================================================================ + /*! + * \brief Convert exception into text + */ + //================================================================================ - return error->IsOK(); + std::string text(netgen::NgException& ex) + { + SMESH_Comment str("NgException"); + str << " at " << netgen::multithread.task << ": " << ex.What(); + return str; + } } -//================================================================================ +//============================================================================= /*! - * \brief Remove "test.out" and "problemfaces" files in current directory + * Here we are going to use the NETGEN mesher */ -//================================================================================ +//============================================================================= -void NETGENPlugin_Mesher::RemoveTmpFiles() +bool NETGENPlugin_Mesher::Compute() +{ + NETGENPlugin_NetgenLibWrapper ngLib; + + netgen::MeshingParameters& mparams = netgen::mparam; + MESSAGE("Compute with:\n" + " max size = " << mparams.maxh << "\n" + " segments per edge = " << mparams.segmentsperedge); + MESSAGE("\n" + " growth rate = " << mparams.grading << "\n" + " elements per radius = " << mparams.curvaturesafety << "\n" + " second order = " << mparams.secondorder << "\n" + " quad allowed = " << mparams.quad); + cout << " quad allowed = " << mparams.quad< meshedSM[3]; // for 0-2 dimensions + NETGENPlugin_Internals internals( *_mesh, _shape, _isVolume ); + PrepareOCCgeometry( occgeo, _shape, *_mesh, meshedSM, &internals ); + + // ------------------------- + // Generate the mesh + // ------------------------- + + netgen::Mesh *ngMesh = NULL; + NETGENPlugin_ngMeshInfo initState; // it remembers size of ng mesh equal to size of Smesh + + SMESH_Comment comment; + int err = 0; + + // vector of nodes in which node index == netgen ID + vector< const SMDS_MeshNode* > nodeVec; + + { + // ---------------- + // compute 1D mesh + // ---------------- + if ( _simpleHyp ) + { + // not to RestrictLocalH() according to curvature during MESHCONST_ANALYSE + mparams.uselocalh = false; + mparams.grading = 0.8; // not limitited size growth + + if ( _simpleHyp->GetNumberOfSegments() ) + // nb of segments + mparams.maxh = occgeo.boundingbox.Diam(); + else + // segment length + mparams.maxh = _simpleHyp->GetLocalLength(); + } + + if ( mparams.maxh == 0.0 ) + mparams.maxh = occgeo.boundingbox.Diam(); + if ( _simpleHyp || ( mparams.minh == 0.0 && _fineness != NETGENPlugin_Hypothesis::UserDefined)) + mparams.minh = GetDefaultMinSize( _shape, mparams.maxh ); + +#ifdef NETGEN_NEW + // Local size on faces + occgeo.face_maxh = mparams.maxh; +#endif + + // Let netgen create ngMesh and calculate element size on not meshed shapes + char *optstr = 0; + int startWith = netgen::MESHCONST_ANALYSE; + int endWith = netgen::MESHCONST_ANALYSE; + try + { + OCC_CATCH_SIGNALS; + err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr); +#ifdef WITH_SMESH_CANCEL_COMPUTE + if(netgen::multithread.terminate) + return false; +#endif + comment << text(err); + } + catch (Standard_Failure& ex) + { + comment << text(ex); + } + err = 0; //- MESHCONST_ANALYSE isn't so important step + if ( !ngMesh ) + return false; + ngLib.setMesh(( Ng_Mesh*) ngMesh ); + + ngMesh->ClearFaceDescriptors(); // we make descriptors our-self + + if ( _simpleHyp ) + { + // Pass 1D simple parameters to NETGEN + // -------------------------------- + int nbSeg = _simpleHyp->GetNumberOfSegments(); + double segSize = _simpleHyp->GetLocalLength(); + for ( int iE = 1; iE <= occgeo.emap.Extent(); ++iE ) + { + const TopoDS_Edge& e = TopoDS::Edge( occgeo.emap(iE)); + if ( nbSeg ) + segSize = SMESH_Algo::EdgeLength( e ) / ( nbSeg - 0.4 ); + setLocalSize( e, segSize, *ngMesh ); + } + } + else // if ( ! _simpleHyp ) + { + // Local size on vertices and edges + // -------------------------------- + for(std::map::const_iterator it=EdgeId2LocalSize.begin(); it!=EdgeId2LocalSize.end(); it++) + { + int key = (*it).first; + double hi = (*it).second; + const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key); + const TopoDS_Edge& e = TopoDS::Edge(shape); + setLocalSize( e, hi, *ngMesh ); + } + for(std::map::const_iterator it=VertexId2LocalSize.begin(); it!=VertexId2LocalSize.end(); it++) + { + int key = (*it).first; + double hi = (*it).second; + const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key); + const TopoDS_Vertex& v = TopoDS::Vertex(shape); + gp_Pnt p = BRep_Tool::Pnt(v); + NETGENPlugin_Mesher::RestrictLocalSize( *ngMesh, p.XYZ(), hi ); + } + for(map::const_iterator it=FaceId2LocalSize.begin(); + it!=FaceId2LocalSize.end(); it++) + { + int key = (*it).first; + double val = (*it).second; + const TopoDS_Shape& shape = ShapesWithLocalSize.FindKey(key); + int faceNgID = occgeo.fmap.FindIndex(shape); + occgeo.SetFaceMaxH(faceNgID, val); + for ( TopExp_Explorer edgeExp( shape, TopAbs_EDGE ); edgeExp.More(); edgeExp.Next() ) + setLocalSize( TopoDS::Edge( edgeExp.Current() ), val, *ngMesh ); + } + } + + // Precompute internal edges (issue 0020676) in order to + // add mesh on them correctly (twice) to netgen mesh + if ( !err && internals.hasInternalEdges() ) + { + // load internal shapes into OCCGeometry + netgen::OCCGeometry intOccgeo; + internals.getInternalEdges( intOccgeo.fmap, intOccgeo.emap, intOccgeo.vmap, meshedSM ); + intOccgeo.boundingbox = occgeo.boundingbox; + intOccgeo.shape = occgeo.shape; +#ifdef NETGEN_NEW + intOccgeo.face_maxh.SetSize(intOccgeo.fmap.Extent()); + intOccgeo.face_maxh = netgen::mparam.maxh; +#endif + netgen::Mesh *tmpNgMesh = NULL; + try + { + OCC_CATCH_SIGNALS; + // compute local H on internal shapes in the main mesh + //OCCSetLocalMeshSize(intOccgeo, *ngMesh); it deletes ngMesh->localH + + // let netgen create a temporary mesh + netgen::OCCGenerateMesh(intOccgeo, tmpNgMesh, startWith, endWith, optstr); +#ifdef WITH_SMESH_CANCEL_COMPUTE + if(netgen::multithread.terminate) + return false; +#endif + // copy LocalH from the main to temporary mesh + initState.transferLocalH( ngMesh, tmpNgMesh ); + + // compute mesh on internal edges + startWith = endWith = netgen::MESHCONST_MESHEDGES; + err = netgen::OCCGenerateMesh(intOccgeo, tmpNgMesh, startWith, endWith, optstr); + comment << text(err); + } + catch (Standard_Failure& ex) + { + comment << text(ex); + err = 1; + } + initState.restoreLocalH( tmpNgMesh ); + + // fill SMESH by netgen mesh + vector< const SMDS_MeshNode* > tmpNodeVec; + FillSMesh( intOccgeo, *tmpNgMesh, initState, *_mesh, tmpNodeVec, comment ); + err = ( err || !comment.empty() ); + + nglib::Ng_DeleteMesh((nglib::Ng_Mesh*)tmpNgMesh); + } + + // Fill ngMesh with nodes and segments of computed submeshes + if ( !err ) + { + _faceDescriptors.clear(); + err = ! ( fillNgMesh(occgeo, *ngMesh, nodeVec, meshedSM[ MeshDim_0D ]) && + fillNgMesh(occgeo, *ngMesh, nodeVec, meshedSM[ MeshDim_1D ])); + } + initState = NETGENPlugin_ngMeshInfo(ngMesh); + + // Compute 1d mesh + if (!err) + { + startWith = endWith = netgen::MESHCONST_MESHEDGES; + try + { + OCC_CATCH_SIGNALS; + err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr); +#ifdef WITH_SMESH_CANCEL_COMPUTE + if(netgen::multithread.terminate) + return false; +#endif + comment << text(err); + } + catch (Standard_Failure& ex) + { + comment << text(ex); + err = 1; + } + } + mparams.uselocalh = true; // restore as it is used at surface optimization + + // --------------------- + // compute surface mesh + // --------------------- + if (!err) + { + // Pass 2D simple parameters to NETGEN + if ( _simpleHyp ) { + if ( double area = _simpleHyp->GetMaxElementArea() ) { + // face area + mparams.maxh = sqrt(2. * area/sqrt(3.0)); + mparams.grading = 0.4; // moderate size growth + } + else { + // length from edges + if ( ngMesh->GetNSeg() ) { + double edgeLength = 0; + TopTools_MapOfShape visitedEdges; + for ( TopExp_Explorer exp( _shape, TopAbs_EDGE ); exp.More(); exp.Next() ) + if( visitedEdges.Add(exp.Current()) ) + edgeLength += SMESH_Algo::EdgeLength( TopoDS::Edge( exp.Current() )); + // we have to multiply length by 2 since for each TopoDS_Edge there + // are double set of NETGEN edges, in other words, we have to + // divide ngMesh->GetNSeg() by 2. + mparams.maxh = 2*edgeLength / ngMesh->GetNSeg(); + } + else { + mparams.maxh = 1000; + } + mparams.grading = 0.2; // slow size growth + } + mparams.quad = _simpleHyp->GetAllowQuadrangles(); + mparams.maxh = min( mparams.maxh, occgeo.boundingbox.Diam()/2 ); + ngMesh->SetGlobalH (mparams.maxh); + netgen::Box<3> bb = occgeo.GetBoundingBox(); + bb.Increase (bb.Diam()/20); + ngMesh->SetLocalH (bb.PMin(), bb.PMax(), mparams.grading); + } + + // Care of vertices internal in faces (issue 0020676) + if ( internals.hasInternalVertexInFace() ) + { + // store computed segments in SMESH in order not to create SMESH + // edges for ng segments added by addIntVerticesInFaces() + FillSMesh( occgeo, *ngMesh, initState, *_mesh, nodeVec, comment ); + // add segments to faces with internal vertices + addIntVerticesInFaces( occgeo, *ngMesh, nodeVec, internals ); + initState = NETGENPlugin_ngMeshInfo(ngMesh); + } + + // Let netgen compute 2D mesh + startWith = netgen::MESHCONST_MESHSURFACE; + endWith = _optimize ? netgen::MESHCONST_OPTSURFACE : netgen::MESHCONST_MESHSURFACE; + try + { + OCC_CATCH_SIGNALS; + err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr); +#ifdef WITH_SMESH_CANCEL_COMPUTE + if(netgen::multithread.terminate) + return false; +#endif + comment << text (err); + } + catch (Standard_Failure& ex) + { + comment << text(ex); + //err = 1; -- try to make volumes anyway + } + catch (netgen::NgException exc) + { + comment << text(exc); + //err = 1; -- try to make volumes anyway + } + } + // --------------------- + // generate volume mesh + // --------------------- + // Fill ngMesh with nodes and faces of computed 2D submeshes + if ( !err && _isVolume && ( !meshedSM[ MeshDim_2D ].empty() || mparams.quad )) + { + // load SMESH with computed segments and faces + FillSMesh( occgeo, *ngMesh, initState, *_mesh, nodeVec, comment ); + + // compute pyramids on quadrangles + SMESH_ProxyMesh::Ptr proxyMesh; + if ( _mesh->NbQuadrangles() > 0 ) + for ( int iS = 1; iS <= occgeo.somap.Extent(); ++iS ) + { + StdMeshers_QuadToTriaAdaptor* Adaptor = new StdMeshers_QuadToTriaAdaptor; + proxyMesh.reset( Adaptor ); + + int nbPyrams = _mesh->NbPyramids(); + Adaptor->Compute( *_mesh, occgeo.somap(iS) ); + if ( nbPyrams != _mesh->NbPyramids() ) + { + list< SMESH_subMesh* > quadFaceSM; + for (TopExp_Explorer face(occgeo.somap(iS), TopAbs_FACE); face.More(); face.Next()) + if ( Adaptor->GetProxySubMesh( face.Current() )) + { + quadFaceSM.push_back( _mesh->GetSubMesh( face.Current() )); + meshedSM[ MeshDim_2D ].remove( quadFaceSM.back() ); + } + fillNgMesh(occgeo, *ngMesh, nodeVec, quadFaceSM, proxyMesh); + } + } + // fill ngMesh with faces of sub-meshes + err = ! ( fillNgMesh(occgeo, *ngMesh, nodeVec, meshedSM[ MeshDim_2D ])); + initState = NETGENPlugin_ngMeshInfo(ngMesh); + //toPython( ngMesh, "/tmp/ngPython.py"); + } + if (!err && _isVolume) + { + // Pass 3D simple parameters to NETGEN + const NETGENPlugin_SimpleHypothesis_3D* simple3d = + dynamic_cast< const NETGENPlugin_SimpleHypothesis_3D* > ( _simpleHyp ); + if ( simple3d ) { + if ( double vol = simple3d->GetMaxElementVolume() ) { + // max volume + mparams.maxh = pow( 72, 1/6. ) * pow( vol, 1/3. ); + mparams.maxh = min( mparams.maxh, occgeo.boundingbox.Diam()/2 ); + } + else { + // length from faces + mparams.maxh = ngMesh->AverageH(); + } + ngMesh->SetGlobalH (mparams.maxh); + mparams.grading = 0.4; + ngMesh->CalcLocalH(); + } + // Care of vertices internal in solids and internal faces (issue 0020676) + if ( internals.hasInternalVertexInSolid() || internals.hasInternalFaces() ) + { + // store computed faces in SMESH in order not to create SMESH + // faces for ng faces added here + FillSMesh( occgeo, *ngMesh, initState, *_mesh, nodeVec, comment ); + // add ng faces to solids with internal vertices + addIntVerticesInSolids( occgeo, *ngMesh, nodeVec, internals ); + // duplicate mesh faces on internal faces + fixIntFaces( occgeo, *ngMesh, internals ); + initState = NETGENPlugin_ngMeshInfo(ngMesh); + } + // Let netgen compute 3D mesh + startWith = endWith = netgen::MESHCONST_MESHVOLUME; + try + { + OCC_CATCH_SIGNALS; + err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr); +#ifdef WITH_SMESH_CANCEL_COMPUTE + if(netgen::multithread.terminate) + return false; +#endif + if ( comment.empty() ) // do not overwrite a previos error + comment << text(err); + } + catch (Standard_Failure& ex) + { + if ( comment.empty() ) // do not overwrite a previos error + comment << text(ex); + err = 1; + } + catch (netgen::NgException exc) + { + if ( comment.empty() ) // do not overwrite a previos error + comment << text(exc); + err = 1; + } + // Let netgen optimize 3D mesh + if ( !err && _optimize ) + { + startWith = endWith = netgen::MESHCONST_OPTVOLUME; + try + { + OCC_CATCH_SIGNALS; + err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr); +#ifdef WITH_SMESH_CANCEL_COMPUTE + if(netgen::multithread.terminate) + return false; +#endif + if ( comment.empty() ) // do not overwrite a previos error + comment << text(err); + } + catch (Standard_Failure& ex) + { + if ( comment.empty() ) // do not overwrite a previos error + comment << text(ex); + } + catch (netgen::NgException exc) + { + if ( comment.empty() ) // do not overwrite a previos error + comment << text(exc); + } + } + } + if (!err && mparams.secondorder > 0) + { + try + { + OCC_CATCH_SIGNALS; + netgen::OCCRefinementSurfaces ref (occgeo); + ref.MakeSecondOrder (*ngMesh); + } + catch (Standard_Failure& ex) + { + if ( comment.empty() ) // do not overwrite a previos error + comment << "Exception in netgen at passing to 2nd order "; + } + catch (netgen::NgException exc) + { + if ( comment.empty() ) // do not overwrite a previos error + comment << exc.What(); + } + } + } + int nbNod = ngMesh->GetNP(); + int nbSeg = ngMesh->GetNSeg(); + int nbFac = ngMesh->GetNSE(); + int nbVol = ngMesh->GetNE(); + bool isOK = ( !err && (_isVolume ? (nbVol > 0) : (nbFac > 0)) ); + + MESSAGE((err ? "Mesh Generation failure" : "End of Mesh Generation") << + ", nb nodes: " << nbNod << + ", nb segments: " << nbSeg << + ", nb faces: " << nbFac << + ", nb volumes: " << nbVol); + + // Feed back the SMESHDS with the generated Nodes and Elements + if ( true /*isOK*/ ) // get whatever built + FillSMesh( occgeo, *ngMesh, initState, *_mesh, nodeVec, comment ); //!< + + SMESH_ComputeErrorPtr readErr = readErrors(nodeVec); + if ( readErr && !readErr->myBadElements.empty() ) + error = readErr; + + if ( error->IsOK() && ( !isOK || comment.size() > 0 )) + error->myName = COMPERR_ALGO_FAILED; + if ( !comment.empty() ) + error->myComment = comment; + + // SetIsAlwaysComputed( true ) to empty sub-meshes, which + // appear if the geometry contains coincident sub-shape due + // to bool merge_solids = 1; in netgen/libsrc/occ/occgenmesh.cpp + const int nbMaps = 2; + const TopTools_IndexedMapOfShape* geoMaps[nbMaps] = + { & occgeo.vmap, & occgeo.emap/*, & occgeo.fmap*/ }; + for ( int iMap = 0; iMap < nbMaps; ++iMap ) + for (int i = 1; i <= geoMaps[iMap]->Extent(); i++) + if ( SMESH_subMesh* sm = _mesh->GetSubMeshContaining( geoMaps[iMap]->FindKey(i))) + if ( !sm->IsMeshComputed() ) + sm->SetIsAlwaysComputed( true ); + + // set bad compute error to subshapes of all failed sub-shapes + if ( !error->IsOK() ) + { + bool pb2D = false, pb3D = false; + for (int i = 1; i <= occgeo.fmap.Extent(); i++) { + int status = occgeo.facemeshstatus[i-1]; + if (status == 1 ) continue; + if ( SMESH_subMesh* sm = _mesh->GetSubMeshContaining( occgeo.fmap( i ))) { + SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); + if ( !smError || smError->IsOK() ) { + if ( status == -1 ) + smError.reset( new SMESH_ComputeError( *error )); + else + smError.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED, "Ignored" )); + if ( SMESH_Algo::GetMeshError( sm ) == SMESH_Algo::MEr_OK ) + smError->myName = COMPERR_WARNING; + } + pb2D = pb2D || smError->IsKO(); + } + } + if ( !pb2D ) // all faces are OK + for (int i = 1; i <= occgeo.somap.Extent(); i++) + if ( SMESH_subMesh* sm = _mesh->GetSubMeshContaining( occgeo.somap( i ))) + { + bool smComputed = nbVol && !sm->IsEmpty(); + if ( smComputed && internals.hasInternalVertexInSolid( sm->GetId() )) + { + int nbIntV = internals.getSolidsWithVertices().find( sm->GetId() )->second.size(); + SMESHDS_SubMesh* smDS = sm->GetSubMeshDS(); + smComputed = ( smDS->NbElements() > 0 || smDS->NbNodes() > nbIntV ); + } + SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); + if ( !smComputed && ( !smError || smError->IsOK() )) + { + smError.reset( new SMESH_ComputeError( *error )); + if ( nbVol && SMESH_Algo::GetMeshError( sm ) == SMESH_Algo::MEr_OK ) + smError->myName = COMPERR_WARNING; + } + pb3D = pb3D || ( smError && smError->IsKO() ); + } + if ( !pb2D && !pb3D ) + err = 0; // no fatal errors, only warnings + } + + return !err; +} + +//============================================================================= +/*! + * Evaluate + */ +//============================================================================= +bool NETGENPlugin_Mesher::Evaluate(MapShapeNbElems& aResMap) +{ + netgen::MeshingParameters& mparams = netgen::mparam; + + + // ------------------------- + // Prepare OCC geometry + // ------------------------- + netgen::OCCGeometry occgeo; + PrepareOCCgeometry( occgeo, _shape, *_mesh ); + + bool tooManyElems = false; + const int hugeNb = std::numeric_limits::max() / 100; + + // ---------------- + // evaluate 1D + // ---------------- + // pass 1D simple parameters to NETGEN + if ( _simpleHyp ) { + if ( int nbSeg = _simpleHyp->GetNumberOfSegments() ) { + // nb of segments + mparams.segmentsperedge = nbSeg + 0.1; + mparams.maxh = occgeo.boundingbox.Diam(); + mparams.minh = GetDefaultMinSize( _shape, mparams.maxh ); + mparams.grading = 0.01; + } + else { + // segment length + mparams.segmentsperedge = 1; + mparams.maxh = _simpleHyp->GetLocalLength(); + } + } + // let netgen create ngMesh and calculate element size on not meshed shapes + NETGENPlugin_NetgenLibWrapper ngLib; + netgen::Mesh *ngMesh = NULL; + char *optstr = 0; + int startWith = netgen::MESHCONST_ANALYSE; + int endWith = netgen::MESHCONST_MESHEDGES; + int err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr); +#ifdef WITH_SMESH_CANCEL_COMPUTE + if(netgen::multithread.terminate) + return false; +#endif + ngLib.setMesh(( Ng_Mesh*) ngMesh ); + if (err) { + if ( SMESH_subMesh* sm = _mesh->GetSubMeshContaining( _shape )) + sm->GetComputeError().reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED )); + return false; + } + + // calculate total nb of segments and length of edges + double fullLen = 0.0; + int fullNbSeg = 0; + int entity = mparams.secondorder > 0 ? SMDSEntity_Quad_Edge : SMDSEntity_Edge; + TopTools_DataMapOfShapeInteger Edge2NbSeg; + for (TopExp_Explorer exp(_shape, TopAbs_EDGE); exp.More(); exp.Next()) + { + TopoDS_Edge E = TopoDS::Edge( exp.Current() ); + if( !Edge2NbSeg.Bind(E,0) ) + continue; + + double aLen = SMESH_Algo::EdgeLength(E); + fullLen += aLen; + + vector& aVec = aResMap[_mesh->GetSubMesh(E)]; + if ( aVec.empty() ) + aVec.resize( SMDSEntity_Last, 0); + else + fullNbSeg += aVec[ entity ]; + } + + // store nb of segments computed by Netgen + NCollection_Map linkMap; + for (int i = 1; i <= ngMesh->GetNSeg(); ++i ) + { + const netgen::Segment& seg = ngMesh->LineSegment(i); + Link link(seg[0], seg[1]); + if ( !linkMap.Add( link )) continue; + int aGeomEdgeInd = seg.epgeominfo[0].edgenr; + if (aGeomEdgeInd > 0 && aGeomEdgeInd <= occgeo.emap.Extent()) + { + vector& aVec = aResMap[_mesh->GetSubMesh(occgeo.emap(aGeomEdgeInd))]; + aVec[ entity ]++; + } + } + // store nb of nodes on edges computed by Netgen + TopTools_DataMapIteratorOfDataMapOfShapeInteger Edge2NbSegIt(Edge2NbSeg); + for (; Edge2NbSegIt.More(); Edge2NbSegIt.Next()) + { + vector& aVec = aResMap[_mesh->GetSubMesh(Edge2NbSegIt.Key())]; + if ( aVec[ entity ] > 1 && aVec[ SMDSEntity_Node ] == 0 ) + aVec[SMDSEntity_Node] = mparams.secondorder > 0 ? 2*aVec[ entity ]-1 : aVec[ entity ]-1; + + fullNbSeg += aVec[ entity ]; + Edge2NbSeg( Edge2NbSegIt.Key() ) = aVec[ entity ]; + } + + // ---------------- + // evaluate 2D + // ---------------- + if ( _simpleHyp ) { + if ( double area = _simpleHyp->GetMaxElementArea() ) { + // face area + mparams.maxh = sqrt(2. * area/sqrt(3.0)); + mparams.grading = 0.4; // moderate size growth + } + else { + // length from edges + mparams.maxh = fullLen/fullNbSeg; + mparams.grading = 0.2; // slow size growth + } + } + mparams.maxh = min( mparams.maxh, occgeo.boundingbox.Diam()/2 ); + mparams.maxh = min( mparams.maxh, fullLen/fullNbSeg * (1. + mparams.grading)); + + for (TopExp_Explorer exp(_shape, TopAbs_FACE); exp.More(); exp.Next()) + { + TopoDS_Face F = TopoDS::Face( exp.Current() ); + SMESH_subMesh *sm = _mesh->GetSubMesh(F); + GProp_GProps G; + BRepGProp::SurfaceProperties(F,G); + double anArea = G.Mass(); + tooManyElems = tooManyElems || ( anArea/hugeNb > mparams.maxh*mparams.maxh ); + int nb1d = 0; + if ( !tooManyElems ) + { + TopTools_MapOfShape egdes; + for (TopExp_Explorer exp1(F,TopAbs_EDGE); exp1.More(); exp1.Next()) + if ( egdes.Add( exp1.Current() )) + nb1d += Edge2NbSeg.Find(exp1.Current()); + } + int nbFaces = tooManyElems ? hugeNb : int( 4*anArea / (mparams.maxh*mparams.maxh*sqrt(3.))); + int nbNodes = tooManyElems ? hugeNb : (( nbFaces*3 - (nb1d-1)*2 ) / 6 + 1 ); + + vector aVec(SMDSEntity_Last, 0); + if( mparams.secondorder > 0 ) { + int nb1d_in = (nbFaces*3 - nb1d) / 2; + aVec[SMDSEntity_Node] = nbNodes + nb1d_in; + aVec[SMDSEntity_Quad_Triangle] = nbFaces; + } + else { + aVec[SMDSEntity_Node] = Max ( nbNodes, 0 ); + aVec[SMDSEntity_Triangle] = nbFaces; + } + aResMap[sm].swap(aVec); + } + + // ---------------- + // evaluate 3D + // ---------------- + if(_isVolume) { + // pass 3D simple parameters to NETGEN + const NETGENPlugin_SimpleHypothesis_3D* simple3d = + dynamic_cast< const NETGENPlugin_SimpleHypothesis_3D* > ( _simpleHyp ); + if ( simple3d ) { + if ( double vol = simple3d->GetMaxElementVolume() ) { + // max volume + mparams.maxh = pow( 72, 1/6. ) * pow( vol, 1/3. ); + mparams.maxh = min( mparams.maxh, occgeo.boundingbox.Diam()/2 ); + } + else { + // using previous length from faces + } + mparams.grading = 0.4; + mparams.maxh = min( mparams.maxh, fullLen/fullNbSeg * (1. + mparams.grading)); + } + GProp_GProps G; + BRepGProp::VolumeProperties(_shape,G); + double aVolume = G.Mass(); + double tetrVol = 0.1179*mparams.maxh*mparams.maxh*mparams.maxh; + tooManyElems = tooManyElems || ( aVolume/hugeNb > tetrVol ); + int nbVols = tooManyElems ? hugeNb : int(aVolume/tetrVol); + int nb1d_in = int(( nbVols*6 - fullNbSeg ) / 6 ); + vector aVec(SMDSEntity_Last, 0 ); + if ( tooManyElems ) // avoid FPE + { + aVec[SMDSEntity_Node] = hugeNb; + aVec[ mparams.secondorder > 0 ? SMDSEntity_Quad_Tetra : SMDSEntity_Tetra] = hugeNb; + } + else + { + if( mparams.secondorder > 0 ) { + aVec[SMDSEntity_Node] = nb1d_in/3 + 1 + nb1d_in; + aVec[SMDSEntity_Quad_Tetra] = nbVols; + } + else { + aVec[SMDSEntity_Node] = nb1d_in/3 + 1; + aVec[SMDSEntity_Tetra] = nbVols; + } + } + SMESH_subMesh *sm = _mesh->GetSubMesh(_shape); + aResMap[sm].swap(aVec); + } + + return true; +} + +//================================================================================ +/*! + * \brief Remove "test.out" and "problemfaces" files in current directory + */ +//================================================================================ + +void NETGENPlugin_Mesher::RemoveTmpFiles() +{ + if ( SMESH_File("test.out").remove() && netgen::testout) + { + delete netgen::testout; + netgen::testout = 0; + } + SMESH_File("problemfaces").remove(); + SMESH_File("occmesh.rep").remove(); +} + +//================================================================================ +/*! + * \brief Read mesh entities preventing successful computation from "test.out" file + */ +//================================================================================ + +SMESH_ComputeErrorPtr +NETGENPlugin_Mesher::readErrors(const vector& nodeVec) +{ + SMESH_ComputeErrorPtr err = SMESH_ComputeError::New + (COMPERR_BAD_INPUT_MESH, "Some edges multiple times in surface mesh"); + SMESH_File file("test.out"); + vector two(2); + const char* badEdgeStr = " multiple times in surface mesh"; + const int badEdgeStrLen = strlen( badEdgeStr ); + while( !file.eof() ) + { + if ( strncmp( file, "Edge ", 5 ) == 0 && + file.getInts( two ) && + strncmp( file, badEdgeStr, badEdgeStrLen ) == 0 && + two[0] < nodeVec.size() && two[1] < nodeVec.size()) + { + err->myBadElements.push_back( new SMDS_LinearEdge( nodeVec[ two[0]], nodeVec[ two[1]] )); + file += badEdgeStrLen; + } + else if ( strncmp( file, "Intersecting: ", 14 ) == 0 ) + { +// Intersecting: +// openelement 18 with open element 126 +// 41 36 38 +// 69 70 72 + vector three1(3), three2(3); + file.getLine(); + const char* pos = file; + bool ok = ( strncmp( file, "openelement ", 12 ) == 0 ); + ok = ok && file.getInts( two ); + ok = ok && file.getInts( three1 ); + ok = ok && file.getInts( three2 ); + for ( int i = 0; ok && i < 3; ++i ) + ok = ( three1[i] < nodeVec.size() && nodeVec[ three1[i]]); + for ( int i = 0; ok && i < 3; ++i ) + ok = ( three2[i] < nodeVec.size() && nodeVec[ three2[i]]); + if ( ok ) + { + err->myBadElements.push_back( new SMDS_FaceOfNodes( nodeVec[ three1[0]], + nodeVec[ three1[1]], + nodeVec[ three1[2]])); + err->myBadElements.push_back( new SMDS_FaceOfNodes( nodeVec[ three2[0]], + nodeVec[ three2[1]], + nodeVec[ three2[2]])); + err->myComment = "Intersecting triangles"; + } + else + { + file.setPos( pos ); + } + } + else + { + ++file; + } + } + return err; +} + +//================================================================================ +/*! + * \brief Write a python script creating an equivalent SALOME mesh. + * This is useful to see what mesh is passed as input for the next step of mesh + * generation (of mesh of higher dimension) + */ +//================================================================================ + +void NETGENPlugin_Mesher::toPython( const netgen::Mesh* ngMesh, + const std::string& pyFile) +{ + ofstream outfile(pyFile.c_str(), ios::out); + if ( !outfile ) return; + + outfile << "import smesh, SMESH" << endl + << "mesh = smesh.Mesh()" << endl << endl; + + using namespace netgen; + PointIndex pi; + for (pi = PointIndex::BASE; + pi < ngMesh->GetNP()+PointIndex::BASE; pi++) + { + outfile << "mesh.AddNode( "; + outfile << (*ngMesh)[pi](0) << ", "; + outfile << (*ngMesh)[pi](1) << ", "; + outfile << (*ngMesh)[pi](2) << ")" << endl; + } + + int nbDom = ngMesh->GetNDomains(); + for ( int i = 0; i < nbDom; ++i ) + outfile<< "grp" << i+1 << " = mesh.CreateEmptyGroup( SMESH.FACE, 'domain"<< i+1 << "')"<< endl; + + SurfaceElementIndex sei; + for (sei = 0; sei < ngMesh->GetNSE(); sei++) + { + outfile << "mesh.AddFace([ "; + Element2d sel = (*ngMesh)[sei]; + for (int j = 0; j < sel.GetNP(); j++) + outfile << sel[j] << ( j+1 < sel.GetNP() ? ", " : " ])"); + outfile << endl; + + if ((*ngMesh)[sei].GetIndex()) + { + if ( int dom1 = ngMesh->GetFaceDescriptor((*ngMesh)[sei].GetIndex ()).DomainIn()) + outfile << "grp"<< dom1 <<".Add([ " << (int)sei+1 << " ])" << endl; + if ( int dom2 = ngMesh->GetFaceDescriptor((*ngMesh)[sei].GetIndex ()).DomainOut()) + outfile << "grp"<< dom2 <<".Add([ " << (int)sei+1 << " ])" << endl; + } + } + + for (ElementIndex ei = 0; ei < ngMesh->GetNE(); ei++) + { + Element el = (*ngMesh)[ei]; + outfile << "mesh.AddVolume([ "; + for (int j = 0; j < el.GetNP(); j++) + outfile << el[j] << ( j+1 < el.GetNP() ? ", " : " ])"); + outfile << endl; + } + + for (int i = 1; i <= ngMesh->GetNSeg(); i++) + { + const Segment & seg = ngMesh->LineSegment (i); + outfile << "mesh.AddEdge([ " + << seg[0] << ", " + << seg[1] << " ])" << endl; + } + cout << "Write " << pyFile << endl; +} + +//================================================================================ +/*! + * \brief Constructor of NETGENPlugin_ngMeshInfo + */ +//================================================================================ + +NETGENPlugin_ngMeshInfo::NETGENPlugin_ngMeshInfo( netgen::Mesh* ngMesh): + _copyOfLocalH(0) +{ + if ( ngMesh ) + { + _nbNodes = ngMesh->GetNP(); + _nbSegments = ngMesh->GetNSeg(); + _nbFaces = ngMesh->GetNSE(); + _nbVolumes = ngMesh->GetNE(); + } + else + { + _nbNodes = _nbSegments = _nbFaces = _nbVolumes = 0; + } +} + +//================================================================================ +/*! + * \brief Copy LocalH member from one netgen mesh to another + */ +//================================================================================ + +void NETGENPlugin_ngMeshInfo::transferLocalH( netgen::Mesh* fromMesh, + netgen::Mesh* toMesh ) +{ + if ( !fromMesh->LocalHFunctionGenerated() ) return; + if ( !toMesh->LocalHFunctionGenerated() ) + toMesh->CalcLocalH(); + + const size_t size = sizeof( netgen::LocalH ); + _copyOfLocalH = new char[ size ]; + memcpy( (void*)_copyOfLocalH, (void*)&toMesh->LocalHFunction(), size ); + memcpy( (void*)&toMesh->LocalHFunction(), (void*)&fromMesh->LocalHFunction(), size ); +} + +//================================================================================ +/*! + * \brief Restore LocalH member of a netgen mesh + */ +//================================================================================ + +void NETGENPlugin_ngMeshInfo::restoreLocalH( netgen::Mesh* toMesh ) +{ + if ( _copyOfLocalH ) + { + const size_t size = sizeof( netgen::LocalH ); + memcpy( (void*)&toMesh->LocalHFunction(), (void*)_copyOfLocalH, size ); + delete [] _copyOfLocalH; + _copyOfLocalH = 0; + } +} + +//================================================================================ +/*! + * \brief Find "internal" sub-shapes + */ +//================================================================================ + +NETGENPlugin_Internals::NETGENPlugin_Internals( SMESH_Mesh& mesh, + const TopoDS_Shape& shape, + bool is3D ) + : _mesh( mesh ), _is3D( is3D ) +{ + SMESHDS_Mesh* meshDS = mesh.GetMeshDS(); + + TopExp_Explorer f,e; + for ( f.Init( shape, TopAbs_FACE ); f.More(); f.Next() ) + { + int faceID = meshDS->ShapeToIndex( f.Current() ); + + // find not computed internal edges + + for ( e.Init( f.Current().Oriented(TopAbs_FORWARD), TopAbs_EDGE ); e.More(); e.Next() ) + if ( e.Current().Orientation() == TopAbs_INTERNAL ) + { + SMESH_subMesh* eSM = mesh.GetSubMesh( e.Current() ); + if ( eSM->IsEmpty() ) + { + _e2face.insert( make_pair( eSM->GetId(), faceID )); + for ( TopoDS_Iterator v(e.Current()); v.More(); v.Next() ) + _e2face.insert( make_pair( meshDS->ShapeToIndex( v.Value() ), faceID )); + } + } + + // find internal vertices in a face + set intVV; // issue 0020850 where same vertex is twice in a face + for ( TopoDS_Iterator fSub( f.Current() ); fSub.More(); fSub.Next()) + if ( fSub.Value().ShapeType() == TopAbs_VERTEX ) + { + int vID = meshDS->ShapeToIndex( fSub.Value() ); + if ( intVV.insert( vID ).second ) + _f2v[ faceID ].push_back( vID ); + } + + if ( is3D ) + { + // find internal faces and their subshapes where nodes are to be doubled + // to make a crack with non-sewed borders + + if ( f.Current().Orientation() == TopAbs_INTERNAL ) + { + _intShapes.insert( meshDS->ShapeToIndex( f.Current() )); + + // egdes + list< TopoDS_Shape > edges; + for ( e.Init( f.Current(), TopAbs_EDGE ); e.More(); e.Next()) + if ( SMESH_MesherHelper::NbAncestors( e.Current(), mesh, TopAbs_FACE ) > 1 ) + { + _intShapes.insert( meshDS->ShapeToIndex( e.Current() )); + edges.push_back( e.Current() ); + // find border faces + PShapeIteratorPtr fIt = + SMESH_MesherHelper::GetAncestors( edges.back(),mesh,TopAbs_FACE ); + while ( const TopoDS_Shape* pFace = fIt->next() ) + if ( !pFace->IsSame( f.Current() )) + _borderFaces.insert( meshDS->ShapeToIndex( *pFace )); + } + // vertices + // we consider vertex internal if it is shared by more than one internal edge + list< TopoDS_Shape >::iterator edge = edges.begin(); + for ( ; edge != edges.end(); ++edge ) + for ( TopoDS_Iterator v( *edge ); v.More(); v.Next() ) + { + set internalEdges; + PShapeIteratorPtr eIt = + SMESH_MesherHelper::GetAncestors( v.Value(),mesh,TopAbs_EDGE ); + while ( const TopoDS_Shape* pEdge = eIt->next() ) + { + int edgeID = meshDS->ShapeToIndex( *pEdge ); + if ( isInternalShape( edgeID )) + internalEdges.insert( edgeID ); + } + if ( internalEdges.size() > 1 ) + _intShapes.insert( meshDS->ShapeToIndex( v.Value() )); + } + } + } + } // loop on geom faces + + // find vertices internal in solids + if ( is3D ) + { + for ( TopExp_Explorer so(shape, TopAbs_SOLID); so.More(); so.Next()) + { + int soID = meshDS->ShapeToIndex( so.Current() ); + for ( TopoDS_Iterator soSub( so.Current() ); soSub.More(); soSub.Next()) + if ( soSub.Value().ShapeType() == TopAbs_VERTEX ) + _s2v[ soID ].push_back( meshDS->ShapeToIndex( soSub.Value() )); + } + } +} + +//================================================================================ +/*! + * \brief Find mesh faces on non-internal geom faces sharing internal edge + * some nodes of which are to be doubled to make the second border of the "crack" + */ +//================================================================================ + +void NETGENPlugin_Internals::findBorderElements( TIDSortedElemSet & borderElems ) +{ + if ( _intShapes.empty() ) return; + + SMESH_Mesh& mesh = const_cast(_mesh); + SMESHDS_Mesh* meshDS = mesh.GetMeshDS(); + + // loop on internal geom edges + set::const_iterator intShapeId = _intShapes.begin(); + for ( ; intShapeId != _intShapes.end(); ++intShapeId ) + { + const TopoDS_Shape& s = meshDS->IndexToShape( *intShapeId ); + if ( s.ShapeType() != TopAbs_EDGE ) continue; + + // get internal and non-internal geom faces sharing the internal edge + int intFace = 0; + set::iterator bordFace = _borderFaces.end(); + PShapeIteratorPtr faces = SMESH_MesherHelper::GetAncestors( s, _mesh, TopAbs_FACE ); + while ( const TopoDS_Shape* pFace = faces->next() ) + { + int faceID = meshDS->ShapeToIndex( *pFace ); + if ( isInternalShape( faceID )) + intFace = faceID; + else + bordFace = _borderFaces.insert( faceID ).first; + } + if ( bordFace == _borderFaces.end() || !intFace ) continue; + + // get all links of mesh faces on internal geom face sharing nodes on edge + set< SMESH_OrientedLink > links; //!< links of faces on internal geom face + list suspectFaces[2]; //!< mesh faces on border geom faces + int nbSuspectFaces = 0; + SMESHDS_SubMesh* intFaceSM = meshDS->MeshElements( intFace ); + if ( !intFaceSM || intFaceSM->NbElements() == 0 ) continue; + SMESH_subMeshIteratorPtr smIt = mesh.GetSubMesh( s )->getDependsOnIterator(true,true); + while ( smIt->more() ) + { + SMESHDS_SubMesh* sm = smIt->next()->GetSubMeshDS(); + if ( !sm ) continue; + SMDS_NodeIteratorPtr nIt = sm->GetNodes(); + while ( nIt->more() ) + { + const SMDS_MeshNode* nOnEdge = nIt->next(); + SMDS_ElemIteratorPtr fIt = nOnEdge->GetInverseElementIterator(SMDSAbs_Face); + while ( fIt->more() ) + { + const SMDS_MeshElement* f = fIt->next(); + int nbNodes = f->NbNodes() / ( f->IsQuadratic() ? 2 : 1 ); + if ( intFaceSM->Contains( f )) + { + for ( int i = 0; i < nbNodes; ++i ) + links.insert( SMESH_OrientedLink( f->GetNode(i), f->GetNode((i+1)%nbNodes))); + } + else + { + int nbDblNodes = 0; + for ( int i = 0; i < nbNodes; ++i ) + nbDblNodes += isInternalShape( f->GetNode(i)->getshapeId() ); + if ( nbDblNodes ) + suspectFaces[ nbDblNodes < 2 ].push_back( f ); + nbSuspectFaces++; + } + } + } + } + // suspectFaces[0] having link with same orientation as mesh faces on + // the internal geom face are . suspectFaces[1] have + // only one node on edge , we decide on them later (at the 2nd loop) + // by links of found at the 1st and 2nd loops + set< SMESH_OrientedLink > borderLinks; + for ( int isPostponed = 0; isPostponed < 2; ++isPostponed ) + { + list::iterator fIt = suspectFaces[isPostponed].begin(); + for ( int nbF = 0; fIt != suspectFaces[isPostponed].end(); ++fIt, ++nbF ) + { + const SMDS_MeshElement* f = *fIt; + bool isBorder = false, linkFound = false, borderLinkFound = false; + list< SMESH_OrientedLink > faceLinks; + int nbNodes = f->NbNodes() / ( f->IsQuadratic() ? 2 : 1 ); + for ( int i = 0; i < nbNodes; ++i ) + { + SMESH_OrientedLink link( f->GetNode(i), f->GetNode((i+1)%nbNodes)); + faceLinks.push_back( link ); + if ( !linkFound ) + { + set< SMESH_OrientedLink >::iterator foundLink = links.find( link ); + if ( foundLink != links.end() ) + { + linkFound= true; + isBorder = ( foundLink->_reversed == link._reversed ); + if ( !isBorder && !isPostponed ) break; + faceLinks.pop_back(); + } + else if ( isPostponed && !borderLinkFound ) + { + foundLink = borderLinks.find( link ); + if ( foundLink != borderLinks.end() ) + { + borderLinkFound = true; + isBorder = ( foundLink->_reversed != link._reversed ); + } + } + } + } + if ( isBorder ) + { + borderElems.insert( f ); + borderLinks.insert( faceLinks.begin(), faceLinks.end() ); + } + else if ( !linkFound && !borderLinkFound ) + { + suspectFaces[1].push_back( f ); + if ( nbF > 2 * nbSuspectFaces ) + break; // dead loop protection + } + } + } + } +} + +//================================================================================ +/*! + * \brief put internal shapes in maps and fill in submeshes to precompute + */ +//================================================================================ + +void NETGENPlugin_Internals::getInternalEdges( TopTools_IndexedMapOfShape& fmap, + TopTools_IndexedMapOfShape& emap, + TopTools_IndexedMapOfShape& vmap, + list< SMESH_subMesh* > smToPrecompute[]) +{ + if ( !hasInternalEdges() ) return; + map::const_iterator ev_face = _e2face.begin(); + for ( ; ev_face != _e2face.end(); ++ev_face ) + { + const TopoDS_Shape& ev = _mesh.GetMeshDS()->IndexToShape( ev_face->first ); + const TopoDS_Shape& face = _mesh.GetMeshDS()->IndexToShape( ev_face->second ); + + ( ev.ShapeType() == TopAbs_EDGE ? emap : vmap ).Add( ev ); + fmap.Add( face ); + //cout<<"INTERNAL EDGE or VERTEX "<first<<" on face "<second<first )); + } +} + +//================================================================================ +/*! + * \brief return shapes and submeshes to be meshed and already meshed boundary submeshes + */ +//================================================================================ + +void NETGENPlugin_Internals::getInternalFaces( TopTools_IndexedMapOfShape& fmap, + TopTools_IndexedMapOfShape& emap, + list< SMESH_subMesh* >& intFaceSM, + list< SMESH_subMesh* >& boundarySM) +{ + if ( !hasInternalFaces() ) return; + + // and are for not yet meshed shapes + // is for submeshes of faces + // is for meshed edges and vertices + + intFaceSM.clear(); + boundarySM.clear(); + + set shapeIDs ( _intShapes ); + if ( !_borderFaces.empty() ) + shapeIDs.insert( _borderFaces.begin(), _borderFaces.end() ); + + set::const_iterator intS = shapeIDs.begin(); + for ( ; intS != shapeIDs.end(); ++intS ) + { + SMESH_subMesh* sm = _mesh.GetSubMeshContaining( *intS ); + + if ( sm->GetSubShape().ShapeType() != TopAbs_FACE ) continue; + + intFaceSM.push_back( sm ); + + // add submeshes of not computed internal faces + if ( !sm->IsEmpty() ) continue; + + SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(true,true); + while ( smIt->more() ) + { + sm = smIt->next(); + const TopoDS_Shape& s = sm->GetSubShape(); + + if ( sm->IsEmpty() ) + { + // not yet meshed + switch ( s.ShapeType() ) { + case TopAbs_FACE: fmap.Add ( s ); break; + case TopAbs_EDGE: emap.Add ( s ); break; + default:; + } + } + else + { + if ( s.ShapeType() != TopAbs_FACE ) + boundarySM.push_back( sm ); + } + } + } +} + +//================================================================================ +/*! + * \brief Return true if given shape is to be precomputed in order to be correctly + * added to netgen mesh + */ +//================================================================================ + +bool NETGENPlugin_Internals::isShapeToPrecompute(const TopoDS_Shape& s) +{ + int shapeID = _mesh.GetMeshDS()->ShapeToIndex( s ); + switch ( s.ShapeType() ) { + case TopAbs_FACE : break; //return isInternalShape( shapeID ) || isBorderFace( shapeID ); + case TopAbs_EDGE : return isInternalEdge( shapeID ); + case TopAbs_VERTEX: break; + default:; + } + return false; +} + +//================================================================================ +/*! + * \brief Return SMESH + */ +//================================================================================ + +SMESH_Mesh& NETGENPlugin_Internals::getMesh() const +{ + return const_cast( _mesh ); +} + +//================================================================================ +/*! + * \brief Initialize netgen library + */ +//================================================================================ + +NETGENPlugin_NetgenLibWrapper::NETGENPlugin_NetgenLibWrapper() +{ + Ng_Init(); + _ngMesh = Ng_NewMesh(); +} + +//================================================================================ +/*! + * \brief Finish using netgen library + */ +//================================================================================ + +NETGENPlugin_NetgenLibWrapper::~NETGENPlugin_NetgenLibWrapper() +{ + Ng_DeleteMesh( _ngMesh ); + Ng_Exit(); + NETGENPlugin_Mesher::RemoveTmpFiles(); +} + +//================================================================================ +/*! + * \brief Set netgen mesh to delete at destruction + */ +//================================================================================ + +void NETGENPlugin_NetgenLibWrapper::setMesh( Ng_Mesh* mesh ) { - TCollection_AsciiString str("test.out"); - OSD_Path path1( str ); - OSD_File file1( path1 ); - file1.Remove(); - str = "problemfaces"; - OSD_Path path2( str ); - OSD_File file2( path2 ); - file2.Remove(); + if ( _ngMesh ) + Ng_DeleteMesh( _ngMesh ); + _ngMesh = mesh; } diff --git a/src/NETGENPlugin/NETGENPlugin_Mesher.hxx b/src/NETGENPlugin/NETGENPlugin_Mesher.hxx index 4cea643..a525ea7 100644 --- a/src/NETGENPlugin/NETGENPlugin_Mesher.hxx +++ b/src/NETGENPlugin/NETGENPlugin_Mesher.hxx @@ -1,52 +1,82 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_Mesher.hxx // Author : Michael Sazonov (OCN) // Date : 31/03/2006 // Project : SALOME -// $Header$ -//============================================================================= // #ifndef _NETGENPlugin_Mesher_HXX_ #define _NETGENPlugin_Mesher_HXX_ #include "NETGENPlugin_Defs.hxx" -#include "StdMeshers_FaceSide.hxx" + +#include +#include +#include +#include + +namespace nglib { +#include +} + #include +#include +#include class SMESH_Mesh; +class SMESH_Comment; class SMESHDS_Mesh; class TopoDS_Shape; +class TopTools_DataMapOfShapeShape; +class TopTools_IndexedMapOfShape; class NETGENPlugin_Hypothesis; class NETGENPlugin_SimpleHypothesis_2D; +class NETGENPlugin_Internals; namespace netgen { class OCCGeometry; class Mesh; } +//============================================================================= +/*! + * \brief Struct storing nb of entities in netgen mesh + */ +//============================================================================= +struct NETGENPlugin_ngMeshInfo +{ + int _nbNodes, _nbSegments, _nbFaces, _nbVolumes; + char* _copyOfLocalH; + NETGENPlugin_ngMeshInfo( netgen::Mesh* ngMesh=0); + void transferLocalH( netgen::Mesh* fromMesh, netgen::Mesh* toMesh ); + void restoreLocalH ( netgen::Mesh* ngMesh); +}; + +//============================================================================= /*! * \brief This class calls the NETGEN mesher of OCC geometry */ +//============================================================================= class NETGENPLUGIN_EXPORT NETGENPlugin_Mesher { @@ -56,36 +86,155 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Mesher NETGENPlugin_Mesher (SMESH_Mesh* mesh, const TopoDS_Shape& aShape, const bool isVolume); - void SetParameters(const NETGENPlugin_Hypothesis* hyp); + void SetParameters(const NETGENPlugin_Hypothesis* hyp); void SetParameters(const NETGENPlugin_SimpleHypothesis_2D* hyp); bool Compute(); + bool Evaluate(MapShapeNbElems& aResMap); + static void PrepareOCCgeometry(netgen::OCCGeometry& occgeom, const TopoDS_Shape& shape, SMESH_Mesh& mesh, - std::list< SMESH_subMesh* > * meshedSM=0); + std::list< SMESH_subMesh* > * meshedSM=0, + NETGENPlugin_Internals* internalShapes=0); - static void RemoveTmpFiles(); + static double GetDefaultMinSize(const TopoDS_Shape& shape, + const double maxSize); + + static void RestrictLocalSize(netgen::Mesh& ngMesh, const gp_XYZ& p, const double size); -protected: + static int FillSMesh(const netgen::OCCGeometry& occgeom, + netgen::Mesh& ngMesh, + const NETGENPlugin_ngMeshInfo& initState, + SMESH_Mesh& sMesh, + std::vector& nodeVec, + SMESH_Comment& comment); bool fillNgMesh(netgen::OCCGeometry& occgeom, netgen::Mesh& ngMesh, - std::vector& nodeVec, - const std::list< SMESH_subMesh* > & meshedSM); + std::vector& nodeVec, + const std::list< SMESH_subMesh* > & meshedSM, + SMESH_ProxyMesh::Ptr proxyMesh=SMESH_ProxyMesh::Ptr()); + + static void fixIntFaces(const netgen::OCCGeometry& occgeom, + netgen::Mesh& ngMesh, + NETGENPlugin_Internals& internalShapes); + + static void addIntVerticesInFaces(const netgen::OCCGeometry& occgeom, + netgen::Mesh& ngMesh, + std::vector& nodeVec, + NETGENPlugin_Internals& internalShapes); + + static void addIntVerticesInSolids(const netgen::OCCGeometry& occgeom, + netgen::Mesh& ngMesh, + std::vector& nodeVec, + NETGENPlugin_Internals& internalShapes); void defaultParameters(); + static void RemoveTmpFiles(); + + static SMESH_ComputeErrorPtr readErrors(const std::vector< const SMDS_MeshNode* >& nodeVec); + + + static void toPython( const netgen::Mesh* ngMesh, + const std::string& pyFile); // debug private: SMESH_Mesh* _mesh; const TopoDS_Shape& _shape; bool _isVolume; bool _optimize; + int _fineness; const NETGENPlugin_SimpleHypothesis_2D * _simpleHyp; std::map< int, std::pair > _faceDescriptors; }; +//============================================================================= +/*! + * \brief Container of info needed to solve problems with internal shapes. + * + * Issue 0020676. It is made up as a class to be ready to extract from NETGEN + * and put in SMESH as soon as the same solution is needed somewhere else. + * The approach is to precompute internal edges in 2D and internal faces in 3D + * and put their mesh correctly (twice) into netgen mesh. + * In 2D, this class finds internal edges in faces and their vertices. + * In 3D, it additionally finds internal faces, their edges shared with other faces, + * and their vertices shared by several internal edges. Nodes built on the found + * shapes and mesh faces built on the found internal faces are to be doubled in + * netgen mesh to emulate a "crack" + * + * For internal faces a more simple solution is found, which is just to duplicate + * mesh faces on internal geom faces without modeling a "real crack". For this + * reason findBorderElements() is no more used anywhere. + */ +//============================================================================= + +class NETGENPLUGIN_EXPORT NETGENPlugin_Internals +{ + SMESH_Mesh& _mesh; + bool _is3D; + //2D + std::map _e2face;//! > _f2v;//! _intShapes; + std::set _borderFaces; //!< non-internal faces sharing the internal edge + std::map > _s2v;//!& getEdgesAndVerticesWithFaces() const { return _e2face; } + void getInternalEdges( TopTools_IndexedMapOfShape& fmap, + TopTools_IndexedMapOfShape& emap, + TopTools_IndexedMapOfShape& vmap, + std::list< SMESH_subMesh* > smToPrecompute[]); + // vertices + bool hasInternalVertexInFace() const { return !_f2v.empty(); } + const std::map >& getFacesWithVertices() const { return _f2v; } + + // 3D meshing + // faces + bool hasInternalFaces() const { return !_intShapes.empty(); } + bool isInternalShape( int id ) const { return _intShapes.count( id ); } + void findBorderElements( std::set< const SMDS_MeshElement*, TIDCompare > & borderElems ); + bool isBorderFace( int faceID ) const { return _borderFaces.count( faceID ); } + void getInternalFaces( TopTools_IndexedMapOfShape& fmap, + TopTools_IndexedMapOfShape& emap, + std::list< SMESH_subMesh* >& facesSM, + std::list< SMESH_subMesh* >& boundarySM); + // vertices + bool hasInternalVertexInSolid() const { return !_s2v.empty(); } + bool hasInternalVertexInSolid(int soID ) const { return _s2v.count(soID); } + const std::map >& getSolidsWithVertices() const { return _s2v; } + + +}; + +//================================================================================ +/*! + * \brief It correctly initializes netgen library at constructor and + * correctly finishes using netgen library at destructor + */ +//================================================================================ + +struct NETGENPLUGIN_EXPORT NETGENPlugin_NetgenLibWrapper +{ + nglib::Ng_Mesh * _ngMesh; + NETGENPlugin_NetgenLibWrapper(); + ~NETGENPlugin_NetgenLibWrapper(); + void setMesh( nglib::Ng_Mesh* mesh ); +}; + #endif diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D.cxx index 75bbc53..bf56622 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D.cxx @@ -1,30 +1,30 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_NETGEN_2D.cxx // Author : Michael Sazonov (OCN) // Date : 20/03/2006 // Project : SALOME -// $Header$ //============================================================================= // #include "NETGENPlugin_NETGEN_2D.hxx" @@ -40,6 +40,13 @@ #include +#ifdef WITH_SMESH_CANCEL_COMPUTE +namespace nglib { +#include +} +#include +#endif + using namespace std; //============================================================================= @@ -57,7 +64,7 @@ NETGENPlugin_NETGEN_2D::NETGENPlugin_NETGEN_2D(int hypId, int studyId, _shapeType = (1 << TopAbs_FACE); // 1 bit /shape type _compatibleHypothesis.push_back("NETGEN_Parameters_2D"); _compatibleHypothesis.push_back("NETGEN_SimpleParameters_2D"); - _requireDescretBoundary = false; + _requireDiscreteBoundary = false; _onlyUnaryInput = false; _hypothesis = NULL; _supportSubmeshes = true; @@ -121,11 +128,37 @@ bool NETGENPlugin_NETGEN_2D::CheckHypothesis bool NETGENPlugin_NETGEN_2D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { - //SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); +#ifdef WITH_SMESH_CANCEL_COMPUTE + netgen::multithread.terminate = 0; +#endif NETGENPlugin_Mesher mesher(&aMesh, aShape, false); -// NETGENPlugin_Mesher mesher(meshDS, aShape, false); mesher.SetParameters(dynamic_cast(_hypothesis)); mesher.SetParameters(dynamic_cast(_hypothesis)); return mesher.Compute(); } + +#ifdef WITH_SMESH_CANCEL_COMPUTE +void NETGENPlugin_NETGEN_2D::CancelCompute() +{ + SMESH_Algo::CancelCompute(); + netgen::multithread.terminate = 1; +} +#endif + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool NETGENPlugin_NETGEN_2D::Evaluate(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap) +{ + + NETGENPlugin_Mesher mesher(&aMesh, aShape, false); + mesher.SetParameters(dynamic_cast(_hypothesis)); + mesher.SetParameters(dynamic_cast(_hypothesis)); + return mesher.Evaluate(aResMap); +} diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D.hxx index 57b6ee4..cfb723d 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_NETGEN_2D.hxx // Author : Michael Sazonov (OCN) @@ -50,7 +51,14 @@ public: SMESH_Hypothesis::Hypothesis_Status& aStatus); virtual bool Compute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape); + const TopoDS_Shape& aShape); + +#ifdef WITH_SMESH_CANCEL_COMPUTE + virtual void CancelCompute(); +#endif + + virtual bool Evaluate(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap); protected: const SMESHDS_Hypothesis* _hypothesis; diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.cxx index 2bad447..5959507 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_NETGEN_2D3D.cxx // Author : Michael Sazonov (OCN) @@ -40,6 +41,13 @@ #include +#ifdef WITH_SMESH_CANCEL_COMPUTE +namespace nglib { +#include +} +#include +#endif + using namespace std; //============================================================================= @@ -57,7 +65,7 @@ NETGENPlugin_NETGEN_2D3D::NETGENPlugin_NETGEN_2D3D(int hypId, int studyId, _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type _compatibleHypothesis.push_back("NETGEN_Parameters"); _compatibleHypothesis.push_back("NETGEN_SimpleParameters_3D"); - _requireDescretBoundary = false; + _requireDiscreteBoundary = false; _onlyUnaryInput = false; _hypothesis = NULL; _supportSubmeshes = true; @@ -124,6 +132,9 @@ bool NETGENPlugin_NETGEN_2D3D::CheckHypothesis bool NETGENPlugin_NETGEN_2D3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { +#ifdef WITH_SMESH_CANCEL_COMPUTE + netgen::multithread.terminate = 0; +#endif // SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); NETGENPlugin_Mesher mesher(&aMesh, aShape, true); @@ -132,3 +143,27 @@ bool NETGENPlugin_NETGEN_2D3D::Compute(SMESH_Mesh& aMesh, mesher.SetParameters(dynamic_cast(_hypothesis)); return mesher.Compute(); } + +#ifdef WITH_SMESH_CANCEL_COMPUTE +void NETGENPlugin_NETGEN_2D3D::CancelCompute() +{ + SMESH_Algo::CancelCompute(); + netgen::multithread.terminate = 1; +} +#endif + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool NETGENPlugin_NETGEN_2D3D::Evaluate(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap) +{ + NETGENPlugin_Mesher mesher(&aMesh, aShape, true); + mesher.SetParameters(dynamic_cast(_hypothesis)); + mesher.SetParameters(dynamic_cast(_hypothesis)); + return mesher.Evaluate(aResMap); +} diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.hxx index 2f490d7..7775f8c 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_NETGEN_2D3D.hxx // Author : Michael Sazonov (OCN) @@ -50,7 +51,15 @@ public: SMESH_Hypothesis::Hypothesis_Status& aStatus); virtual bool Compute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape); + const TopoDS_Shape& aShape); + +#ifdef WITH_SMESH_CANCEL_COMPUTE + virtual void CancelCompute(); +#endif + + virtual bool Evaluate(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap); protected: const SMESHDS_Hypothesis* _hypothesis; diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D_i.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D_i.cxx index c15f825..943bb73 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D_i.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : idl implementation // File : NETGENPlugin_NETGEN_2D3D_i.cxx // Author : Michael Sazonov (OCN) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D_i.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D_i.hxx index 083deeb..624a0d5 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D_i.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D3D_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : idl implementation // File : NETGENPlugin_NETGEN_2D3D_i.hxx // Author : Michael Sazonov (OCN) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx index fb48a06..acb11d6 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File : NETGENPlugin_NETGEN_2D_ONLY.cxx // Author : Edward AGAPOV (OCC) // Project : SALOME @@ -26,6 +24,7 @@ #include "NETGENPlugin_NETGEN_2D_ONLY.hxx" #include "NETGENPlugin_Mesher.hxx" +#include "NETGENPlugin_Hypothesis_2D.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" @@ -39,6 +38,7 @@ #include "StdMeshers_LengthFromEdges.hxx" #include "StdMeshers_QuadranglePreference.hxx" +#include #include #include @@ -46,6 +46,7 @@ #include #include +#include /* Netgen include files @@ -53,19 +54,23 @@ namespace nglib { #include } +#ifndef OCCGEOMETRY #define OCCGEOMETRY +#endif #include #include //#include namespace netgen { extern int OCCGenerateMesh (OCCGeometry&, Mesh*&, int, int, char*); - /*extern*/ MeshingParameters mparam; + extern MeshingParameters mparam; } using namespace std; using namespace netgen; using namespace nglib; +//#define DUMP_SEGMENTS + //============================================================================= /*! * @@ -78,16 +83,18 @@ NETGENPlugin_NETGEN_2D_ONLY::NETGENPlugin_NETGEN_2D_ONLY(int hypId, int studyId, { MESSAGE("NETGENPlugin_NETGEN_2D_ONLY::NETGENPlugin_NETGEN_2D_ONLY"); _name = "NETGEN_2D_ONLY"; - + _shapeType = (1 << TopAbs_FACE);// 1 bit /shape type _compatibleHypothesis.push_back("MaxElementArea"); _compatibleHypothesis.push_back("LengthFromEdges"); _compatibleHypothesis.push_back("QuadranglePreference"); + _compatibleHypothesis.push_back("NETGEN_Parameters_2D"); _hypMaxElementArea = 0; _hypLengthFromEdges = 0; _hypQuadranglePreference = 0; + _hypParameters = 0; } //============================================================================= @@ -138,21 +145,21 @@ bool NETGENPlugin_NETGEN_2D_ONLY::CheckHypothesis (SMESH_Mesh& aMesh, _hypLengthFromEdges = static_cast (hyp); else if ( hypName == "QuadranglePreference" ) _hypQuadranglePreference = static_cast(hyp); + else if ( hypName == "NETGEN_Parameters_2D" ) + _hypParameters = static_cast(hyp); else { aStatus = HYP_INCOMPATIBLE; return false; } } - if ( _hypMaxElementArea && _hypLengthFromEdges ) { + int nbHyps = bool(_hypMaxElementArea) + bool(_hypLengthFromEdges) + bool(_hypParameters ); + if ( nbHyps > 1 ) aStatus = HYP_CONCURENT; - return false; - } - - if ( _hypMaxElementArea || _hypLengthFromEdges ) + else if ( nbHyps == 1) aStatus = HYP_OK; - return aStatus == HYP_OK; + return ( aStatus == HYP_OK ); } //================================================================================ @@ -162,7 +169,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::CheckHypothesis (SMESH_Mesh& aMesh, */ //================================================================================ -static TError AddSegmentsToMesh(netgen::Mesh& ngMesh, +static TError addSegmentsToMesh(netgen::Mesh& ngMesh, OCCGeometry& geom, const TSideVector& wires, SMESH_MesherHelper& helper, @@ -172,20 +179,27 @@ static TError AddSegmentsToMesh(netgen::Mesh& ngMesh, // Check wires and count nodes // ---------------------------- int nbNodes = 0; + double totalLength = 0; for ( int iW = 0; iW < wires.size(); ++iW ) { StdMeshers_FaceSidePtr wire = wires[ iW ]; if ( wire->MissVertexNode() ) - return TError - (new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH, "Missing nodes on vertices")); - + { + // Commented for issue 0020960. It worked for the case, let's wait for case where it doesn't. + // It seems that there is no reason for this limitation +// return TError +// (new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH, "Missing nodes on vertices")); + if (getenv("USER") && string("eap")==getenv("USER")) + cout << "Warning: NETGENPlugin_NETGEN_2D_ONLY : try to work with missing nodes on vertices"<& uvPtVec = wire->GetUVPtStruct(); if ( uvPtVec.size() != wire->NbPoints() ) return TError (new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH, SMESH_Comment("Unexpected nb of points on wire ") << iW << ": " << uvPtVec.size()<<" != "<NbPoints())); - nbNodes += wire->NbSegments(); + nbNodes += wire->NbPoints(); + totalLength += wire->Length(); } nodeVec.reserve( nbNodes ); @@ -197,37 +211,64 @@ static TError AddSegmentsToMesh(netgen::Mesh& ngMesh, // bb.Increase (bb.Diam()/10); // ngMesh.SetLocalH (bb.PMin(), bb.PMax(), 0.5); // set grading + // map for nodes on vertices since they can be shared between wires + // ( issue 0020676, face_int_box.brep) + map node2ngID; + const int faceID = 1, solidID = 0; - ngMesh.AddFaceDescriptor (FaceDescriptor(faceID, solidID, solidID, 0)); + if ( ngMesh.GetNFD() < 1 ) + ngMesh.AddFaceDescriptor (FaceDescriptor(faceID, solidID, solidID, 0)); for ( int iW = 0; iW < wires.size(); ++iW ) { StdMeshers_FaceSidePtr wire = wires[ iW ]; const vector& uvPtVec = wire->GetUVPtStruct(); + const int nbSegments = wire->NbPoints() - 1; + + // compute length of every segment + vector segLen( nbSegments ); + for ( int i = 0; i < nbSegments; ++i ) + segLen[i] = SMESH_TNodeXYZ( uvPtVec[ i ].node ).Distance( uvPtVec[ i+1 ].node ); - int firstPointID = ngMesh.GetNP() + 1; int edgeID = 1, posID = -2; - for ( int i = 0; i < wire->NbSegments(); ++i ) // loop on segments + bool isInternalWire = false; + for ( int i = 0; i < nbSegments; ++i ) // loop on segments { // Add the first point of a segment const SMDS_MeshNode * n = uvPtVec[ i ].node; - const int posShapeID = n->GetPosition()->GetShapeId(); + const int posShapeID = n->getshapeId(); + bool onVertex = ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ); // skip nodes on degenerated edges if ( helper.IsDegenShape( posShapeID ) && - helper.IsDegenShape( uvPtVec[ i+1 ].node->GetPosition()->GetShapeId() )) + helper.IsDegenShape( uvPtVec[ i+1 ].node->getshapeId() )) continue; - nodeVec.push_back( n ); - - MeshPoint mp( Point<3> (n->X(), n->Y(), n->Z()) ); - ngMesh.AddPoint ( mp, 1, EDGEPOINT ); + int ngID1 = ngMesh.GetNP() + 1, ngID2 = ngID1+1; + if ( onVertex ) + ngID1 = node2ngID.insert( make_pair( n, ngID1 )).first->second; + if ( ngID1 > ngMesh.GetNP() ) + { + MeshPoint mp( Point<3> (n->X(), n->Y(), n->Z()) ); + ngMesh.AddPoint ( mp, 1, EDGEPOINT ); + nodeVec.push_back( n ); + } + else + { + ngID2 = ngMesh.GetNP() + 1; + if ( i > 0 ) // prev segment belongs to same wire + { + Segment& prevSeg = ngMesh.LineSegment( ngMesh.GetNSeg() ); + prevSeg[1] = ngID1; + } + } // Add the segment Segment seg; - seg.p1 = ngMesh.GetNP(); // ng node id - seg.p2 = seg.p1 + 1; // ng node id + seg[0] = ngID1; // ng node id + seg[1] = ngID2; // ng node id + seg.edgenr = ngMesh.GetNSeg() + 1;// segment id seg.si = faceID; // = geom.fmap.FindIndex (face); @@ -240,7 +281,7 @@ static TError AddSegmentsToMesh(netgen::Mesh& ngMesh, seg.epgeominfo[ iEnd ].v = pnt.v; // find out edge id and node parameter on edge - bool onVertex = ( pnt.node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ); + onVertex = ( pnt.node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ); if ( onVertex || posShapeID != posID ) { // get edge id @@ -250,29 +291,74 @@ static TError AddSegmentsToMesh(netgen::Mesh& ngMesh, const TopoDS_Edge& edge = wire->Edge( wire->EdgeIndex( normParam )); edgeID = geom.emap.FindIndex( edge ); posID = posShapeID; - if ( onVertex ) // param on curve is different on each of two edges - seg.epgeominfo[ iEnd ].dist = helper.GetNodeU( edge, pnt.node ); + isInternalWire = ( edge.Orientation() == TopAbs_INTERNAL ); + // if ( onVertex ) // param on curve is different on each of two edges + // seg.epgeominfo[ iEnd ].dist = helper.GetNodeU( edge, pnt.node ); } seg.epgeominfo[ iEnd ].edgenr = edgeID; // = geom.emap.FindIndex(edge); } ngMesh.AddSegment (seg); + { + // restrict size of elements near the segment + SMESH_TNodeXYZ np1( n ), np2( uvPtVec[ i+1 ].node ); + // get an average size of adjacent segments to avoid sharp change of + // element size (regression on issue 0020452, note 0010898) + int iPrev = SMESH_MesherHelper::WrapIndex( i-1, nbSegments ); + int iNext = SMESH_MesherHelper::WrapIndex( i+1, nbSegments ); + double avgH = ( segLen[ iPrev ] + segLen[ i ] + segLen[ iNext ]) / 3; + + NETGENPlugin_Mesher::RestrictLocalSize( ngMesh, 0.5*(np1+np2), avgH ); + } +#ifdef DUMP_SEGMENTS + cout << "Segment: " << seg.edgenr << endl + << "\tp1: " << seg[0] << endl + << "\tp2: " << seg[1] << endl + << "\tp0 param: " << seg.epgeominfo[ 0 ].dist << endl + << "\tp0 uv: " << seg.epgeominfo[ 0 ].u <<", "<< seg.epgeominfo[ 0 ].v << endl + << "\tp0 edge: " << seg.epgeominfo[ 0 ].edgenr << endl + << "\tp1 param: " << seg.epgeominfo[ 1 ].dist << endl + << "\tp1 uv: " << seg.epgeominfo[ 1 ].u <<", "<< seg.epgeominfo[ 1 ].v << endl + << "\tp1 edge: " << seg.epgeominfo[ 1 ].edgenr << endl; +#endif + if ( isInternalWire ) + { + swap (seg[0], seg[1]); + swap( seg.epgeominfo[0], seg.epgeominfo[1] ); + seg.edgenr = ngMesh.GetNSeg() + 1; // segment id + ngMesh.AddSegment (seg); +#ifdef DUMP_SEGMENTS + cout << "Segment: " << seg.edgenr << endl << "\tis REVRESE of the previous one" << endl; +#endif + } + } // loop on segments on a wire -// cout << "Segment: " << seg.edgenr << endl -// << "\tp1: " << seg.p1 << endl -// << "\tp2: " << seg.p2 << endl -// << "\tp0 param: " << seg.epgeominfo[ 0 ].dist << endl -// << "\tp0 uv: " << seg.epgeominfo[ 0 ].u <<", "<< seg.epgeominfo[ 0 ].v << endl -// << "\tp0 edge: " << seg.epgeominfo[ 0 ].edgenr << endl -// << "\tp1 param: " << seg.epgeominfo[ 1 ].dist << endl -// << "\tp1 uv: " << seg.epgeominfo[ 1 ].u <<", "<< seg.epgeominfo[ 1 ].v << endl -// << "\tp1 edge: " << seg.epgeominfo[ 1 ].edgenr << endl; + // close chain of segments + if ( nbSegments > 0 ) + { + Segment& lastSeg = ngMesh.LineSegment( ngMesh.GetNSeg() - int( isInternalWire)); + const SMDS_MeshNode * lastNode = uvPtVec.back().node; + lastSeg[1] = node2ngID.insert( make_pair( lastNode, lastSeg[1] )).first->second; + if ( lastSeg[1] > ngMesh.GetNP() ) + { + MeshPoint mp( Point<3> (lastNode->X(), lastNode->Y(), lastNode->Z()) ); + ngMesh.AddPoint ( mp, 1, EDGEPOINT ); + nodeVec.push_back( lastNode ); + } + if ( isInternalWire ) + { + Segment& realLastSeg = ngMesh.LineSegment( ngMesh.GetNSeg() ); + realLastSeg[0] = lastSeg[1]; + } } - Segment& seg = ngMesh.LineSegment( ngMesh.GetNSeg() ); - seg.p2 = firstPointID; - } - ngMesh.CalcSurfacesOfNode(); + } // loop on wires of a face + + // add a segment instead of internal vertex + NETGENPlugin_Internals intShapes( *helper.GetMesh(), helper.GetSubShape(), /*is3D=*/false ); + NETGENPlugin_Mesher::addIntVerticesInFaces( geom, ngMesh, nodeVec, intShapes ); + + ngMesh.CalcSurfacesOfNode(); return TError(); } @@ -286,6 +372,9 @@ static TError AddSegmentsToMesh(netgen::Mesh& ngMesh, bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { +#ifdef WITH_SMESH_CANCEL_COMPUTE + netgen::multithread.terminate = 0; +#endif MESSAGE("NETGENPlugin_NETGEN_2D_ONLY::Compute()"); SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); @@ -311,60 +400,73 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, return error(COMPERR_BAD_INPUT_MESH, SMESH_Comment("Too few segments: ")<NbSegments()); - // ------------------------- - // Make input netgen mesh - // ------------------------- - - Ng_Init(); - netgen::Mesh * ngMesh = new netgen::Mesh (); + // -------------------- + // compute edge length + // -------------------- + NETGENPlugin_Mesher aMesher( &aMesh, aShape, /*isVolume=*/false); netgen::OCCGeometry occgeo; - NETGENPlugin_Mesher::PrepareOCCgeometry( occgeo, F, aMesh ); + aMesher.PrepareOCCgeometry( occgeo, F, aMesh ); occgeo.fmap.Clear(); // face can be reversed, which is wrong in this case (issue 19978) occgeo.fmap.Add( F ); - vector< const SMDS_MeshNode* > nodeVec; - problem = AddSegmentsToMesh( *ngMesh, occgeo, wires, helper, nodeVec ); - if ( problem && !problem->IsOK() ) { - delete ngMesh; Ng_Exit(); - return error( problem ); + if ( _hypParameters ) + { + aMesher.SetParameters(_hypParameters); } - - // -------------------- - // compute edge length - // -------------------- - - double edgeLength = 0; - if (_hypLengthFromEdges || !_hypLengthFromEdges && !_hypMaxElementArea) + else { - int nbSegments = 0; - for ( int iW = 0; iW < nbWires; ++iW ) + double edgeLength = 0; + if (_hypLengthFromEdges || (!_hypLengthFromEdges && !_hypMaxElementArea)) { - edgeLength += wires[ iW ]->Length(); - nbSegments += wires[ iW ]->NbSegments(); + int nbSegments = 0; + for ( int iW = 0; iW < nbWires; ++iW ) + { + edgeLength += wires[ iW ]->Length(); + nbSegments += wires[ iW ]->NbSegments(); + } + if ( nbSegments ) + edgeLength /= nbSegments; } - if ( nbSegments ) - edgeLength /= nbSegments; - } - if ( _hypMaxElementArea ) - { - double maxArea = _hypMaxElementArea->GetMaxArea(); - edgeLength = sqrt(2. * maxArea/sqrt(3.0)); + if ( _hypMaxElementArea ) + { + double maxArea = _hypMaxElementArea->GetMaxArea(); + edgeLength = sqrt(2. * maxArea/sqrt(3.0)); + } + if ( edgeLength < DBL_MIN ) + edgeLength = occgeo.GetBoundingBox().Diam(); + + netgen::mparam.maxh = edgeLength; + netgen::mparam.minh = aMesher.GetDefaultMinSize( aShape, netgen::mparam.maxh ); + netgen::mparam.quad = _hypQuadranglePreference ? 1 : 0; + netgen::mparam.grading = 0.7; // very coarse mesh by default } - if ( edgeLength < DBL_MIN ) - edgeLength = occgeo.GetBoundingBox().Diam(); +#ifdef NETGEN_NEW + occgeo.face_maxh = netgen::mparam.maxh; +#endif - //cout << " edgeLength = " << edgeLength << endl; + // ------------------------- + // Make input netgen mesh + // ------------------------- + + NETGENPlugin_NetgenLibWrapper ngLib; + netgen::Mesh * ngMesh = (netgen::Mesh*) ngLib._ngMesh; - netgen::mparam.maxh = edgeLength; - netgen::mparam.quad = _hypQuadranglePreference ? 1 : 0; - //ngMesh->SetGlobalH ( edgeLength ); + Box<3> bb = occgeo.GetBoundingBox(); + bb.Increase (bb.Diam()/10); + ngMesh->SetLocalH (bb.PMin(), bb.PMax(), netgen::mparam.grading); + ngMesh->SetGlobalH (netgen::mparam.maxh); + + vector< const SMDS_MeshNode* > nodeVec; + problem = addSegmentsToMesh( *ngMesh, occgeo, wires, helper, nodeVec ); + if ( problem && !problem->IsOK() ) + return error( problem ); // ------------------------- // Generate surface mesh // ------------------------- - char *optstr; + char *optstr = 0; int startWith = MESHCONST_MESHSURFACE; int endWith = MESHCONST_OPTSURFACE; int err = 1; @@ -374,20 +476,26 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, OCC_CATCH_SIGNALS; #endif err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr); +#ifdef WITH_SMESH_CANCEL_COMPUTE + if(netgen::multithread.terminate) + return false; +#endif + if ( err ) + error(SMESH_Comment("Error in netgen::OCCGenerateMesh() at ") << netgen::multithread.task); } - catch (Standard_Failure& ex) { - string comment = ex.DynamicType()->Name(); - if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) { - comment += ": "; - comment += ex.GetMessageString(); - } - error(COMPERR_OCC_EXCEPTION, comment); - } - catch (NgException exc) { - error( SMESH_Comment("NgException: ") << exc.What() ); + catch (Standard_Failure& ex) + { + SMESH_Comment str("Exception in netgen::OCCGenerateMesh()"); + str << " at " << netgen::multithread.task + << ": " << ex.DynamicType()->Name(); + if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) + str << ": " << ex.GetMessageString(); + error(str); } catch (...) { - error(COMPERR_EXCEPTION,"Exception in netgen::OCCGenerateMesh()"); + SMESH_Comment str("Exception in netgen::OCCGenerateMesh()"); + str << " at " << netgen::multithread.task; + error(str); } // ---------------------------------------------------- @@ -404,19 +512,26 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, for ( int i = nbInputNodes + 1; i <= nbNodes; ++i ) { const MeshPoint& ngPoint = ngMesh->Point(i); +#ifdef NETGEN_NEW + SMDS_MeshNode * node = meshDS->AddNode(ngPoint(0), ngPoint(1), ngPoint(2)); +#else SMDS_MeshNode * node = meshDS->AddNode(ngPoint.X(), ngPoint.Y(), ngPoint.Z()); +#endif nodeVec[ i-1 ] = node; } // create faces bool reverse = ( aShape.Orientation() == TopAbs_REVERSED ); - for ( int i = 1; i <= nbFaces ; ++i ) + int i,j; + for ( i = 1; i <= nbFaces ; ++i ) { const Element2d& elem = ngMesh->SurfaceElement(i); vector nodes( elem.GetNP() ); - for (int j=1; j <= elem.GetNP(); ++j) + for (j=1; j <= elem.GetNP(); ++j) { int pind = elem.PNum(j); + if ( pind-1 < 0 ) + break; const SMDS_MeshNode* node = nodeVec.at(pind-1); if ( reverse ) nodes[ nodes.size()-j ] = node; @@ -428,17 +543,108 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, meshDS->SetNodeOnFace((SMDS_MeshNode*)node, faceID, pgi.u, pgi.v); } } - SMDS_MeshFace* face = 0; - if ( elem.GetType() == TRIG ) - face = helper.AddFace(nodes[0],nodes[1],nodes[2]); - else - face = helper.AddFace(nodes[0],nodes[1],nodes[2],nodes[3]); + if ( j > elem.GetNP() ) + { + SMDS_MeshFace* face = 0; + if ( elem.GetType() == TRIG ) + face = helper.AddFace(nodes[0],nodes[1],nodes[2]); + else + face = helper.AddFace(nodes[0],nodes[1],nodes[2],nodes[3]); + } + } + + return !err; +} + +#ifdef WITH_SMESH_CANCEL_COMPUTE +void NETGENPlugin_NETGEN_2D_ONLY::CancelCompute() +{ + SMESH_Algo::CancelCompute(); + netgen::multithread.terminate = 1; +} +#endif + +//============================================================================= +/*! + * + */ +//============================================================================= + +bool NETGENPlugin_NETGEN_2D_ONLY::Evaluate(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap) +{ + TopoDS_Face F = TopoDS::Face(aShape); + if(F.IsNull()) + return false; + + // collect info from edges + int nb0d = 0, nb1d = 0; + bool IsQuadratic = false; + bool IsFirst = true; + double fullLen = 0.0; + TopTools_MapOfShape tmpMap; + for (TopExp_Explorer exp(F, TopAbs_EDGE); exp.More(); exp.Next()) { + TopoDS_Edge E = TopoDS::Edge(exp.Current()); + if( tmpMap.Contains(E) ) + continue; + tmpMap.Add(E); + SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); + MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); + if( anIt==aResMap.end() ) { + SMESH_subMesh *sm = aMesh.GetSubMesh(F); + SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); + smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); + return false; + } + std::vector aVec = (*anIt).second; + nb0d += aVec[SMDSEntity_Node]; + nb1d += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); + double aLen = SMESH_Algo::EdgeLength(E); + fullLen += aLen; + if(IsFirst) { + IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]); + IsFirst = false; + } } + tmpMap.Clear(); - Ng_DeleteMesh((nglib::Ng_Mesh*)ngMesh); - Ng_Exit(); + // compute edge length + double ELen = 0; + if (_hypLengthFromEdges || !_hypLengthFromEdges && !_hypMaxElementArea) { + if ( nb1d > 0 ) + ELen = fullLen / nb1d; + } + if ( _hypMaxElementArea ) { + double maxArea = _hypMaxElementArea->GetMaxArea(); + ELen = sqrt(2. * maxArea/sqrt(3.0)); + } + GProp_GProps G; + BRepGProp::SurfaceProperties(F,G); + double anArea = G.Mass(); - NETGENPlugin_Mesher::RemoveTmpFiles(); + const int hugeNb = numeric_limits::max()/10; + if ( anArea / hugeNb > ELen*ELen ) + { + SMESH_subMesh *sm = aMesh.GetSubMesh(F); + SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); + smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated.\nToo small element length",this)); + return false; + } + int nbFaces = (int) ( anArea / ( ELen*ELen*sqrt(3.) / 4 ) ); + int nbNodes = (int) ( ( nbFaces*3 - (nb1d-1)*2 ) / 6 + 1 ); + std::vector aVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; i -#include //amv*/ - class StdMeshers_MaxElementArea; class StdMeshers_LengthFromEdges; -class StdMeshers_QuadranglePreference; -//class NETGENPlugin_Hypothesis; - -/*namespace netgen { - class OCCGeometry; -}*/ -/*namespace netgen { - class OCCGeometry; - extern int OCCGenerateMesh (OCCGeometry&, Mesh*&, int, int, char*); - extern MeshingParameters mparam; -}*/ - -//using namespace netgen; +class NETGENPlugin_Hypothesis_2D; /*! * \brief Mesher generating 2D elements on a geometrical face taking @@ -70,17 +52,18 @@ public: virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); - /*static TError AddSegmentsToMesh(netgen::Mesh& ngMesh, - OCCGeometry& geom, - const TSideVector& wires, - SMESH_MesherHelper& helper, - vector< const SMDS_MeshNode* > & nodeVec); //amv*/ +#ifdef WITH_SMESH_CANCEL_COMPUTE + virtual void CancelCompute(); +#endif + + virtual bool Evaluate(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap); protected: const StdMeshers_MaxElementArea* _hypMaxElementArea; const StdMeshers_LengthFromEdges* _hypLengthFromEdges; - const StdMeshers_QuadranglePreference* _hypQuadranglePreference; - // const NETGENPlugin_Hypothesis* _hypothesis; + const SMESHDS_Hypothesis* _hypQuadranglePreference; + const NETGENPlugin_Hypothesis_2D* _hypParameters; }; #endif diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY_i.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY_i.cxx index 6dac129..f1f9d94 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY_i.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY_i.cxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : NETGENPlugin_NETGEN_2D_ONLY_i.cxx // Author : Edward AGAPOV (OCC) @@ -38,8 +36,8 @@ //============================================================================= NETGENPlugin_NETGEN_2D_ONLY_i::NETGENPlugin_NETGEN_2D_ONLY_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 ), diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY_i.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY_i.hxx index 125a5dc..c34e06c 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY_i.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY_i.hxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : NETGENPlugin_NETGEN_2D_ONLY_i.cxx // Author : Edward AGAPOV (OCC) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_i.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_i.cxx index 3a113f6..9e2a944 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_i.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : idl implementation // File : NETGENPlugin_NETGEN_2D_i.cxx // Author : Michael Sazonov (OCN) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_i.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_i.hxx index 984f953..ebbfae9 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_i.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : idl implementation // File : NETGENPlugin_NETGEN_2D_i.hxx // Author : Michael Sazonov (OCN) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index 0400de6..e923afb 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -1,36 +1,36 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + //============================================================================= // File : NETGENPlugin_NETGEN_3D.cxx // Moved here from SMESH_NETGEN_3D.cxx // Created : lundi 27 Janvier 2003 // Author : Nadir BOUHAMOU (CEA) // Project : SALOME -// $Header$ //============================================================================= // #include "NETGENPlugin_NETGEN_3D.hxx" -#include "NETGENPlugin_Mesher.hxx" +#include "NETGENPlugin_Hypothesis.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" @@ -40,11 +40,17 @@ #include "SMESH_Gen.hxx" #include "SMESH_Mesh.hxx" #include "SMESH_MesherHelper.hxx" +#include "SMESH_MeshEditor.hxx" #include "StdMeshers_QuadToTriaAdaptor.hxx" +#include "StdMeshers_MaxElementVolume.hxx" +#include "StdMeshers_ViscousLayers.hxx" +#include #include +#include #include #include +#include #include #include @@ -60,10 +66,20 @@ Netgen include files */ +#ifndef OCCGEOMETRY +#define OCCGEOMETRY +#endif +#include namespace nglib { #include } +namespace netgen { + extern int OCCGenerateMesh (OCCGeometry&, Mesh*&, int, int, char*); + extern MeshingParameters mparam; + extern volatile multithreadt multithread; +} using namespace nglib; +using namespace std; //============================================================================= /*! @@ -72,17 +88,21 @@ using namespace nglib; //============================================================================= NETGENPlugin_NETGEN_3D::NETGENPlugin_NETGEN_3D(int hypId, int studyId, - SMESH_Gen* gen) + SMESH_Gen* gen) : SMESH_3D_Algo(hypId, studyId, gen) { MESSAGE("NETGENPlugin_NETGEN_3D::NETGENPlugin_NETGEN_3D"); _name = "NETGEN_3D"; _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type _compatibleHypothesis.push_back("MaxElementVolume"); + _compatibleHypothesis.push_back("NETGEN_Parameters"); + _compatibleHypothesis.push_back("ViscousLayers"); _maxElementVolume = 0.; _hypMaxElementVolume = NULL; + _hypParameters = NULL; + _viscousLayersHyp = NULL; _requireShape = false; // can work without shape } @@ -104,47 +124,51 @@ NETGENPlugin_NETGEN_3D::~NETGENPlugin_NETGEN_3D() */ //============================================================================= -bool NETGENPlugin_NETGEN_3D::CheckHypothesis - (SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, - SMESH_Hypothesis::Hypothesis_Status& aStatus) +bool NETGENPlugin_NETGEN_3D::CheckHypothesis (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + Hypothesis_Status& aStatus) { MESSAGE("NETGENPlugin_NETGEN_3D::CheckHypothesis"); _hypMaxElementVolume = NULL; + _hypParameters = NULL; + _viscousLayersHyp = NULL; _maxElementVolume = DBL_MAX; list::const_iterator itl; const SMESHDS_Hypothesis* theHyp; - const list& hyps = GetUsedHypothesis(aMesh, aShape); - int nbHyp = hyps.size(); - if (!nbHyp) + const list& hyps = + GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliary=*/false); + list ::const_iterator h = hyps.begin(); + if ( h == hyps.end()) { aStatus = SMESH_Hypothesis::HYP_OK; - //aStatus = SMESH_Hypothesis::HYP_MISSING; return true; // can work with no hypothesis } - itl = hyps.begin(); - theHyp = (*itl); // use only the first hypothesis - - string hypName = theHyp->GetName(); - - bool isOk = false; - - if (hypName == "MaxElementVolume") + aStatus = HYP_OK; + for ( ; h != hyps.end(); ++h ) { - _hypMaxElementVolume = static_cast (theHyp); - ASSERT(_hypMaxElementVolume); - _maxElementVolume = _hypMaxElementVolume->GetMaxVolume(); - isOk =true; - aStatus = SMESH_Hypothesis::HYP_OK; + if ( !_hypMaxElementVolume ) + _hypMaxElementVolume = dynamic_cast< const StdMeshers_MaxElementVolume*> ( *h ); + if ( !_viscousLayersHyp ) + _viscousLayersHyp = dynamic_cast< const StdMeshers_ViscousLayers*> ( *h ); + if ( ! _hypParameters ) + _hypParameters = dynamic_cast< const NETGENPlugin_Hypothesis*> ( *h ); + + if ( *h != _hypMaxElementVolume && + *h != _viscousLayersHyp && + *h != _hypParameters) + aStatus = HYP_INCOMPATIBLE; } - else - aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE; + if ( _hypMaxElementVolume && _hypParameters ) + aStatus = HYP_INCOMPATIBLE; - return isOk; + if ( _hypMaxElementVolume ) + _maxElementVolume = _hypMaxElementVolume->GetMaxVolume(); + + return aStatus == HYP_OK; } //============================================================================= @@ -156,191 +180,143 @@ bool NETGENPlugin_NETGEN_3D::CheckHypothesis bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { +#ifdef WITH_SMESH_CANCEL_COMPUTE + netgen::multithread.terminate = 0; +#endif MESSAGE("NETGENPlugin_NETGEN_3D::Compute with maxElmentsize = " << _maxElementVolume); SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); - const int invalid_ID = -1; + SMESH_MesherHelper helper(aMesh); + bool _quadraticMesh = helper.IsQuadraticSubMesh(aShape); + helper.SetElementsOnShape( true ); - SMESH::Controls::Area areaControl; - SMESH::Controls::TSequenceOfXYZ nodesCoords; + int Netgen_NbOfNodes = 0; - // ------------------------------------------------------------------- - // get triangles on aShell and make a map of nodes to Netgen node IDs - // ------------------------------------------------------------------- + double Netgen_point[3]; + int Netgen_triangle[3]; - SMESH_MesherHelper helper(aMesh); - SMESH_MesherHelper* myTool = &helper; - bool _quadraticMesh = myTool->IsQuadraticSubMesh(aShape); + NETGENPlugin_NetgenLibWrapper ngLib; + Ng_Mesh * Netgen_mesh = ngLib._ngMesh; - typedef map< const SMDS_MeshNode*, int> TNodeToIDMap; - TNodeToIDMap nodeToNetgenID; - list< const SMDS_MeshElement* > triangles; - list< bool > isReversed; // orientation of triangles + // vector of nodes in which node index == netgen ID + vector< const SMDS_MeshNode* > nodeVec; + { + const int invalid_ID = -1; - TopAbs_ShapeEnum mainType = aMesh.GetShapeToMesh().ShapeType(); - bool checkReverse = ( mainType == TopAbs_COMPOUND || mainType == TopAbs_COMPSOLID ); + SMESH::Controls::Area areaControl; + SMESH::Controls::TSequenceOfXYZ nodesCoords; - // for the degeneraged edge: ignore all but one node on it; - // map storing ids of degen edges and vertices and their netgen id: - map< int, int* > degenShapeIdToPtrNgId; - map< int, int* >::iterator shId_ngId; - list< int > degenNgIds; + // maps nodes to ng ID + typedef map< const SMDS_MeshNode*, int, TIDCompare > TNodeToIDMap; + typedef TNodeToIDMap::value_type TN2ID; + TNodeToIDMap nodeToNetgenID; - StdMeshers_QuadToTriaAdaptor Adaptor; - Adaptor.Compute(aMesh,aShape); + // find internal shapes + NETGENPlugin_Internals internals( aMesh, aShape, /*is3D=*/true ); - for (TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next()) - { - const TopoDS_Shape& aShapeFace = exp.Current(); - const SMESHDS_SubMesh * aSubMeshDSFace = meshDS->MeshElements( aShapeFace ); - if ( aSubMeshDSFace ) + // --------------------------------- + // Feed the Netgen with surface mesh + // --------------------------------- + + TopAbs_ShapeEnum mainType = aMesh.GetShapeToMesh().ShapeType(); + bool checkReverse = ( mainType == TopAbs_COMPOUND || mainType == TopAbs_COMPSOLID ); + + SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh )); + if ( _viscousLayersHyp ) { + proxyMesh = _viscousLayersHyp->Compute( aMesh, aShape ); + if ( !proxyMesh ) + return false; + } + if ( aMesh.NbQuadrangles() > 0 ) + { + StdMeshers_QuadToTriaAdaptor* Adaptor = new StdMeshers_QuadToTriaAdaptor; + Adaptor->Compute(aMesh,aShape,proxyMesh.get()); + proxyMesh.reset( Adaptor ); + } + + for ( TopExp_Explorer exFa( aShape, TopAbs_FACE ); exFa.More(); exFa.Next()) + { + const TopoDS_Shape& aShapeFace = exFa.Current(); + int faceID = meshDS->ShapeToIndex( aShapeFace ); + bool isInternalFace = internals.isInternalShape( faceID ); bool isRev = false; - if ( checkReverse && helper.NbAncestors(aShapeFace, aMesh, aShape.ShapeType()) > 1 ) + if ( checkReverse && !isInternalFace && + helper.NbAncestors(aShapeFace, aMesh, aShape.ShapeType()) > 1 ) // IsReversedSubMesh() can work wrong on strongly curved faces, // so we use it as less as possible isRev = SMESH_Algo::IsReversedSubMesh( TopoDS::Face(aShapeFace), meshDS ); + const SMESHDS_SubMesh * aSubMeshDSFace = proxyMesh->GetSubMesh( aShapeFace ); + if ( !aSubMeshDSFace ) continue; SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); - while ( iteratorElem->more() ) // loop on elements on a face + while ( iteratorElem->more() ) // loop on elements on a geom face { - // check element + // check mesh face const SMDS_MeshElement* elem = iteratorElem->next(); if ( !elem ) return error( COMPERR_BAD_INPUT_MESH, "Null element encounters"); - bool isTraingle = ( elem->NbNodes()==3 || (_quadraticMesh && elem->NbNodes()==6 )); - if ( !isTraingle ) { - //return error( COMPERR_BAD_INPUT_MESH, - // SMESH_Comment("Not triangle element ")<GetID()); - // using adaptor - std::list faces = Adaptor.GetTriangles(elem); - if(faces.size()==0) { - return error( COMPERR_BAD_INPUT_MESH, - SMESH_Comment("Not triangles in adaptor for element ")<GetID()); - } - std::list::iterator itf = faces.begin(); - for(; itf!=faces.end(); itf++ ) { - triangles.push_back( (*itf) ); - isReversed.push_back( isRev ); - // put triange's nodes to nodeToNetgenID map - SMDS_ElemIteratorPtr triangleNodesIt = (*itf)->nodesIterator(); - while ( triangleNodesIt->more() ) { - const SMDS_MeshNode * node = - static_cast(triangleNodesIt->next()); - if(myTool->IsMedium(node)) - continue; - nodeToNetgenID.insert( make_pair( node, invalid_ID )); - } + if ( elem->NbCornerNodes() != 3 ) + return error( COMPERR_BAD_INPUT_MESH, "Not triangle element encounters"); + + // Add nodes of triangles and triangles them-selves to netgen mesh + + // add three nodes of triangle + bool hasDegen = false; + for ( int iN = 0; iN < 3; ++iN ) + { + const SMDS_MeshNode* node = elem->GetNode( iN ); + const int shapeID = node->getshapeId(); + if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE && + helper.IsDegenShape( shapeID )) + { + // ignore all nodes on degeneraged edge and use node on its vertex instead + TopoDS_Shape vertex = TopoDS_Iterator( meshDS->IndexToShape( shapeID )).Value(); + node = SMESH_Algo::VertexNode( TopoDS::Vertex( vertex ), meshDS ); + hasDegen = true; } - } - else { - // keep a triangle - triangles.push_back( elem ); - isReversed.push_back( isRev ); - // put elem nodes to nodeToNetgenID map - SMDS_ElemIteratorPtr triangleNodesIt = elem->nodesIterator(); - while ( triangleNodesIt->more() ) { - const SMDS_MeshNode * node = - static_cast(triangleNodesIt->next()); - if(myTool->IsMedium(node)) - continue; - nodeToNetgenID.insert( make_pair( node, invalid_ID )); + int& ngID = nodeToNetgenID.insert(TN2ID( node, invalid_ID )).first->second; + if ( ngID == invalid_ID ) + { + ngID = ++Netgen_NbOfNodes; + Netgen_point [ 0 ] = node->X(); + Netgen_point [ 1 ] = node->Y(); + Netgen_point [ 2 ] = node->Z(); + Ng_AddPoint(Netgen_mesh, Netgen_point); } + Netgen_triangle[ isRev ? 2-iN : iN ] = ngID; } -#ifdef _DEBUG_ - // check if a trainge is degenerated - areaControl.GetPoints( elem, nodesCoords ); - double area = areaControl.GetValue( nodesCoords ); - if ( area <= DBL_MIN ) { - MESSAGE( "Warning: Degenerated " << elem ); - } -#endif - } - // look for degeneraged edges and vetices - for (TopExp_Explorer expE(aShapeFace,TopAbs_EDGE);expE.More();expE.Next()) - { - TopoDS_Edge aShapeEdge = TopoDS::Edge( expE.Current() ); - if ( BRep_Tool::Degenerated( aShapeEdge )) - { - degenNgIds.push_back( invalid_ID ); - int* ptrIdOnEdge = & degenNgIds.back(); - // remember edge id - int edgeID = meshDS->ShapeToIndex( aShapeEdge ); - degenShapeIdToPtrNgId.insert( make_pair( edgeID, ptrIdOnEdge )); - // remember vertex id - int vertexID = meshDS->ShapeToIndex( TopExp::FirstVertex( aShapeEdge )); - degenShapeIdToPtrNgId.insert( make_pair( vertexID, ptrIdOnEdge )); - } - } - } - } - // --------------------------------- - // Feed the Netgen with surface mesh - // --------------------------------- - - int Netgen_NbOfNodes = 0; - int Netgen_param2ndOrder = 0; - double Netgen_paramFine = 1.; - double Netgen_paramSize = pow( 72, 1/6. ) * pow( _maxElementVolume, 1/3. ); - - double Netgen_point[3]; - int Netgen_triangle[3]; - int Netgen_tetrahedron[4]; + // add triangle + if ( hasDegen && (Netgen_triangle[0] == Netgen_triangle[1] || + Netgen_triangle[0] == Netgen_triangle[2] || + Netgen_triangle[2] == Netgen_triangle[1] )) + continue; - Ng_Init(); + Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); - Ng_Mesh * Netgen_mesh = Ng_NewMesh(); + if ( isInternalFace && !proxyMesh->IsTemporary( elem )) + { + swap( Netgen_triangle[1], Netgen_triangle[2] ); + Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); + } + } // loop on elements on a face + } // loop on faces of a SOLID or SHELL - // set nodes and remember thier netgen IDs - bool isDegen = false, hasDegen = !degenShapeIdToPtrNgId.empty(); - TNodeToIDMap::iterator n_id = nodeToNetgenID.begin(); - for ( ; n_id != nodeToNetgenID.end(); ++n_id ) - { - const SMDS_MeshNode* node = n_id->first; - - // ignore nodes on degenerated edge - if ( hasDegen ) { - int shapeId = node->GetPosition()->GetShapeId(); - shId_ngId = degenShapeIdToPtrNgId.find( shapeId ); - isDegen = ( shId_ngId != degenShapeIdToPtrNgId.end() ); - if ( isDegen && *(shId_ngId->second) != invalid_ID ) { - n_id->second = *(shId_ngId->second); - continue; - } - } - Netgen_point [ 0 ] = node->X(); - Netgen_point [ 1 ] = node->Y(); - Netgen_point [ 2 ] = node->Z(); - Ng_AddPoint(Netgen_mesh, Netgen_point); - n_id->second = ++Netgen_NbOfNodes; // set netgen ID - - if ( isDegen ) // all nodes on a degen edge get one netgen ID - *(shId_ngId->second) = n_id->second; - } + // insert old nodes into nodeVec + nodeVec.resize( nodeToNetgenID.size() + 1, 0 ); + TNodeToIDMap::iterator n_id = nodeToNetgenID.begin(); + for ( ; n_id != nodeToNetgenID.end(); ++n_id ) + nodeVec[ n_id->second ] = n_id->first; + nodeToNetgenID.clear(); - // set triangles - list< const SMDS_MeshElement* >::iterator tria = triangles.begin(); - list< bool >::iterator reverse = isReversed.begin(); - for ( ; tria != triangles.end(); ++tria, ++reverse ) - { - int i = 0; - SMDS_ElemIteratorPtr triangleNodesIt = (*tria)->nodesIterator(); - while ( triangleNodesIt->more() ) { - const SMDS_MeshNode * node = - static_cast(triangleNodesIt->next()); - if(myTool->IsMedium(node)) - continue; - Netgen_triangle[ *reverse ? 2 - i : i ] = nodeToNetgenID[ node ]; - ++i; - } - if ( !hasDegen || - // ignore degenerated triangles, they have 2 or 3 same ids - (Netgen_triangle[0] != Netgen_triangle[1] && - Netgen_triangle[0] != Netgen_triangle[2] && - Netgen_triangle[2] != Netgen_triangle[1] )) + if ( internals.hasInternalVertexInSolid() ) { - Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); + netgen::OCCGeometry occgeo; + NETGENPlugin_Mesher::addIntVerticesInSolids( occgeo, + (netgen::Mesh&) *Netgen_mesh, + nodeVec, + internals); } } @@ -348,43 +324,95 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, // Generate the volume mesh // ------------------------- - Ng_Meshing_Parameters Netgen_param; + return compute( aMesh, helper, nodeVec, Netgen_mesh); +} - Netgen_param.secondorder = Netgen_param2ndOrder; - Netgen_param.fineness = Netgen_paramFine; - Netgen_param.maxh = Netgen_paramSize; +//================================================================================ +/*! + * \brief set parameters and generate the volume mesh + */ +//================================================================================ - Ng_Result status; +bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, + SMESH_MesherHelper& helper, + vector< const SMDS_MeshNode* >& nodeVec, + Ng_Mesh * Netgen_mesh) +{ +#ifdef WITH_SMESH_CANCEL_COMPUTE + netgen::multithread.terminate = 0; +#endif + netgen::Mesh* ngMesh = (netgen::Mesh*)Netgen_mesh; + int Netgen_NbOfNodes = Ng_GetNP(Netgen_mesh); + + char *optstr = 0; + int startWith = netgen::MESHCONST_MESHVOLUME; + int endWith = netgen::MESHCONST_OPTVOLUME; + int err = 1; - try { + NETGENPlugin_Mesher aMesher( &aMesh, helper.GetSubShape(), /*isVolume=*/true ); + netgen::OCCGeometry occgeo; + + if ( _hypParameters ) + { + aMesher.SetParameters( _hypParameters ); + if ( !_hypParameters->GetOptimize() ) + endWith = netgen::MESHCONST_MESHVOLUME; + } + else if ( _hypMaxElementVolume ) + { + netgen::mparam.maxh = pow( 72, 1/6. ) * pow( _maxElementVolume, 1/3. ); + } + else if ( aMesh.HasShapeToMesh() ) + { + aMesher.PrepareOCCgeometry( occgeo, helper.GetSubShape(), aMesh ); + netgen::mparam.maxh = occgeo.GetBoundingBox().Diam()/2; + } + else + { + netgen::Point3d pmin, pmax; + ngMesh->GetBox (pmin, pmax); + netgen::mparam.maxh = Dist(pmin, pmax)/2; + } + + if ( !_hypParameters && aMesh.HasShapeToMesh() ) + { + netgen::mparam.minh = aMesher.GetDefaultMinSize( helper.GetSubShape(), netgen::mparam.maxh ); + } + + try + { #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 OCC_CATCH_SIGNALS; #endif - status = Ng_GenerateVolumeMesh(Netgen_mesh, &Netgen_param); - } - catch (Standard_Failure& exc) { - error(COMPERR_OCC_EXCEPTION, exc.GetMessageString()); - status = NG_VOLUME_FAILURE; + ngMesh->CalcLocalH(); + err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr); +#ifdef WITH_SMESH_CANCEL_COMPUTE + if(netgen::multithread.terminate) + return false; +#endif + if ( err ) + error(SMESH_Comment("Error in netgen::OCCGenerateMesh() at ") << netgen::multithread.task); } - catch (...) { - error("Exception in Ng_GenerateVolumeMesh()"); - status = NG_VOLUME_FAILURE; + catch (Standard_Failure& ex) + { + SMESH_Comment str("Exception in netgen::OCCGenerateMesh()"); + str << " at " << netgen::multithread.task + << ": " << ex.DynamicType()->Name(); + if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) + str << ": " << ex.GetMessageString(); + error(str); } - if ( GetComputeError()->IsOK() ) { - switch ( status ) { - case NG_SURFACE_INPUT_ERROR:error( status, "NG_SURFACE_INPUT_ERROR"); - case NG_VOLUME_FAILURE: error( status, "NG_VOLUME_FAILURE"); - case NG_STL_INPUT_ERROR: error( status, "NG_STL_INPUT_ERROR"); - case NG_SURFACE_FAILURE: error( status, "NG_SURFACE_FAILURE"); - case NG_FILE_NOT_FOUND: error( status, "NG_FILE_NOT_FOUND"); - }; + catch (...) + { + SMESH_Comment str("Exception in netgen::OCCGenerateMesh()"); + str << " at " << netgen::multithread.task; + error(str); } int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh); + int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh); - int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh); - - MESSAGE("End of Volume Mesh Generation. status=" << status << + MESSAGE("End of Volume Mesh Generation. err=" << err << ", nb new nodes: " << Netgen_NbOfNodesNew - Netgen_NbOfNodes << ", nb tetra: " << Netgen_NbOfTetra); @@ -392,114 +420,68 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, // Feed back the SMESHDS with the generated Nodes and Volume Elements // ------------------------------------------------------------------- + if ( err ) + { + SMESH_ComputeErrorPtr ce = NETGENPlugin_Mesher::readErrors(nodeVec); + if ( ce && !ce->myBadElements.empty() ) + error( ce ); + } + bool isOK = ( /*status == NG_OK &&*/ Netgen_NbOfTetra > 0 );// get whatever built if ( isOK ) { - // vector of nodes in which node index == netgen ID - vector< const SMDS_MeshNode* > nodeVec ( Netgen_NbOfNodesNew + 1 ); - // insert old nodes into nodeVec - for ( n_id = nodeToNetgenID.begin(); n_id != nodeToNetgenID.end(); ++n_id ) { - nodeVec.at( n_id->second ) = n_id->first; - } + double Netgen_point[3]; + int Netgen_tetrahedron[4]; + // create and insert new nodes into nodeVec + nodeVec.resize( Netgen_NbOfNodesNew + 1, 0 ); int nodeIndex = Netgen_NbOfNodes + 1; - int shapeID = meshDS->ShapeToIndex( aShape ); for ( ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) { Ng_GetPoint( Netgen_mesh, nodeIndex, Netgen_point ); - SMDS_MeshNode * node = meshDS->AddNode(Netgen_point[0], - Netgen_point[1], - Netgen_point[2]); - meshDS->SetNodeInVolume(node, shapeID); - nodeVec.at(nodeIndex) = node; + nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], Netgen_point[1], Netgen_point[2]); } // create tetrahedrons for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) { Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron); - SMDS_MeshVolume * elt = myTool->AddVolume (nodeVec.at( Netgen_tetrahedron[0] ), - nodeVec.at( Netgen_tetrahedron[1] ), - nodeVec.at( Netgen_tetrahedron[2] ), - nodeVec.at( Netgen_tetrahedron[3] )); - meshDS->SetMeshElementOnShape(elt, shapeID ); + try + { + helper.AddVolume (nodeVec.at( Netgen_tetrahedron[0] ), + nodeVec.at( Netgen_tetrahedron[1] ), + nodeVec.at( Netgen_tetrahedron[2] ), + nodeVec.at( Netgen_tetrahedron[3] )); + } + catch (...) + { + } } } - Ng_DeleteMesh(Netgen_mesh); - Ng_Exit(); - - NETGENPlugin_Mesher::RemoveTmpFiles(); - - return (status == NG_OK); + return !err; } -bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, +//================================================================================ +/*! + * \brief Compute tetrahedral mesh from 2D mesh without geometry + */ +//================================================================================ + +bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, SMESH_MesherHelper* aHelper) { MESSAGE("NETGENPlugin_NETGEN_3D::Compute with maxElmentsize = " << _maxElementVolume); const int invalid_ID = -1; bool _quadraticMesh = false; - typedef map< const SMDS_MeshNode*, int> TNodeToIDMap; - TNodeToIDMap nodeToNetgenID; - list< const SMDS_MeshElement* > triangles; - SMESHDS_Mesh* MeshDS = aHelper->GetMeshDS(); SMESH_MesherHelper::MType MeshType = aHelper->IsQuadraticMesh(); - + if(MeshType == SMESH_MesherHelper::COMP) return error( COMPERR_BAD_INPUT_MESH, SMESH_Comment("Mesh with linear and quadratic elements given.")); else if (MeshType == SMESH_MesherHelper::QUADRATIC) _quadraticMesh = true; - - StdMeshers_QuadToTriaAdaptor Adaptor; - Adaptor.Compute(aMesh); - - SMDS_FaceIteratorPtr iteratorFace = MeshDS->facesIterator(); - while(iteratorFace->more()) { - // check element - const SMDS_MeshElement* elem = iteratorFace->next(); - if ( !elem ) - return error( COMPERR_BAD_INPUT_MESH, "Null element encounters"); - bool isTraingle = ( elem->NbNodes()==3 || (_quadraticMesh && elem->NbNodes()==6 )); - if ( !isTraingle ) { - //return error( COMPERR_BAD_INPUT_MESH, - // SMESH_Comment("Not triangle element ")<GetID()); - // using adaptor - std::list faces = Adaptor.GetTriangles(elem); - if(faces.size()==0) { - return error( COMPERR_BAD_INPUT_MESH, - SMESH_Comment("Not triangles in adaptor for element ")<GetID()); - } - std::list::iterator itf = faces.begin(); - for(; itf!=faces.end(); itf++ ) { - triangles.push_back( (*itf) ); - // put triange's nodes to nodeToNetgenID map - SMDS_ElemIteratorPtr triangleNodesIt = (*itf)->nodesIterator(); - while ( triangleNodesIt->more() ) { - const SMDS_MeshNode * node = - static_cast(triangleNodesIt->next()); - if(aHelper->IsMedium(node)) - continue; - nodeToNetgenID.insert( make_pair( node, invalid_ID )); - } - } - } - else { - // keep a triangle - triangles.push_back( elem ); - // put elem nodes to nodeToNetgenID map - SMDS_ElemIteratorPtr triangleNodesIt = elem->nodesIterator(); - while ( triangleNodesIt->more() ) { - const SMDS_MeshNode * node = - static_cast(triangleNodesIt->next()); - if(aHelper->IsMedium(node)) - continue; - nodeToNetgenID.insert( make_pair( node, invalid_ID )); - } - } - } // --------------------------------- // Feed the Netgen with surface mesh @@ -514,121 +496,160 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, int Netgen_triangle[3]; int Netgen_tetrahedron[4]; - Ng_Init(); + NETGENPlugin_NetgenLibWrapper ngLib; + Ng_Mesh * Netgen_mesh = ngLib._ngMesh; - Ng_Mesh * Netgen_mesh = Ng_NewMesh(); - - // set nodes and remember thier netgen IDs - - TNodeToIDMap::iterator n_id = nodeToNetgenID.begin(); - for ( ; n_id != nodeToNetgenID.end(); ++n_id ) + SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh )); + if ( aMesh.NbQuadrangles() > 0 ) { - const SMDS_MeshNode* node = n_id->first; - - Netgen_point [ 0 ] = node->X(); - Netgen_point [ 1 ] = node->Y(); - Netgen_point [ 2 ] = node->Z(); - Ng_AddPoint(Netgen_mesh, Netgen_point); - n_id->second = ++Netgen_NbOfNodes; // set netgen ID - + StdMeshers_QuadToTriaAdaptor* Adaptor = new StdMeshers_QuadToTriaAdaptor; + Adaptor->Compute(aMesh); + proxyMesh.reset( Adaptor ); } - // set triangles - list< const SMDS_MeshElement* >::iterator tria = triangles.begin(); - for ( ; tria != triangles.end(); ++tria) + // maps nodes to ng ID + typedef map< const SMDS_MeshNode*, int, TIDCompare > TNodeToIDMap; + typedef TNodeToIDMap::value_type TN2ID; + TNodeToIDMap nodeToNetgenID; + + SMDS_ElemIteratorPtr fIt = proxyMesh->GetFaces(); + while( fIt->more()) { - int i = 0; - SMDS_ElemIteratorPtr triangleNodesIt = (*tria)->nodesIterator(); - while ( triangleNodesIt->more() ) { - const SMDS_MeshNode * node = - static_cast(triangleNodesIt->next()); - if(aHelper->IsMedium(node)) - continue; - Netgen_triangle[ i ] = nodeToNetgenID[ node ]; - ++i; + // check element + const SMDS_MeshElement* elem = fIt->next(); + if ( !elem ) + return error( COMPERR_BAD_INPUT_MESH, "Null element encounters"); + if ( elem->NbCornerNodes() != 3 ) + return error( COMPERR_BAD_INPUT_MESH, "Not triangle element encounters"); + + // add three nodes of triangle + for ( int iN = 0; iN < 3; ++iN ) + { + const SMDS_MeshNode* node = elem->GetNode( iN ); + int& ngID = nodeToNetgenID.insert(TN2ID( node, invalid_ID )).first->second; + if ( ngID == invalid_ID ) + { + ngID = ++Netgen_NbOfNodes; + Netgen_point [ 0 ] = node->X(); + Netgen_point [ 1 ] = node->Y(); + Netgen_point [ 2 ] = node->Z(); + Ng_AddPoint(Netgen_mesh, Netgen_point); + } + Netgen_triangle[ iN ] = ngID; } - Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); } + proxyMesh.reset(); // delete tmp faces + + // vector of nodes in which node index == netgen ID + vector< const SMDS_MeshNode* > nodeVec ( nodeToNetgenID.size() + 1 ); + // insert old nodes into nodeVec + TNodeToIDMap::iterator n_id = nodeToNetgenID.begin(); + for ( ; n_id != nodeToNetgenID.end(); ++n_id ) + nodeVec.at( n_id->second ) = n_id->first; + nodeToNetgenID.clear(); // ------------------------- // Generate the volume mesh // ------------------------- - Ng_Meshing_Parameters Netgen_param; - - Netgen_param.secondorder = Netgen_param2ndOrder; - Netgen_param.fineness = Netgen_paramFine; - Netgen_param.maxh = Netgen_paramSize; - - Ng_Result status; + return compute( aMesh, *aHelper, nodeVec, Netgen_mesh); +} - try { -#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 - OCC_CATCH_SIGNALS; +#ifdef WITH_SMESH_CANCEL_COMPUTE +void NETGENPlugin_NETGEN_3D::CancelCompute() +{ + SMESH_Algo::CancelCompute(); + netgen::multithread.terminate = 1; +} #endif - status = Ng_GenerateVolumeMesh(Netgen_mesh, &Netgen_param); - } - catch (Standard_Failure& exc) { - error(COMPERR_OCC_EXCEPTION, exc.GetMessageString()); - status = NG_VOLUME_FAILURE; - } - catch (...) { - error("Bad mesh input!!!"); - status = NG_VOLUME_FAILURE; - } - if ( GetComputeError()->IsOK() ) { - error( status, "Bad mesh input!!!"); - } - int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh); - - int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh); - - MESSAGE("End of Volume Mesh Generation. status=" << status << - ", nb new nodes: " << Netgen_NbOfNodesNew - Netgen_NbOfNodes << - ", nb tetra: " << Netgen_NbOfTetra); - - // ------------------------------------------------------------------- - // Feed back the SMESHDS with the generated Nodes and Volume Elements - // ------------------------------------------------------------------- +//============================================================================= +/*! + * + */ +//============================================================================= - bool isOK = ( Netgen_NbOfTetra > 0 );// get whatever built - if ( isOK ) - { - // vector of nodes in which node index == netgen ID - vector< const SMDS_MeshNode* > nodeVec ( Netgen_NbOfNodesNew + 1 ); - // insert old nodes into nodeVec - for ( n_id = nodeToNetgenID.begin(); n_id != nodeToNetgenID.end(); ++n_id ) { - nodeVec.at( n_id->second ) = n_id->first; - } - // create and insert new nodes into nodeVec - int nodeIndex = Netgen_NbOfNodes + 1; - - for ( ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) - { - Ng_GetPoint( Netgen_mesh, nodeIndex, Netgen_point ); - SMDS_MeshNode * node = aHelper->AddNode(Netgen_point[0], - Netgen_point[1], - Netgen_point[2]); - nodeVec.at(nodeIndex) = node; +bool NETGENPlugin_NETGEN_3D::Evaluate(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + MapShapeNbElems& aResMap) +{ + int nbtri = 0, nbqua = 0; + double fullArea = 0.0; + for (TopExp_Explorer expF(aShape, TopAbs_FACE); expF.More(); expF.Next()) { + TopoDS_Face F = TopoDS::Face( expF.Current() ); + SMESH_subMesh *sm = aMesh.GetSubMesh(F); + MapShapeNbElemsItr anIt = aResMap.find(sm); + if( anIt==aResMap.end() ) { + SMESH_ComputeErrorPtr& smError = sm->GetComputeError(); + smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); + return false; } + std::vector aVec = (*anIt).second; + nbtri += Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]); + nbqua += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); + GProp_GProps G; + BRepGProp::SurfaceProperties(F,G); + double anArea = G.Mass(); + fullArea += anArea; + } - // create tetrahedrons - for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) - { - Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron); - aHelper->AddVolume (nodeVec.at( Netgen_tetrahedron[0] ), - nodeVec.at( Netgen_tetrahedron[1] ), - nodeVec.at( Netgen_tetrahedron[2] ), - nodeVec.at( Netgen_tetrahedron[3] )); + // collect info from edges + int nb0d_e = 0, nb1d_e = 0; + bool IsQuadratic = false; + bool IsFirst = true; + TopTools_MapOfShape tmpMap; + for (TopExp_Explorer expF(aShape, TopAbs_EDGE); expF.More(); expF.Next()) { + TopoDS_Edge E = TopoDS::Edge(expF.Current()); + if( tmpMap.Contains(E) ) + continue; + tmpMap.Add(E); + SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(expF.Current()); + MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); + if( anIt==aResMap.end() ) { + SMESH_ComputeErrorPtr& smError = aSubMesh->GetComputeError(); + smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED, + "Submesh can not be evaluated",this)); + return false; + } + std::vector aVec = (*anIt).second; + nb0d_e += aVec[SMDSEntity_Node]; + nb1d_e += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); + if(IsFirst) { + IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]); + IsFirst = false; } } - - Ng_DeleteMesh(Netgen_mesh); - Ng_Exit(); - - NETGENPlugin_Mesher::RemoveTmpFiles(); + tmpMap.Clear(); + + double ELen_face = sqrt(2.* ( fullArea/(nbtri+nbqua*2) ) / sqrt(3.0) ); + double ELen_vol = pow( 72, 1/6. ) * pow( _maxElementVolume, 1/3. ); + double ELen = Min(ELen_vol,ELen_face*2); + + GProp_GProps G; + BRepGProp::VolumeProperties(aShape,G); + double aVolume = G.Mass(); + double tetrVol = 0.1179*ELen*ELen*ELen; + double CoeffQuality = 0.9; + int nbVols = int( aVolume/tetrVol/CoeffQuality ); + int nb1d_f = (nbtri*3 + nbqua*4 - nb1d_e) / 2; + int nb1d_in = (nbVols*6 - nb1d_e - nb1d_f ) / 5; + std::vector aVec(SMDSEntity_Last); + for(int i=SMDSEntity_Node; i& nodeVec, + nglib::Ng_Mesh* ngMesh); + double _maxElementVolume; + const NETGENPlugin_Hypothesis * _hypParameters; const StdMeshers_MaxElementVolume* _hypMaxElementVolume; + const StdMeshers_ViscousLayers* _viscousLayersHyp; }; #endif diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.cxx index 11b3473..c9d64c8 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : NETGENPlugin_NETGEN_3D_i.cxx // Moved here from SMESH_NETGEN_3D_i.cxx @@ -43,8 +44,8 @@ using namespace std; //============================================================================= NETGENPlugin_NETGEN_3D_i::NETGENPlugin_NETGEN_3D_i( PortableServer::POA_ptr thePOA, - int theStudyId, - ::SMESH_Gen* theGenImpl ) + int theStudyId, + ::SMESH_Gen* theGenImpl ) : SALOME::GenericObj_i( thePOA ), SMESH_Hypothesis_i( thePOA ), SMESH_Algo_i( thePOA ), @@ -52,8 +53,8 @@ NETGENPlugin_NETGEN_3D_i::NETGENPlugin_NETGEN_3D_i( PortableServer::POA_ptr theP { MESSAGE( "NETGENPlugin_NETGEN_3D_i::NETGENPlugin_NETGEN_3D_i" ); myBaseImpl = new ::NETGENPlugin_NETGEN_3D( theGenImpl->GetANewId(), - theStudyId, - theGenImpl ); + theStudyId, + theGenImpl ); } //============================================================================= diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.hxx index cbc660b..97d7609 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_i.hxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : NETGENPlugin_NETGEN_3D_i.hxx // Moved here from SMESH_NETGEN_3D_i.hxx diff --git a/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_2D.cxx b/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_2D.cxx index a54d2fb..dd4f81e 100644 --- a/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_2D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_2D.cxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_SimpleHypothesis_2D.cxx // Author : Edward AGAPOV @@ -49,7 +47,8 @@ NETGENPlugin_SimpleHypothesis_2D::NETGENPlugin_SimpleHypothesis_2D (int : SMESH_Hypothesis(hypId, studyId, gen), _nbSegments ((int)NETGENPlugin_Hypothesis::GetDefaultNbSegPerEdge()), _segmentLength(0), - _area (0.) + _area (0.), + _allowQuad (false) { _name = "NETGEN_SimpleParameters_2D"; _param_algo_dim = 2; @@ -120,6 +119,30 @@ void NETGENPlugin_SimpleHypothesis_2D::SetMaxElementArea(double area) } } +//======================================================================= +//function : SetAllowQuadrangles +//purpose : Enables/disables generation of quadrangular faces +//======================================================================= + +void NETGENPlugin_SimpleHypothesis_2D::SetAllowQuadrangles(bool toAllow) +{ + if ( _allowQuad != toAllow ) + { + _allowQuad = toAllow; + NotifySubMeshesHypothesisModification(); + } +} + +//======================================================================= +//function : GetAllowQuadrangles +//purpose : Returns true if generation of quadrangular faces is enabled +//======================================================================= + +bool NETGENPlugin_SimpleHypothesis_2D::GetAllowQuadrangles() const +{ + return _allowQuad; +} + //============================================================================= /*! * @@ -127,7 +150,7 @@ void NETGENPlugin_SimpleHypothesis_2D::SetMaxElementArea(double area) //============================================================================= ostream & NETGENPlugin_SimpleHypothesis_2D::SaveTo(ostream & save) { - save << _nbSegments << " " << _segmentLength << " " << _area; + save << _nbSegments << " " << _segmentLength << " " << _area << " " << _allowQuad; return save; } @@ -160,6 +183,8 @@ istream & NETGENPlugin_SimpleHypothesis_2D::LoadFrom(istream & load) else load.clear(ios::badbit | load.rdstate()); + load >> _allowQuad; + return load; } diff --git a/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_2D.hxx b/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_2D.hxx index 4ed9218..e4406f8 100644 --- a/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_2D.hxx +++ b/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_2D.hxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_SimpleHypothesis_2D.hxx // Author : Edward AGAPOV @@ -80,6 +78,15 @@ public: */ double GetMaxElementArea() const { return _area; } + /*! + * Enables/disables generation of quadrangular faces + */ + void SetAllowQuadrangles(bool toAllow); + /*! + * Returns true if generation of quadrangular faces is enabled + */ + bool GetAllowQuadrangles() const; + // Persistence virtual ostream & SaveTo(ostream & save); virtual istream & LoadFrom(istream & load); @@ -101,6 +108,7 @@ public: private: int _nbSegments; double _segmentLength, _area; + bool _allowQuad; }; #endif diff --git a/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_2D_i.cxx b/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_2D_i.cxx index fac763e..8cc6590 100644 --- a/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_2D_i.cxx +++ b/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_2D_i.cxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_SimpleHypothesis_2D_i.cxx // Author : Edward AGAPOV @@ -34,6 +32,8 @@ #include #include +#include + using namespace std; //============================================================================= @@ -84,7 +84,7 @@ void NETGENPlugin_SimpleHypothesis_2D_i::SetNumberOfSegments(CORBA::Short nb) catch (SALOME_Exception& S_ex) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); } - SMESH::TPythonDump() << _this() << ".SetNumberOfSegments( " << nb << " )"; + SMESH::TPythonDump() << _this() << ".SetNumberOfSegments( " << SMESH::TVar(nb) << " )"; } //============================================================================= @@ -115,7 +115,7 @@ void NETGENPlugin_SimpleHypothesis_2D_i::SetLocalLength(CORBA::Double segmentLen catch (SALOME_Exception& S_ex) { THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); } - SMESH::TPythonDump() << _this() << ".SetLocalLength( " << segmentLength << " )"; + SMESH::TPythonDump() << _this() << ".SetLocalLength( " << SMESH::TVar(segmentLength) << " )"; } //================================================================================ @@ -154,7 +154,7 @@ void NETGENPlugin_SimpleHypothesis_2D_i::SetMaxElementArea(CORBA::Double area) MESSAGE("NETGENPlugin_SimpleHypothesis_2D_i::SetMaxElementArea"); ASSERT(myBaseImpl); this->GetImpl()->SetMaxElementArea(area); - SMESH::TPythonDump() << _this() << ".SetMaxElementArea( " << area << " )"; + SMESH::TPythonDump() << _this() << ".SetMaxElementArea( " << SMESH::TVar(area) << " )"; } @@ -163,18 +163,43 @@ void NETGENPlugin_SimpleHypothesis_2D_i::SetMaxElementArea(CORBA::Double area) * NETGENPlugin_SimpleHypothesis_2D_i::GetMaxElementArea() */ //============================================================================= + CORBA::Double NETGENPlugin_SimpleHypothesis_2D_i::GetMaxElementArea() { MESSAGE("NETGENPlugin_SimpleHypothesis_2D_i::GetMaxElementArea"); ASSERT(myBaseImpl); return this->GetImpl()->GetMaxElementArea(); } + +//============================================================================= +/*! + * Enables/disables generation of quadrangular faces + */ +//============================================================================= + +void NETGENPlugin_SimpleHypothesis_2D_i::SetAllowQuadrangles(CORBA::Boolean toAllow) +{ + ASSERT(myBaseImpl); + SMESH::TPythonDump() << _this() << ".SetAllowQuadrangles( " << toAllow << " )"; + this->GetImpl()->SetAllowQuadrangles(toAllow); +} + +//============================================================================= +/*! + * Returns true if generation of quadrangular faces is enabled + */ +//============================================================================= + +CORBA::Boolean NETGENPlugin_SimpleHypothesis_2D_i::GetAllowQuadrangles() +{ + return this->GetImpl()->GetAllowQuadrangles(); +} //============================================================================= /*! * NETGENPlugin_SimpleHypothesis_2D_i::GetImpl */ //============================================================================= -::NETGENPlugin_SimpleHypothesis_2D* NETGENPlugin_SimpleHypothesis_2D_i::GetImpl() +::NETGENPlugin_SimpleHypothesis_2D* NETGENPlugin_SimpleHypothesis_2D_i::GetImpl() const { MESSAGE("NETGENPlugin_SimpleHypothesis_2D_i::GetImpl"); return (::NETGENPlugin_SimpleHypothesis_2D*)myBaseImpl; @@ -183,9 +208,9 @@ CORBA::Double NETGENPlugin_SimpleHypothesis_2D_i::GetMaxElementArea() //================================================================================ /*! * \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 - * + * \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) */ //================================================================================ @@ -193,3 +218,41 @@ CORBA::Boolean NETGENPlugin_SimpleHypothesis_2D_i::IsDimSupported( SMESH::Dimens { return type == SMESH::DIM_2D; } + +//================================================================================ +/*! + * \brief method intended to remove explicit treatment of Netgen hypotheses from SMESH_NoteBook + */ +//================================================================================ + +int NETGENPlugin_SimpleHypothesis_2D_i::getParamIndex(const TCollection_AsciiString& method, + int nbVars) const +{ + if ( method == "SetLocalLength" ) return 0; + if ( method == "SetNumberOfSegments" ) return 0; + if ( method == "SetMaxElementArea" ) return 1; + if ( method == "LengthFromEdges" ) return 10; // just to go to the next state + if ( method == "SetMaxElementVolume" ) return 2; + if ( method == "LengthFromFaces" ) return 10; // just to go to the next state + + return SMESH_Hypothesis_i::getParamIndex( method, nbVars ); // return default value +} + +//================================================================================ +/*! + * \brief Method used to convert variable parameters stored in an old study + * into myMethod2VarParams. It should return a method name for an index of + * variable parameters. Index is countered from zero + */ +//================================================================================ + +std::string NETGENPlugin_SimpleHypothesis_2D_i::getMethodOfParameter(const int paramIndex, + int nbVars) const +{ + switch ( paramIndex ) { + case 0: return GetImpl()->GetNumberOfSegments() ? "SetNumberOfSegments" : "SetLocalLength"; + case 1: return "SetMaxElementArea"; + case 2: return "SetMaxElementVolume"; + } + return ""; +} diff --git a/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_2D_i.hxx b/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_2D_i.hxx index 5426293..5ad350e 100644 --- a/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_2D_i.hxx +++ b/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_2D_i.hxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_SimpleHypothesis_2D_i.hxx // Author : Edward AGAPOV @@ -64,12 +62,25 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_SimpleHypothesis_2D_i: void SetMaxElementArea(CORBA::Double area); CORBA::Double GetMaxElementArea(); + void SetAllowQuadrangles(CORBA::Boolean toAllow); + CORBA::Boolean GetAllowQuadrangles(); // Get implementation - ::NETGENPlugin_SimpleHypothesis_2D* GetImpl(); + ::NETGENPlugin_SimpleHypothesis_2D* GetImpl() const; // Verify whether hypothesis supports given entity type CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + + public: + // method intended to remove explicit treatment of Netgen hypotheses from + // SMESH_NoteBook to assure backward compatibility after implemeneting + // issue 0021308: Remove hard-coded dependency of the external mesh plugins + virtual int getParamIndex(const TCollection_AsciiString& method, int nbVars) const; + + // method used to convert variable parameters stored in an old study + // into myMethod2VarParams. It should return a method name for an index of + // variable parameters. Index is countered from zero + virtual std::string getMethodOfParameter(const int paramIndex, int nbVars) const; }; #endif diff --git a/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_3D.cxx b/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_3D.cxx index fd799b9..3fb1d3f 100644 --- a/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_3D.cxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_SimpleHypothesis_3D.cxx // Author : Edward AGAPOV diff --git a/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_3D.hxx b/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_3D.hxx index 7b7de4f..537dd35 100644 --- a/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_3D.hxx +++ b/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_3D.hxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_SimpleHypothesis_3D.hxx // Author : Edward AGAPOV diff --git a/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_3D_i.cxx b/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_3D_i.cxx index 96b9aa8..5becc61 100644 --- a/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_3D_i.cxx +++ b/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_3D_i.cxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_SimpleHypothesis_3D_i.cxx // Author : Edward AGAPOV @@ -94,7 +92,7 @@ void NETGENPlugin_SimpleHypothesis_3D_i::SetMaxElementVolume(CORBA::Double value MESSAGE("NETGENPlugin_SimpleHypothesis_3D_i::SetMaxElementVolume"); ASSERT(myBaseImpl); this->GetImpl()->SetMaxElementVolume(value); - SMESH::TPythonDump() << _this() << ".SetMaxElementVolume( " << value << " )"; + SMESH::TPythonDump() << _this() << ".SetMaxElementVolume( " << SMESH::TVar(value) << " )"; } diff --git a/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_3D_i.hxx b/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_3D_i.hxx index 6fd6688..e52dbab 100644 --- a/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_3D_i.hxx +++ b/src/NETGENPlugin/NETGENPlugin_SimpleHypothesis_3D_i.hxx @@ -1,24 +1,22 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // NETGENPlugin : C++ implementation // File : NETGENPlugin_SimpleHypothesis_3D_i.hxx // Author : Edward AGAPOV diff --git a/src/NETGENPlugin/NETGENPlugin_i.cxx b/src/NETGENPlugin/NETGENPlugin_i.cxx index 78e77c1..acfa7c0 100644 --- a/src/NETGENPlugin/NETGENPlugin_i.cxx +++ b/src/NETGENPlugin/NETGENPlugin_i.cxx @@ -1,24 +1,25 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE // -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. // -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // SMESH NETGENPlugin : implementaion of SMESH idl descriptions // File : NETGENPlugin.cxx // Author : Julia DOROVSKIKH @@ -27,12 +28,14 @@ // #include "utilities.h" -#include "NETGENPlugin_NETGEN_3D_i.hxx" -#include "NETGENPlugin_NETGEN_2D_i.hxx" -#include "NETGENPlugin_NETGEN_2D_ONLY_i.hxx" -#include "NETGENPlugin_NETGEN_2D3D_i.hxx" -#include "NETGENPlugin_Hypothesis_i.hxx" +#include "NETGENPlugin_Hypothesis_2D_ONLY_i.hxx" #include "NETGENPlugin_Hypothesis_2D_i.hxx" +#include "NETGENPlugin_Hypothesis_3D_i.hxx" +#include "NETGENPlugin_Hypothesis_i.hxx" +#include "NETGENPlugin_NETGEN_2D3D_i.hxx" +#include "NETGENPlugin_NETGEN_2D_ONLY_i.hxx" +#include "NETGENPlugin_NETGEN_2D_i.hxx" +#include "NETGENPlugin_NETGEN_3D_i.hxx" #include "NETGENPlugin_SimpleHypothesis_2D_i.hxx" #include "NETGENPlugin_SimpleHypothesis_3D_i.hxx" @@ -73,6 +76,10 @@ extern "C" aCreator = new NETGENPlugin_Creator_i; else if (strcmp(aHypName, "NETGEN_Parameters_2D") == 0) aCreator = new NETGENPlugin_Creator_i; + else if (strcmp(aHypName, "NETGEN_Parameters_3D") == 0) + aCreator = new NETGENPlugin_Creator_i; + else if (strcmp(aHypName, "NETGEN_Parameters_2D_ONLY") == 0) + aCreator = new NETGENPlugin_Creator_i; else if (strcmp(aHypName, "NETGEN_SimpleParameters_2D") == 0) aCreator = new NETGENPlugin_Creator_i; else if (strcmp(aHypName, "NETGEN_SimpleParameters_3D") == 0) -- 2.39.2