]> SALOME platform Git repositories - plugins/hybridplugin.git/commitdiff
Salome HOME
Merge from V6_3_BR 06/06/2011
authorvsr <vsr@opencascade.com>
Mon, 6 Jun 2011 09:39:53 +0000 (09:39 +0000)
committervsr <vsr@opencascade.com>
Mon, 6 Jun 2011 09:39:53 +0000 (09:39 +0000)
37 files changed:
GHS3DPLUGIN_version.h.in
Makefile.am
adm_local/Makefile.am
adm_local/unix/Makefile.am
adm_local/unix/config_files/Makefile.am
adm_local/unix/config_files/check_GHS3D.m4
adm_local/unix/config_files/check_GHS3DPLUGIN.m4
adm_local/unix/make_common_starter.am
bin/Makefile.am
build_cmake
build_cmake.bat
build_configure
clean_configure
configure.ac
idl/GHS3DPlugin_Algorithm.idl
idl/Makefile.am
resources/GHS3DPlugin.xml
resources/Makefile.am
resources/SalomeApp.xml
src/GHS3DPlugin/GHS3DPlugin_Defs.hxx
src/GHS3DPlugin/GHS3DPlugin_GHS3D.cxx
src/GHS3DPlugin/GHS3DPlugin_GHS3D.hxx
src/GHS3DPlugin/GHS3DPlugin_GHS3D_i.cxx
src/GHS3DPlugin/GHS3DPlugin_GHS3D_i.hxx
src/GHS3DPlugin/GHS3DPlugin_Hypothesis.cxx
src/GHS3DPlugin/GHS3DPlugin_Hypothesis.hxx
src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.cxx
src/GHS3DPlugin/GHS3DPlugin_Hypothesis_i.hxx
src/GHS3DPlugin/GHS3DPlugin_i.cxx
src/GHS3DPlugin/Makefile.am
src/GHS3DPlugin/libmesh5.c [new file with mode: 0644]
src/GHS3DPlugin/libmesh5.h [new file with mode: 0755]
src/GUI/GHS3DPluginGUI_HypothesisCreator.cxx
src/GUI/GHS3DPluginGUI_HypothesisCreator.h
src/GUI/GHS3DPlugin_images.ts
src/GUI/Makefile.am
src/Makefile.am

index ac6fa7ddcccc99e2f978e254eaf51856050d8a0c..a94dcdae7d5da1b6e74001d9b33a313341f3f37f 100644 (file)
@@ -1,20 +1,20 @@
-//  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+// Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 //  File   : GHS3DPLUGIN_version.h
index 4cbed0ba737300283bab0a880b59256db4b2c45c..ca82224b3d49e75ab1176d1b77063a37b4d86676 100644 (file)
@@ -1,20 +1,20 @@
-#  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+# Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 #
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Lesser General Public
-#  License as published by the Free Software Foundation; either
-#  version 2.1 of the License.
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
 #
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Lesser General Public License for more details.
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
 #
-#  You should have received a copy of the GNU Lesser General Public
-#  License along with this library; if not, write to the Free Software
-#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #
-#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
 # -* Makefile *-
index ce6079f8741612a114e8c4fec8836660ad3bb64f..6705970ec52420e23c72470189dbcfbcad7165a3 100644 (file)
@@ -1,20 +1,20 @@
-#  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+# Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 #
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Lesser General Public
-#  License as published by the Free Software Foundation; either
-#  version 2.1 of the License.
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
 #
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Lesser General Public License for more details.
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
 #
-#  You should have received a copy of the GNU Lesser General Public
-#  License along with this library; if not, write to the Free Software
-#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #
-#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
index b10b609910f679675d1c03e5aa83b60f5422e59e..6c83087ac1b246546590b8e0cc6852787afaa3bc 100644 (file)
@@ -1,20 +1,20 @@
-#  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+# Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 #
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Lesser General Public
-#  License as published by the Free Software Foundation; either
-#  version 2.1 of the License.
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
 #
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Lesser General Public License for more details.
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
 #
-#  You should have received a copy of the GNU Lesser General Public
-#  License along with this library; if not, write to the Free Software
-#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #
-#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
index 6ee9ddb94d2bb20b3f329ceb6f7d9efac277e657..e173ea60187c6c372a169deb5709c98293cc93b2 100644 (file)
@@ -1,20 +1,20 @@
-#  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+# Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 #
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Lesser General Public
-#  License as published by the Free Software Foundation; either
-#  version 2.1 of the License.
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
 #
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Lesser General Public License for more details.
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
 #
-#  You should have received a copy of the GNU Lesser General Public
-#  License along with this library; if not, write to the Free Software
-#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #
-#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
 include $(top_srcdir)/adm_local/unix/make_common_starter.am
index 70e31632b41eb480082b7c70422d74e64ccf5db5..3ecabf022ae7de6e5c0068d599a1bf934f6f0da7 100644 (file)
@@ -1,20 +1,20 @@
-dnl  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+dnl Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 dnl
-dnl  This library is free software; you can redistribute it and/or
-dnl  modify it under the terms of the GNU Lesser General Public
-dnl  License as published by the Free Software Foundation; either
-dnl  version 2.1 of the License.
+dnl This library is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Lesser General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2.1 of the License.
 dnl
-dnl  This library is distributed in the hope that it will be useful,
-dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
-dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-dnl  Lesser General Public License for more details.
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+dnl Lesser General Public License for more details.
 dnl
-dnl  You should have received a copy of the GNU Lesser General Public
-dnl  License along with this library; if not, write to the Free Software
-dnl  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+dnl You should have received a copy of the GNU Lesser General Public
+dnl License along with this library; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 dnl
-dnl  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 dnl
 
 AC_DEFUN([CHECK_GHS3D],[
index 626be0366888a44354963915a4cbc958b540a7b3..1722d1e83e6846bcf92a032514d27e745af01de5 100755 (executable)
@@ -1,20 +1,20 @@
-dnl  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+dnl Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 dnl
-dnl  This library is free software; you can redistribute it and/or
-dnl  modify it under the terms of the GNU Lesser General Public
-dnl  License as published by the Free Software Foundation; either
-dnl  version 2.1 of the License.
+dnl This library is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Lesser General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2.1 of the License.
 dnl
-dnl  This library is distributed in the hope that it will be useful,
-dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
-dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-dnl  Lesser General Public License for more details.
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+dnl Lesser General Public License for more details.
 dnl
-dnl  You should have received a copy of the GNU Lesser General Public
-dnl  License along with this library; if not, write to the Free Software
-dnl  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+dnl You should have received a copy of the GNU Lesser General Public
+dnl License along with this library; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 dnl
-dnl  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+dnl See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 dnl
 
 #  Check availability of GHS3DPLUGIN binary distribution
index 29ea7c14c4f77c899e2fea540a5575c3ffc791b4..e4e7b6dad56f1e5721cf050e3c0f54b9902ee984 100644 (file)
@@ -1,20 +1,20 @@
-#  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+# Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 #
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Lesser General Public
-#  License as published by the Free Software Foundation; either
-#  version 2.1 of the License.
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
 #
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Lesser General Public License for more details.
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
 #
-#  You should have received a copy of the GNU Lesser General Public
-#  License along with this library; if not, write to the Free Software
-#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #
-#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
 # ============================================================
index 7bb738b8632b58ed693a49598ecf328f3190108b..74967025fdd0840c7df3d93f9864535a7c19ff42 100644 (file)
@@ -1,20 +1,20 @@
-#  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+# Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 #
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Lesser General Public
-#  License as published by the Free Software Foundation; either
-#  version 2.1 of the License.
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
 #
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Lesser General Public License for more details.
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
 #
-#  You should have received a copy of the GNU Lesser General Public
-#  License along with this library; if not, write to the Free Software
-#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #
-#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
 # -* Makefile *- 
index 84cca18bfe2cb96e8318a4cf15140bb1fe3440f6..6d2d944378bcf5f619b2f5e293de8d007c19ebaf 100755 (executable)
@@ -1,21 +1,21 @@
 #!/bin/sh
-#  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+# Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 #
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Lesser General Public
-#  License as published by the Free Software Foundation; either
-#  version 2.1 of the License.
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
 #
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Lesser General Public License for more details.
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
 #
-#  You should have received a copy of the GNU Lesser General Public
-#  License along with this library; if not, write to the Free Software
-#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #
-#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
 CURRENT_DIR=`pwd`
index 0040452fb0d447e0b607d714c2320ea918aa6422..2ab238883cdd2bc1f3eb16dfb8c367f22331cdce 100644 (file)
@@ -1,20 +1,20 @@
-@REM  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+@REM Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 @REM
-@REM  This library is free software; you can redistribute it and/or
-@REM  modify it under the terms of the GNU Lesser General Public
-@REM  License as published by the Free Software Foundation; either
-@REM  version 2.1 of the License.
+@REM 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 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 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 See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 @REM
 
 %PYTHONBIN% %KERNEL_ROOT_DIR%\salome_adm\cmake_files\am2cmake.py --ghs3dplugin\r
index f1181627d1fc90a5384899a11c530c1e89ee72b6..e476f5d579c5735ccf14b5442f8ca9510d24c913 100755 (executable)
@@ -1,21 +1,21 @@
 #!/bin/bash
-#  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+# Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 #
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Lesser General Public
-#  License as published by the Free Software Foundation; either
-#  version 2.1 of the License.
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
 #
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Lesser General Public License for more details.
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
 #
-#  You should have received a copy of the GNU Lesser General Public
-#  License along with this library; if not, write to the Free Software
-#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #
-#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
 # Tool for updating list of .in file for the SALOME project 
index ec471417c4cbf855d020f55b0f740d1d3f8583a5..cd4e202ae61c2ea32bf0f8cb86a8b6027d130e68 100755 (executable)
@@ -1,21 +1,21 @@
 #!/bin/sh
-#  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+# Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 #
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Lesser General Public
-#  License as published by the Free Software Foundation; either
-#  version 2.1 of the License.
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
 #
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Lesser General Public License for more details.
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
 #
-#  You should have received a copy of the GNU Lesser General Public
-#  License along with this library; if not, write to the Free Software
-#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #
-#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
 rm -rf autom4te.cache aclocal.m4 configure make_config
index f68d5f2cff5d6677e045b7b4ca1c0df9c44b4b37..21b88630f2b26e1456b58e0926d02d3ccdfb196d 100644 (file)
@@ -1,20 +1,20 @@
-#  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+# Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 #
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Lesser General Public
-#  License as published by the Free Software Foundation; either
-#  version 2.1 of the License.
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
 #
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Lesser General Public License for more details.
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
 #
-#  You should have received a copy of the GNU Lesser General Public
-#  License along with this library; if not, write to the Free Software
-#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #
-#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
 #  PLEASE DO NOT MODIFY configure.in FILE
@@ -27,7 +27,7 @@
 # Modified by : Marc Tajchman (CEA)
 # Created from configure.in.base
 #
-AC_INIT([Salome2 Project GHS3DPLUGIN module],[6.2.0], [webmaster.salome@opencascade.com], [SalomeGHS3DPLUGIN])
+AC_INIT([Salome2 Project GHS3DPLUGIN module],[6.3.0], [webmaster.salome@opencascade.com], [SalomeGHS3DPLUGIN])
 AC_CONFIG_AUX_DIR(adm_local/unix/config_files)
 AC_CANONICAL_HOST
 AC_CANONICAL_TARGET
@@ -352,6 +352,13 @@ echo ---------------------------------------------
 echo
 
 CHECK_GHS3D
+if test "${GHS3D_ok}" = "yes"; then
+  if test "x$GHS3D_VERSION" = "x"
+  then
+    GHS3D_VERSION=`ghs3d -u |grep "TETMESH-GHS3D SOFTWARE"|awk '{print $3}'|awk -F- '{print $1}'|awk -F. '{print $1$2}'`
+  fi
+  AC_DEFINE_UNQUOTED(GHS3D_VERSION,${GHS3D_VERSION})
+fi
 
 echo
 echo ---------------------------------------------
index 20bcf334a3178069fd17f53f308a8bdd2173019d..8d04925a2ee4aac5243af0726a2e366524166856 100644 (file)
@@ -1,20 +1,20 @@
-//  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+// Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 //  File   : GHS3D_Algorithm.idl
 
 #include "SALOME_Exception.idl"
 #include "SMESH_Hypothesis.idl"
+#include "SMESH_Mesh.idl"
 
 /*!
  * GHS3DPlugin: interfaces to GHS3D related hypotheses and algorithms
  */
 module GHS3DPlugin
 {
+  typedef sequence<double,3> TCoords;
   struct GHS3DEnforcedVertex {
-    double x;
-    double y;
-    double z;
+    string name;
+    string geomEntry;
+    TCoords coords;
+    string groupName;
     double size;
   };
   
@@ -45,6 +48,7 @@ module GHS3DPlugin
    */
   interface GHS3DPlugin_GHS3D : SMESH::SMESH_3D_Algo
   {
+    SMESH::SMESH_Mesh importGMFMesh(in string aGMFFileName);
   };
 
   /*!
@@ -109,8 +113,8 @@ module GHS3DPlugin
     void SetToUseBoundaryRecoveryVersion(in boolean toUse);
     boolean GetToUseBoundaryRecoveryVersion();
     /*!
-     * Applies nite-element correction by replacing overconstrained elements where
-     * it is possible. The process is cutting rst the overconstrained edges and
+     * Applies finite-element correction by replacing overconstrained elements where
+     * it is possible. The process is cutting first the overconstrained edges and
      * second the overconstrained facets. This insure that no edges have two boundary
      * vertices and that no facets have three boundary vertices.
      */
@@ -129,11 +133,22 @@ module GHS3DPlugin
     /*!
      * To set an enforced vertex
      */
-    void SetEnforcedVertex(in double x, in double y, in double z, in double size);
+    boolean SetEnforcedVertex(in double x, in double y, in double z, in double size) raises (SALOME::SALOME_Exception);
+    boolean SetEnforcedVertexWithGroup(in double x, in double y, in double z, in double size, in string groupName) raises (SALOME::SALOME_Exception);
+    boolean SetEnforcedVertexGeom(in GEOM::GEOM_Object theVertex, in double size) raises (SALOME::SALOME_Exception);
+    boolean SetEnforcedVertexGeomWithGroup(in GEOM::GEOM_Object theVertex, in double size, in string groupName) raises (SALOME::SALOME_Exception);
     double GetEnforcedVertex(in double x, in double y, in double z) raises (SALOME::SALOME_Exception);
-    void RemoveEnforcedVertex(in double x, in double y, in double z) raises (SALOME::SALOME_Exception);
+    double GetEnforcedVertexGeom(in GEOM::GEOM_Object theVertex) raises (SALOME::SALOME_Exception);
+    boolean RemoveEnforcedVertex(in double x, in double y, in double z) raises (SALOME::SALOME_Exception);
+    boolean RemoveEnforcedVertexGeom(in GEOM::GEOM_Object theVertex) raises (SALOME::SALOME_Exception);
     GHS3DEnforcedVertexList GetEnforcedVertices();
     void ClearEnforcedVertices();
+    
+    boolean SetEnforcedMesh(in SMESH::SMESH_IDSource theSource, in SMESH::ElementType elementType) raises (SALOME::SALOME_Exception);
+    boolean SetEnforcedMeshWithGroup(in SMESH::SMESH_IDSource theSource, in SMESH::ElementType elementType, in string groupName) raises (SALOME::SALOME_Exception);
+    boolean SetEnforcedMeshSize(in SMESH::SMESH_IDSource theSource, in SMESH::ElementType elementType, in double size) raises (SALOME::SALOME_Exception);
+    boolean SetEnforcedMeshSizeWithGroup(in SMESH::SMESH_IDSource theSource, in SMESH::ElementType elementType, in double size, in string groupName) raises (SALOME::SALOME_Exception);
+    void ClearEnforcedMeshes();
   };
 };
 
index 8e265df928f845eac91acb52d7dd181a76bd05dd..605fb96e3653fc87a8b24ff231ad1b490d1265db 100644 (file)
@@ -1,20 +1,20 @@
-#  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+# Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 #
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Lesser General Public
-#  License as published by the Free Software Foundation; either
-#  version 2.1 of the License.
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
 #
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Lesser General Public License for more details.
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
 #
-#  You should have received a copy of the GNU Lesser General Public
-#  License along with this library; if not, write to the Free Software
-#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #
-#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
 # This Makefile is responsible of generating the client and server
@@ -47,12 +47,14 @@ libSalomeIDLGHS3DPLUGIN_la_CPPFLAGS = \
        $(CORBA_INCLUDES) \
        $(KERNEL_CXXFLAGS) \
        $(GEOM_CXXFLAGS) \
+       $(MED_CXXFLAGS) \
        $(SMESH_CXXFLAGS)
 
 libSalomeIDLGHS3DPLUGIN_la_LDFLAGS = -no-undefined -version-info=0:0:0
 libSalomeIDLGHS3DPLUGIN_la_LIBADD  = \
        $(KERNEL_LDFLAGS) -lSalomeIDLKernel \
        $(GEOM_LDFLAGS) -lSalomeIDLGEOM \
+       $(MED_LDFLAGS) -lSalomeIDLMED \
        $(SMESH_LDFLAGS) -lSalomeIDLSMESH \
        @CORBA_LIBS@
 
@@ -64,6 +66,7 @@ OMNIORB_IDLPYFLAGS  = \
        -I$(top_builddir)/idl/salome \
        -I$(KERNEL_ROOT_DIR)/idl/salome \
        -I$(GEOM_ROOT_DIR)/idl/salome \
+       -I$(MED_ROOT_DIR)/idl/salome \
        -I$(SMESH_ROOT_DIR)/idl/salome
 
 IDLCXXFLAGS = \
@@ -72,11 +75,13 @@ IDLCXXFLAGS = \
        -I$(top_builddir)/idl/salome \
        -I$(KERNEL_ROOT_DIR)/idl/salome \
        -I$(GEOM_ROOT_DIR)/idl/salome \
+       -I$(MED_ROOT_DIR)/idl/salome \
        -I$(SMESH_ROOT_DIR)/idl/salome
 IDLPYFLAGS  = \
        @IDLPYFLAGS@ \
        -I$(KERNEL_ROOT_DIR)/idl/salome \
        -I$(GEOM_ROOT_DIR)/idl/salome \
+       -I$(MED_ROOT_DIR)/idl/salome \
        -I$(SMESH_ROOT_DIR)/idl/salome
 
 # potential problem on parallel make on the following - multiple outputs
@@ -108,7 +113,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 $$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$(MED_ROOT_DIR)/idl/salome -I$(SMESH_ROOT_DIR)/idl/salome $$dep 2>/dev/null | \
            sed 's/\.o/\SK.cc/' >>$@; \
          fi; \
        done ;
index 1e7fe640d6ba1115f00e41293f392a93a5514af7..5702b41d283b756df4175d0860a9e61eb1d27fcf 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version='1.0' encoding='us-ascii'?>
 <!DOCTYPE meshers PUBLIC "" "desktop.dtd">
 <!--
-  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+  Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
index 42efbd4c53e665675dfb458a7f4eb8f6771695f7..626a4e55c31271ff875a101b4d741d6b3074dcb2 100644 (file)
@@ -1,20 +1,20 @@
-#  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+# Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 #
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Lesser General Public
-#  License as published by the Free Software Foundation; either
-#  version 2.1 of the License.
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
 #
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Lesser General Public License for more details.
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
 #
-#  You should have received a copy of the GNU Lesser General Public
-#  License along with this library; if not, write to the Free Software
-#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #
-#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
 # -* Makefile *- 
index a8a2a80635c742cdd61ba8d11335b6418286f276..bca519a7cfb5782c259b09d65b1ad85c1b6c2b97 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+  Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
index 0d9f9271c2614a49448a9d08c8e55d59de286181..f594d7dc304d29474fb8ecb3a3a6123d8e8cdc09 100644 (file)
@@ -1,20 +1,20 @@
-//  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+// Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 //=============================================================================
index abf3db6ca4efe8ec1522e31c87949af570fd6567..7d04f532c17dc36d2b104d299428af92e98269a6 100644 (file)
@@ -1,20 +1,20 @@
-//  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+// Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 //=============================================================================
 #include "GHS3DPlugin_GHS3D.hxx"
 #include "GHS3DPlugin_Hypothesis.hxx"
 
-
 #include <Basics_Utils.hxx>
 
-#include "SMESH_Gen.hxx"
+//#include "SMESH_Gen.hxx"
+#include <SMESH_Client.hxx>
 #include "SMESH_Mesh.hxx"
 #include "SMESH_Comment.hxx"
 #include "SMESH_MesherHelper.hxx"
 #include "SMESH_MeshEditor.hxx"
+#include "SMESH_OctreeNode.hxx"
+#include "SMESH_Group.hxx"
 
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
 #include "SMDS_FaceOfNodes.hxx"
 #include "SMDS_VolumeOfNodes.hxx"
 
+#include "SMESHDS_Group.hxx"
+
 #include <StdMeshers_QuadToTriaAdaptor.hxx>
 #include <StdMeshers_ViscousLayers.hxx>
 
 #include <BRepAdaptor_Surface.hxx>
 #include <BRepBndLib.hxx>
+#include <BRepBuilderAPI_MakeVertex.hxx>
 #include <BRepClass3d_SolidClassifier.hxx>
+#include <BRepExtrema_DistShapeShape.hxx>
 #include <BRepTools.hxx>
 #include <BRep_Tool.hxx>
 #include <Bnd_Box.hxx>
@@ -62,6 +68,7 @@
 #include <TopTools_IndexedMapOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopoDS.hxx>
+#include <TopoDS_Shape.hxx>
 //#include <BRepClass_FaceClassifier.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <BRepGProp.hxx>
@@ -74,6 +81,7 @@
 #else
 #include <sys/sysinfo.h>
 #endif
+#include <algorithm>
 
 using namespace std;
 
@@ -101,6 +109,10 @@ extern "C"
 
 #define HOLE_ID -1
 
+#ifndef GHS3D_VERSION
+#define GHS3D_VERSION 41
+#endif
+
 typedef const list<const SMDS_MeshFace*> TTriaList;
 
 static void removeFile( const TCollection_AsciiString& fileName )
@@ -130,7 +142,19 @@ GHS3DPlugin_GHS3D::GHS3DPlugin_GHS3D(int hypId, int studyId, SMESH_Gen* gen)
   _nbShape=0;
   _compatibleHypothesis.push_back("GHS3D_Parameters");
   _compatibleHypothesis.push_back( StdMeshers_ViscousLayers::GetHypType() );
-  _requireShape = false; // can work without shape
+  _requireShape = false; // can work without shape_studyId
+
+  smeshGen_i = SMESH_Gen_i::GetSMESHGen();
+  CORBA::Object_var anObject = smeshGen_i->GetNS()->Resolve("/myStudyManager");
+  SALOMEDS::StudyManager_var aStudyMgr = SALOMEDS::StudyManager::_narrow(anObject);
+
+  MESSAGE("studyid = " << _studyId);
+
+  myStudy = NULL;
+  myStudy = aStudyMgr->GetStudyByID(_studyId);
+  if (myStudy)
+    MESSAGE("myStudy->StudyId() = " << myStudy->StudyId());
+  
 #ifdef WITH_SMESH_CANCEL_COMPUTE
   _compute_canceled = false;
 #endif
@@ -179,6 +203,31 @@ bool GHS3DPlugin_GHS3D::CheckHypothesis ( SMESH_Mesh&         aMesh,
   return true;
 }
 
+
+//=======================================================================
+//function : entryToShape
+//purpose  : 
+//=======================================================================
+
+TopoDS_Shape GHS3DPlugin_GHS3D::entryToShape(std::string entry)
+{
+  MESSAGE("GHS3DPlugin_GHS3D::entryToShape "<<entry );
+  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() );
+  return S;
+}
+
 //=======================================================================
 //function : findShape
 //purpose  : 
@@ -238,6 +287,197 @@ static char* readMapIntLine(char* ptr, int tab[]) {
   return ptr;
 }
 
+//================================================================================
+/*!
+ * \brief returns true if a triangle defined by the nodes is a temporary face on a
+ * side facet of pyramid and defines sub-domian inside the pyramid
+ */
+//================================================================================
+
+static bool isTmpFace(const SMDS_MeshNode* node1,
+                      const SMDS_MeshNode* node2,
+                      const SMDS_MeshNode* node3)
+{
+  // find a pyramid sharing the 3 nodes
+  //const SMDS_MeshElement* pyram = 0;
+  SMDS_ElemIteratorPtr vIt1 = node1->GetInverseElementIterator(SMDSAbs_Volume);
+  while ( vIt1->more() )
+  {
+    const SMDS_MeshElement* pyram = vIt1->next();
+    if ( pyram->NbCornerNodes() != 5 ) continue;
+    int i2, i3;
+    if ( (i2 = pyram->GetNodeIndex( node2 )) >= 0 &&
+         (i3 = pyram->GetNodeIndex( node3 )) >= 0 )
+    {
+      // Triangle defines sub-domian inside the pyramid if it's
+      // normal points out of the pyram
+
+      // make i2 and i3 hold indices of base nodes of the pyram while
+      // keeping the nodes order in the triangle
+      const int iApex = 4;
+      if ( i2 == iApex )
+        i2 = i3, i3 = pyram->GetNodeIndex( node1 );
+      else if ( i3 == iApex )
+        i3 = i2, i2 = pyram->GetNodeIndex( node1 );
+
+      int i3base = (i2+1) % 4; // next index after i2 within the pyramid base
+      return ( i3base != i3 );
+    }
+  }
+  return false;
+}
+
+//=======================================================================
+//function : findShapeID
+//purpose  : find the solid corresponding to GHS3D sub-domain following
+//           the technique proposed in GHS3D manual (available within
+//           ghs3d installation) in chapter "B.4 Subdomain (sub-region) assignment".
+//           In brief: normal of the triangle defined by the given nodes
+//           points out of the domain it is associated to
+//=======================================================================
+
+static int findShapeID(SMESH_Mesh&          mesh,
+                       const SMDS_MeshNode* node1,
+                       const SMDS_MeshNode* node2,
+                       const SMDS_MeshNode* node3,
+                       const bool           toMeshHoles)
+{
+  const int invalidID = 0;
+  SMESHDS_Mesh* meshDS = mesh.GetMeshDS();
+
+  // face the nodes belong to
+  const SMDS_MeshElement * face = meshDS->FindFace(node1,node2,node3);
+  if ( !face )
+    return isTmpFace(node1, node2, node3) ? HOLE_ID : invalidID;
+#ifdef _DEBUG_
+  std::cout << "bnd face " << face->GetID() << " - ";
+#endif
+  // geom face the face assigned to
+  SMESH_MeshEditor editor(&mesh);
+  int geomFaceID = editor.FindShape( face );
+  if ( !geomFaceID )
+    return isTmpFace(node1, node2, node3) ? HOLE_ID : invalidID;
+  TopoDS_Shape shape = meshDS->IndexToShape( geomFaceID );
+  if ( shape.IsNull() || shape.ShapeType() != TopAbs_FACE )
+    return invalidID;
+  TopoDS_Face geomFace = TopoDS::Face( shape );
+
+  // solids bounded by geom face
+  TopTools_IndexedMapOfShape solids, shells;
+  TopTools_ListIteratorOfListOfShape ansIt = mesh.GetAncestors(geomFace);
+  for ( ; ansIt.More(); ansIt.Next() ) {
+    switch ( ansIt.Value().ShapeType() ) {
+    case TopAbs_SOLID:
+      solids.Add( ansIt.Value() ); break;
+    case TopAbs_SHELL:
+      shells.Add( ansIt.Value() ); break;
+    default:;
+    }
+  }
+  // analyse found solids
+  if ( solids.Extent() == 0 || shells.Extent() == 0)
+    return invalidID;
+
+  const TopoDS_Solid& solid1 = TopoDS::Solid( solids(1) );
+  if ( solids.Extent() == 1 )
+  {
+    if ( toMeshHoles )
+      return meshDS->ShapeToIndex( solid1 );
+
+    // - Are we at a hole boundary face?
+    if ( shells(1).IsSame( BRepTools::OuterShell( solid1 )) )
+    { // - No, but maybe a hole is bound by two shapes? Does shells(1) touches another shell?
+      bool touch = false;
+      TopExp_Explorer eExp( shells(1), TopAbs_EDGE );
+      // check if any edge of shells(1) belongs to another shell
+      for ( ; eExp.More() && !touch; eExp.Next() ) {
+        ansIt = mesh.GetAncestors( eExp.Current() );
+        for ( ; ansIt.More() && !touch; ansIt.Next() ) {
+          if ( ansIt.Value().ShapeType() == TopAbs_SHELL )
+            touch = ( !ansIt.Value().IsSame( shells(1) ));
+        }
+      }
+      if (!touch)
+        return meshDS->ShapeToIndex( solid1 );
+    }
+  }
+  // find orientation of geom face within the first solid
+  TopExp_Explorer fExp( solid1, TopAbs_FACE );
+  for ( ; fExp.More(); fExp.Next() )
+    if ( geomFace.IsSame( fExp.Current() )) {
+      geomFace = TopoDS::Face( fExp.Current() );
+      break;
+    }
+  if ( !fExp.More() )
+    return invalidID; // face not found
+
+  // normale to triangle
+  gp_Pnt node1Pnt ( node1->X(), node1->Y(), node1->Z() );
+  gp_Pnt node2Pnt ( node2->X(), node2->Y(), node2->Z() );
+  gp_Pnt node3Pnt ( node3->X(), node3->Y(), node3->Z() );
+  gp_Vec vec12( node1Pnt, node2Pnt );
+  gp_Vec vec13( node1Pnt, node3Pnt );
+  gp_Vec meshNormal = vec12 ^ vec13;
+  if ( meshNormal.SquareMagnitude() < DBL_MIN )
+    return invalidID;
+
+  // get normale to geomFace at any node
+  bool geomNormalOK = false;
+  gp_Vec geomNormal;
+  const SMDS_MeshNode* nodes[3] = { node1, node2, node3 };
+  SMESH_MesherHelper helper( mesh ); helper.SetSubShape( geomFace );
+  for ( int i = 0; !geomNormalOK && i < 3; ++i )
+  {
+    // find UV of i-th node on geomFace
+    const SMDS_MeshNode* nNotOnSeamEdge = 0;
+    if ( helper.IsSeamShape( nodes[i]->getshapeId() )) {
+      if ( helper.IsSeamShape( nodes[(i+1)%3]->getshapeId() ))
+        nNotOnSeamEdge = nodes[(i+2)%3];
+      else
+        nNotOnSeamEdge = nodes[(i+1)%3];
+    }
+    bool uvOK;
+    gp_XY uv = helper.GetNodeUV( geomFace, nodes[i], nNotOnSeamEdge, &uvOK );
+    // check that uv is correct
+    if (uvOK) {
+      double tol = 1e-6;
+      TopoDS_Shape nodeShape = helper.GetSubShapeByNode( nodes[i], meshDS );
+      if ( !nodeShape.IsNull() )
+        switch ( nodeShape.ShapeType() )
+        {
+        case TopAbs_FACE:   tol = BRep_Tool::Tolerance( TopoDS::Face( nodeShape )); break;
+        case TopAbs_EDGE:   tol = BRep_Tool::Tolerance( TopoDS::Edge( nodeShape )); break;
+        case TopAbs_VERTEX: tol = BRep_Tool::Tolerance( TopoDS::Vertex( nodeShape )); break;
+        default:;
+        }
+      gp_Pnt nodePnt ( nodes[i]->X(), nodes[i]->Y(), nodes[i]->Z() );
+      BRepAdaptor_Surface surface( geomFace );
+      uvOK = ( nodePnt.Distance( surface.Value( uv.X(), uv.Y() )) < 2 * tol );
+      if ( uvOK ) {
+        // normale to geomFace at UV
+        gp_Vec du, dv;
+        surface.D1( uv.X(), uv.Y(), nodePnt, du, dv );
+        geomNormal = du ^ dv;
+        if ( geomFace.Orientation() == TopAbs_REVERSED )
+          geomNormal.Reverse();
+        geomNormalOK = ( geomNormal.SquareMagnitude() > DBL_MIN * 1e3 );
+      }
+    }
+  }
+  if ( !geomNormalOK)
+    return invalidID;
+
+  // compare normals
+  bool isReverse = ( meshNormal * geomNormal ) < 0;
+  if ( !isReverse )
+    return meshDS->ShapeToIndex( solid1 );
+
+  if ( solids.Extent() == 1 )
+    return HOLE_ID; // we are inside a hole
+  else
+    return meshDS->ShapeToIndex( solids(2) );
+}
+
 //=======================================================================
 //function : countShape
 //purpose  :
@@ -246,560 +486,2086 @@ static char* readMapIntLine(char* ptr, int tab[]) {
 // template < class Mesh, class Shape >
 // static int countShape( Mesh* mesh, Shape shape ) {
 //   TopExp_Explorer expShape ( mesh->ShapeToMesh(), shape );
+//   TopTools_MapOfShape mapShape;
 //   int nbShape = 0;
 //   for ( ; expShape.More(); expShape.Next() ) {
+//     if (mapShape.Add(expShape.Current())) {
 //       nbShape++;
+//     }
 //   }
 //   return nbShape;
 // }
 
 //=======================================================================
-//function : writeFaces
-//purpose  : 
+//function : getShape
+//purpose  :
 //=======================================================================
 
-static bool writeFaces (ofstream &             theFile,
-                        const SMESH_ProxyMesh& theMesh,
-                        const TopoDS_Shape&    theShape,
-                        const map <int,int> &  theSmdsToGhs3dIdMap)
-{
-  // record structure:
-  //
-  // NB_ELEMS DUMMY_INT
-  // Loop from 1 to NB_ELEMS
-  // NB_NODES NODE_NB_1 NODE_NB_2 ... (NB_NODES + 1) times: DUMMY_INT
+// template < class Mesh, class Shape, class Tab >
+// void getShape(Mesh* mesh, Shape shape, Tab *t_Shape) {
+//   TopExp_Explorer expShape ( mesh->ShapeToMesh(), shape );
+//   TopTools_MapOfShape mapShape;
+//   for ( int i=0; expShape.More(); expShape.Next() ) {
+//     if (mapShape.Add(expShape.Current())) {
+//       t_Shape[i] = expShape.Current();
+//       i++;
+//     }
+//   }
+//   return;
+// }
 
-  TopoDS_Shape aShape;
-  const SMESHDS_SubMesh* theSubMesh;
-  const SMDS_MeshElement* aFace;
-  const char* space    = "  ";
-  const int   dummyint = 0;
-  map<int,int>::const_iterator itOnMap;
-  SMDS_ElemIteratorPtr itOnSubMesh, itOnSubFace;
-  int nbNodes, aSmdsID;
+// //=======================================================================
+// //function : findEdgeID
+// //purpose  :
+// //=======================================================================
+// 
+// static int findEdgeID(const SMDS_MeshNode* aNode,
+//                       const SMESHDS_Mesh*  theMesh,
+//                       const int            nEdge,
+//                       const TopoDS_Shape*  t_Edge) {
+// 
+//   TopoDS_Shape aPntShape, foundEdge;
+//   TopoDS_Vertex aVertex;
+//   gp_Pnt aPnt( aNode->X(), aNode->Y(), aNode->Z() );
+// 
+//   int foundInd, ind;
+//   double nearest = RealLast(), *t_Dist;
+//   double epsilon = Precision::Confusion();
+// 
+//   t_Dist = new double[ nEdge ];
+//   aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
+//   aVertex   = TopoDS::Vertex( aPntShape );
+// 
+//   for ( ind=0; ind < nEdge; ind++ ) {
+//     BRepExtrema_DistShapeShape aDistance ( aVertex, t_Edge[ind] );
+//     t_Dist[ind] = aDistance.Value();
+//     if ( t_Dist[ind] < nearest ) {
+//       nearest   = t_Dist[ind];
+//       foundEdge = t_Edge[ind];
+//       foundInd  = ind;
+//       if ( nearest < epsilon )
+//         ind = nEdge;
+//     }
+//   }
+// 
+//   delete [] t_Dist;
+//   return theMesh->ShapeToIndex( foundEdge );
+// }
 
-  // count triangles bound to geometry
-  int nbTriangles = 0;
 
-  TopTools_IndexedMapOfShape facesMap;
-  TopExp::MapShapes( theShape, TopAbs_FACE, facesMap );
+//=======================================================================
+//function : readGMFFile
+//purpose  : read GMF file with geometry associated to mesh
+// TODO
+//=======================================================================
 
-  for ( int i = 1; i <= facesMap.Extent(); ++i )
-    if (( theSubMesh  = theMesh.GetSubMesh( facesMap(i))))
-      nbTriangles += theSubMesh->NbElements();
+// static bool readGMFFile(
+//                         const int                       fileOpen,
+//                         const char*                     theFileName, 
+//                         SMESH_Mesh&                     theMesh,
+//                         const int                       nbShape,
+//                         const TopoDS_Shape*             tabShape,
+//                         double**                        tabBox,
+//                         map <int,const SMDS_MeshNode*>& theGhs3dIdToNodeMap,
+//                         bool                            toMeshHoles,
+//                         int                             nbEnforcedVertices,
+//                         int                             nbEnforcedNodes)
+// {
+//   TopoDS_Shape aShape;
+//   TopoDS_Vertex aVertex;
+//   SMESHDS_Mesh* theMeshDS = theMesh.GetMeshDS();
+//   int nbElem = 0, nbRef = 0, IdShapeRef = 1;
+//   int *tabID;
+//   int aGMFNodeID = 0;
+//   int compoundID =
+//     nbShape ? theMeshDS->ShapeToIndex( tabShape[0] ) : theMeshDS->ShapeToIndex( theMeshDS->ShapeToMesh() );
+//   int tetraShapeID = compoundID;
+//   double epsilon = Precision::Confusion();
+//   int *nodeAssigne, *GMFNodeAssigne;
+//   SMDS_MeshNode** GMFNode;
+//   TopoDS_Shape *tabCorner, *tabEdge;
+//   std::map <GmfKwdCod,int> tabRef;
+//   
+//   
+//   int ver, dim;
+//   MESSAGE("Read " << theFileName << " file");
+//   int InpMsh = GmfOpenMesh(theFileName, GmfRead, &ver, &dim);
+//   if (!InpMsh)
+//     return false;
+//   
+//   // ===========================
+//   // Fill the tabID array: BEGIN
+//   // ===========================
+//   
+//   /*
+//   The output .mesh file does not contain yet the subdomain-info (Ghs3D 4.2)
+//   */
+//   Kernel_Utils::Localizer loc;
+//   struct stat status;
+//   size_t      length;
+// 
+//   char *ptr, *mapPtr;
+//   char *tetraPtr;
+//   int *tab = new int[3];
+//   
+//   // Read the file state
+//   fstat(fileOpen, &status);
+//   length   = status.st_size;
+//   
+//   // Mapping the result file into memory
+// #ifdef WNT
+//   HANDLE fd = CreateFile(theFileName, GENERIC_READ, FILE_SHARE_READ,
+//                          NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+//   HANDLE hMapObject = CreateFileMapping(fd, NULL, PAGE_READONLY,
+//                                         0, (DWORD)length, NULL);
+//   ptr = ( char* ) MapViewOfFile(hMapObject, FILE_MAP_READ, 0, 0, 0 );
+// #else
+//   ptr = (char *) mmap(0,length,PROT_READ,MAP_PRIVATE,fileOpen,0);
+// #endif
+//   mapPtr = ptr;
+// 
+//   ptr      = readMapIntLine(ptr, tab);
+//   tetraPtr = ptr;
+// 
+//   nbElem            = tab[0];
+//   int nbNodes       = tab[1];
+//   
+//   for (int i=0; i < 4*nbElem; i++)
+//     strtol(ptr, &ptr, 10);
+//   
+//   for (int iNode=1; iNode <= nbNodes; iNode++)
+//     for (int iCoor=0; iCoor < 3; iCoor++)
+//       strtod(ptr, &ptr);
+// 
+//     
+//   // Reading the number of triangles which corresponds to the number of sub-domains
+//   int nbTriangle = strtol(ptr, &ptr, 10);
+// 
+//   
+//   // The keyword does not exist yet => to update when it is created
+// //   int nbTriangle = GmfStatKwd(InpMsh, GmfSubdomain);
+// //   int id_tri[3];
+// 
+// 
+//   tabID = new int[nbTriangle];
+//   for (int i=0; i < nbTriangle; i++) {
+//     tabID[i] = 0;
+//     int nodeId1, nodeId2, nodeId3;
+//     // find the solid corresponding to GHS3D sub-domain following
+//     // the technique proposed in GHS3D manual in chapter
+//     // "B.4 Subdomain (sub-region) assignment"
+// 
+//     nodeId1 = strtol(ptr, &ptr, 10);
+//     nodeId2 = strtol(ptr, &ptr, 10);
+//     nodeId3 = strtol(ptr, &ptr, 10);
+// 
+// //   // The keyword does not exist yet => to update when it is created
+// //     GmfGetLin(InpMsh, GmfSubdomain, &id_tri[0], &id_tri[1], &id_tri[2]);
+// //     nodeId1 = id_tri[0];
+// //     nodeId2 = id_tri[1];
+// //     nodeId3 = id_tri[2];
+// 
+//     if ( nbTriangle > 1 ) {
+//       // get the nodes indices
+//       const SMDS_MeshNode* n1 = theGhs3dIdToNodeMap[ nodeId1 ];
+//       const SMDS_MeshNode* n2 = theGhs3dIdToNodeMap[ nodeId2 ];
+//       const SMDS_MeshNode* n3 = theGhs3dIdToNodeMap[ nodeId3 ];
+//       try {
+//         OCC_CATCH_SIGNALS;
+//         tabID[i] = findShapeID( theMesh, n1, n2, n3, toMeshHoles );
+//         // -- 0020330: Pb with ghs3d as a submesh
+//         // check that found shape is to be meshed
+//         if ( tabID[i] > 0 ) {
+//           const TopoDS_Shape& foundShape = theMeshDS->IndexToShape( tabID[i] );
+//           bool isToBeMeshed = false;
+//           for ( int iS = 0; !isToBeMeshed && iS < nbShape; ++iS )
+//             isToBeMeshed = foundShape.IsSame( tabShape[ iS ]);
+//           if ( !isToBeMeshed )
+//             tabID[i] = HOLE_ID;
+//         }
+//         // END -- 0020330: Pb with ghs3d as a submesh
+// #ifdef _DEBUG_
+//         std::cout << i+1 << " subdomain: findShapeID() returns " << tabID[i] << std::endl;
+// #endif
+//       }
+//       catch ( Standard_Failure & ex)
+//       {
+// #ifdef _DEBUG_
+//         std::cout << i+1 << " subdomain: Exception caugt: " << ex.GetMessageString() << std::endl;
+// #endif
+//       }
+//       catch (...) {
+// #ifdef _DEBUG_
+//         std::cout << i+1 << " subdomain: unknown exception caught " << std::endl;
+// #endif
+//       }
+//     }
+//   }
+//   
+//   // ===========================
+//   // Fill the tabID array: END
+//   // ===========================
+//   
+// 
+//   tabRef[GmfVertices]       = 3;
+//   tabRef[GmfCorners]        = 1;
+//   tabRef[GmfEdges]          = 2;
+//   tabRef[GmfRidges]         = 1;
+//   tabRef[GmfTriangles]      = 3;
+// //   tabRef[GmfQuadrilaterals] = 4;
+//   tabRef[GmfTetrahedra]     = 4;
+// //   tabRef[GmfHexahedra]      = 8;
+//   
+//   SMDS_NodeIteratorPtr itOnGMFInputNode = theMeshDS->nodesIterator();
+//   while ( itOnGMFInputNode->more() )
+//     theMeshDS->RemoveNode( itOnGMFInputNode->next() );
+// 
+//   
+//   int nbVertices = GmfStatKwd(InpMsh, GmfVertices);
+//   int nbCorners = max(countShape( theMeshDS, TopAbs_VERTEX ) , GmfStatKwd(InpMsh, GmfCorners));
+//   int nbShapeEdge = countShape( theMeshDS, TopAbs_EDGE );
+// 
+//   tabCorner       = new TopoDS_Shape[ nbCorners ];
+//   tabEdge         = new TopoDS_Shape[ nbShapeEdge ];
+//   nodeAssigne     = new int[ nbVertices + 1 ];
+//   GMFNodeAssigne  = new int[ nbVertices + 1 ];
+//   GMFNode         = new SMDS_MeshNode*[ nbVertices + 1 ];
+// 
+//   getShape(theMeshDS, TopAbs_VERTEX, tabCorner);
+//   getShape(theMeshDS, TopAbs_EDGE,   tabEdge);
+// 
+//   std::map <GmfKwdCod,int>::const_iterator it = tabRef.begin();
+//   for ( ; it != tabRef.end() ; ++it)
+//   {
+// //     int dummy;
+//     GmfKwdCod token = it->first;
+//     nbRef    = it->second;
+// 
+//     nbElem = GmfStatKwd(InpMsh, token);
+//     if (nbElem > 0) {
+//       GmfGotoKwd(InpMsh, token);
+//       std::cout << "Read " << nbElem;
+//     }
+//     else
+//       continue;
+// 
+//     int id[nbElem*tabRef[token]];
+//     int ghs3dShapeID[nbElem];
+// 
+//     if (token == GmfVertices) {
+//       std::cout << " vertices" << std::endl;
+//       int aGMFID;
+// 
+//       float VerTab_f[nbElem][3];
+//       double VerTab_d[nbElem][3];
+//       SMDS_MeshNode * aGMFNode;
+// 
+//       for ( int iElem = 0; iElem < nbElem; iElem++ ) {
+//         aGMFID = iElem + 1;
+//         if (ver == GmfFloat) {
+//           GmfGetLin(InpMsh, token, &VerTab_f[nbElem][0], &VerTab_f[nbElem][1], &VerTab_f[nbElem][2], &ghs3dShapeID[iElem]);
+//           aGMFNode = theMeshDS->AddNode(VerTab_f[nbElem][0], VerTab_f[nbElem][1], VerTab_f[nbElem][2]);
+//         }
+//         else {
+//           GmfGetLin(InpMsh, token, &VerTab_d[nbElem][0], &VerTab_d[nbElem][1], &VerTab_d[nbElem][2], &ghs3dShapeID[iElem]);
+//           aGMFNode = theMeshDS->AddNode(VerTab_d[nbElem][0], VerTab_d[nbElem][1], VerTab_d[nbElem][2]);
+//         }
+//         GMFNode[ aGMFID ] = aGMFNode;
+//         nodeAssigne[ aGMFID ] = 0;
+//         GMFNodeAssigne[ aGMFID ] = 0;
+//       }
+//     }
+//     else if (token == GmfCorners && nbElem > 0) {
+//       std::cout << " corners" << std::endl;
+//       for ( int iElem = 0; iElem < nbElem; iElem++ )
+//         GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]]);
+//     }
+//     else if (token == GmfRidges && nbElem > 0) {
+//       std::cout << " ridges" << std::endl;
+//       for ( int iElem = 0; iElem < nbElem; iElem++ )
+//         GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]]);
+//     }
+//     else if (token == GmfEdges && nbElem > 0) {
+//       std::cout << " edges" << std::endl;
+//       for ( int iElem = 0; iElem < nbElem; iElem++ )
+//         GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &ghs3dShapeID[iElem]);
+//     }
+//     else if (token == GmfTriangles && nbElem > 0) {
+//       std::cout << " triangles" << std::endl;
+//       for ( int iElem = 0; iElem < nbElem; iElem++ )
+//         GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &ghs3dShapeID[iElem]);
+//     }
+// //     else if (token == GmfQuadrilaterals && nbElem > 0) {
+// //       std::cout << " Quadrilaterals" << std::endl;
+// //       for ( int iElem = 0; iElem < nbElem; iElem++ )
+// //         GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &id[iElem*tabRef[token]+3], &ghs3dShapeID[iElem]);
+// //     }
+//     else if (token == GmfTetrahedra && nbElem > 0) {
+//       std::cout << " Tetrahedra" << std::endl;
+//       for ( int iElem = 0; iElem < nbElem; iElem++ )
+//         GmfGetLin(InpMsh, token, 
+//                   &id[iElem*tabRef[token]], 
+//                   &id[iElem*tabRef[token]+1], 
+//                   &id[iElem*tabRef[token]+2], 
+//                   &id[iElem*tabRef[token]+3], 
+//                   &ghs3dShapeID[iElem]);
+//     }
+// //     else if (token == GmfHexahedra && nbElem > 0) {
+// //       std::cout << " Hexahedra" << std::endl;
+// //       for ( int iElem = 0; iElem < nbElem; iElem++ )
+// //         GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &id[iElem*tabRef[token]+3],
+// //                   &id[iElem*tabRef[token]+4], &id[iElem*tabRef[token]+5], &id[iElem*tabRef[token]+6], &id[iElem*tabRef[token]+7], &ghs3dShapeID[iElem]);
+// //     }
+// 
+//     switch (token) {
+//     case GmfCorners:
+//     case GmfRidges:
+//     case GmfEdges:
+//     case GmfTriangles:
+// //     case GmfQuadrilaterals:
+//     case GmfTetrahedra:
+// //     case GmfHexahedra:
+//     {
+//       int nodeDim, shapeID, *nodeID;
+//       SMDS_MeshNode** node;
+// //       std::vector< SMDS_MeshNode* > enfNode( nbRef );
+//       SMDS_MeshElement * aGMFElement;
+//       
+//       node    = new SMDS_MeshNode*[nbRef];
+//       nodeID  = new int[ nbRef ];
+// 
+//       for ( int iElem = 0; iElem < nbElem; iElem++ )
+//       {
+//         for ( int iRef = 0; iRef < nbRef; iRef++ )
+//         {
+//           aGMFNodeID = id[iElem*tabRef[token]+iRef]; // read nbRef aGMFNodeID
+//           node  [ iRef ] = GMFNode[ aGMFNodeID ];
+//           nodeID[ iRef ] = aGMFNodeID;
+//         }
+// 
+//         switch (token)
+//         {
+//         case GmfCorners: {
+//           nodeDim = 1;
+//           gp_Pnt GMFPnt ( node[0]->X(), node[0]->Y(), node[0]->Z() );
+//           for ( int i=0; i<nbElem; i++ ) {
+//             aVertex = TopoDS::Vertex( tabCorner[i] );
+//             gp_Pnt aPnt = BRep_Tool::Pnt( aVertex );
+//             if ( aPnt.Distance( GMFPnt ) < epsilon )
+//               break;
+//           }
+//           break;
+//         }
+//         case GmfEdges: {
+//           nodeDim = 2;
+//           aGMFElement = theMeshDS->AddEdge( node[0], node[1] );
+//           int iNode = 1;
+//           if ( GMFNodeAssigne[ nodeID[0] ] == 0 || GMFNodeAssigne[ nodeID[0] ] == 2 )
+//             iNode = 0;
+//           shapeID = findEdgeID( node[iNode], theMeshDS, nbShapeEdge, tabEdge );
+//           break;
+//         }
+//         case GmfRidges:
+//           break;
+//         case GmfTriangles: {
+//           nodeDim = 3;
+//           aGMFElement = theMeshDS->AddFace( node[0], node[1], node[2]);
+//           shapeID = -1;
+//           break;
+//         }
+// //         case GmfQuadrilaterals: {
+// //           nodeDim = 4;
+// //           aGMFElement = theMeshDS->AddFace( node[0], node[1], node[2], node[3] );
+// //           shapeID = -1;
+// //           break;
+// //         }
+//         case GmfTetrahedra: {
+//           
+//           // IN WORK
+//           TopoDS_Shape aSolid;
+//           // We always run GHS3D with "to mesh holes"==TRUE but we must not create
+//           // tetras within holes depending on hypo option,
+//           // so we first check if aTet is inside a hole and then create it 
+//           if ( nbTriangle > 1 ) {
+//             tetraShapeID = HOLE_ID; // negative tetraShapeID means not to create tetras if !toMeshHoles
+//             int aGhs3dShapeID = ghs3dShapeID[iElem] - IdShapeRef;
+//             if ( tabID[ aGhs3dShapeID ] == 0 ) {
+//               TopAbs_State state;
+//               aSolid = findShape(node, aSolid, tabShape, tabBox, nbShape, &state);
+//               if ( toMeshHoles || state == TopAbs_IN )
+//                 tetraShapeID = theMeshDS->ShapeToIndex( aSolid );
+//               tabID[ aGhs3dShapeID ] = tetraShapeID;
+//             }
+//             else
+//               tetraShapeID = tabID[ aGhs3dShapeID ];
+//           }
+//           else if ( nbShape > 1 ) {
+//             // Case where nbTriangle == 1 while nbShape == 2 encountered
+//             // with compound of 2 boxes and "To mesh holes"==False,
+//             // so there are no subdomains specified for each tetrahedron.
+//             // Try to guess a solid by a node already bound to shape
+//             tetraShapeID = 0;
+//             for ( int i=0; i<4 && tetraShapeID==0; i++ ) {
+//               if ( nodeAssigne[ nodeID[i] ] == 1 &&
+//                   node[i]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_3DSPACE &&
+//                   node[i]->getshapeId() > 1 )
+//               {
+//                 tetraShapeID = node[i]->getshapeId();
+//               }
+//             }
+//             if ( tetraShapeID==0 ) {
+//               aSolid = findShape(node, aSolid, tabShape, tabBox, nbShape);
+//               tetraShapeID = theMeshDS->ShapeToIndex( aSolid );
+//             }
+//           }
+//           // set new nodes and tetrahedron onto the shape
+//           for ( int i=0; i<4; i++ ) {
+//             if ( nodeAssigne[ nodeID[i] ] == 0 ) {
+//               if ( tetraShapeID != HOLE_ID )
+//                 theMeshDS->SetNodeInVolume( node[i], tetraShapeID );
+//               nodeAssigne[ nodeID[i] ] = tetraShapeID;
+//             }
+//           }
+//           if ( toMeshHoles || tetraShapeID != HOLE_ID ) {
+//             aGMFElement = theMeshDS->AddVolume( node[1], node[0], node[2], node[3] );
+//             theMeshDS->SetMeshElementOnShape( aGMFElement, tetraShapeID );
+//           }
+//           
+//           // IN WORK
+//           
+//           nodeDim = 5;
+//           break;
+//         }
+// //         case GmfHexahedra: {
+// //           nodeDim = 6;
+// //           aGMFElement = theMeshDS->AddVolume( node[0], node[3], node[2], node[1],
+// //                                             node[4], node[7], node[6], node[5] );
+// //           break;
+// //         }
+//         default: continue;
+//         }
+//         if (token != GmfRidges)
+//         {
+//           for ( int i=0; i<nbRef; i++ ) {
+//               if ( GMFNodeAssigne[ nodeID[i] ] == 0 ) {
+//                 if      ( token == GmfCorners )   theMeshDS->SetNodeOnVertex( node[0], aVertex );
+//                 else if ( token == GmfEdges )     theMeshDS->SetNodeOnEdge( node[i], shapeID );
+//                 else if ( token == GmfTriangles ) theMeshDS->SetNodeOnFace( node[i], shapeID );
+//                 GMFNodeAssigne[ nodeID[i] ] = nodeDim;
+//               }
+//             }
+//             if ( token != "Corners" )
+//               theMeshDS->SetMeshElementOnShape( aGMFElement, shapeID );
+//         }
+//       } // for
+//       
+//       if ( !toMeshHoles ) {
+//         map <int,const SMDS_MeshNode*>::iterator itOnNode = theGhs3dIdToNodeMap.find( nbVertices-(nbEnforcedVertices+nbEnforcedNodes) );
+//         for ( ; itOnNode != theGhs3dIdToNodeMap.end(); ++itOnNode) {
+//           if ( nodeAssigne[ itOnNode->first ] == HOLE_ID )
+//             theMeshDS->RemoveFreeNode( itOnNode->second, 0 );
+//         }
+//       }
+//       
+//       delete [] node;
+//       delete [] nodeID;
+//       break;
+//       } // case GmfTetrahedra
+//     } // switch(token)
+//   } // for
+//   cout << std::endl;
+//   
+// #ifdef WNT
+//   UnmapViewOfFile(mapPtr);
+//   CloseHandle(hMapObject);
+//   CloseHandle(fd);
+// #else
+//   munmap(mapPtr, length);
+// #endif
+//   close(fileOpen);
+//   
+//   delete [] tabID;
+//   delete [] tabCorner;
+//   delete [] tabEdge;
+//   delete [] nodeAssigne;
+//   delete [] GMFNodeAssigne;
+//   delete [] GMFNode;
+//   
+//   return true;
+// }
 
-  std::cout << "    " << facesMap.Extent() << " shapes of 2D dimension" << std::endl;
-  std::cout << std::endl;
 
-  theFile << space << nbTriangles << space << dummyint << std::endl;
+//=======================================================================
+//function : updateMeshGroups
+//purpose  : Update or create groups in mesh
+//=======================================================================
 
-  for ( int i = 1; i <= facesMap.Extent(); i++ )
-  {
-    aShape = facesMap(i);
-    theSubMesh = theMesh.GetSubMesh(aShape);
-    if ( !theSubMesh ) continue;
-    itOnSubMesh = theSubMesh->GetElements();
-    while ( itOnSubMesh->more() )
-    {
-      aFace = itOnSubMesh->next();
-      nbNodes = aFace->NbNodes();
-
-      theFile << space << nbNodes;
-
-      itOnSubFace = aFace->nodesIterator();
-      while ( itOnSubFace->more() ) {
-        // find GHS3D ID
-        aSmdsID = itOnSubFace->next()->GetID();
-        itOnMap = theSmdsToGhs3dIdMap.find( aSmdsID );
-        // if ( itOnMap == theSmdsToGhs3dIdMap.end() ) {
-        //   cout << "not found node: " << aSmdsID << endl;
-        //   return false;
-        // }
-        ASSERT( itOnMap != theSmdsToGhs3dIdMap.end() );
-
-        theFile << space << (*itOnMap).second;
-      }
-
-      // (NB_NODES + 1) times: DUMMY_INT
-      for ( int j=0; j<=nbNodes; j++)
-        theFile << space << dummyint;
-
-      theFile << std::endl;
+static void updateMeshGroups(SMESH_Mesh* theMesh,
+                             const SMDS_MeshElement* anElem,
+                             std::string groupName)
+{
+  bool groupDone = false;
+  SMESH_Mesh::GroupIteratorPtr grIt = theMesh->GetGroups();
+  while (grIt->more()) {
+    SMESH_Group * group = grIt->next();
+    if ( !group ) continue;
+    SMESHDS_GroupBase* groupDS = group->GetGroupDS();
+    if ( !groupDS ) continue;
+    if ( groupDS->GetType()==anElem->GetType() && groupName.compare(group->GetName())==0) {
+      SMESHDS_Group* aGroupDS = static_cast<SMESHDS_Group*>( groupDS );
+      aGroupDS->SMDSGroup().Add(anElem);
+      groupDone = true;
+      MESSAGE("Successfully added enforced element to existing group " << groupName);
+      break;
     }
   }
-
-  return true;
+  if (!groupDone)
+  {
+    int groupId;
+    SMESH_Group* aGroup = theMesh->AddGroup(anElem->GetType(), groupName.c_str(), groupId);
+    aGroup->SetName( groupName.c_str() );
+    SMESHDS_Group* aGroupDS = static_cast<SMESHDS_Group*>( aGroup->GetGroupDS() );
+    aGroupDS->SMDSGroup().Add(anElem);
+    MESSAGE("Successfully created enforced vertex group " << groupName);
+    groupDone = true;
+  }
+  if (!groupDone)
+    throw SALOME_Exception(LOCALIZED("A enforced vertex node was not added to a group"));
 }
 
 //=======================================================================
-//function : writeFaces
-//purpose  : Write Faces in case if generate 3D mesh w/o geometry
+//function : readGMFFile
+//purpose  : read GMF file w/o geometry associated to mesh
 //=======================================================================
 
-static bool writeFaces (ofstream &                      theFile,
-                        const SMESH_ProxyMesh&          theMesh,
-                        vector <const SMDS_MeshNode*> & theNodeByGhs3dId)
+static bool readGMFFile(const char*                     theFile,
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+                        GHS3DPlugin_GHS3D*              theAlgo,
+#endif 
+                        SMESH_MesherHelper*             theHelper,
+                        TopoDS_Shape                    theSolid,
+                        vector <const SMDS_MeshNode*> & theNodeByGhs3dId,
+                        map<const SMDS_MeshNode*,int> & theNodeToGhs3dIdMap,
+                        std::vector<std::string> &      aNodeGroupByGhs3dId,
+                        std::vector<std::string> &      anEdgeGroupByGhs3dId,
+                        std::vector<std::string> &      aFaceGroupByGhs3dId)
 {
-  // record structure:
-  //
-  // NB_ELEMS DUMMY_INT
-  // Loop from 1 to NB_ELEMS
-  //   NB_NODES NODE_NB_1 NODE_NB_2 ... (NB_NODES + 1) times: DUMMY_INT
+  SMESHDS_Mesh* theMeshDS = theHelper->GetMeshDS();
 
-  int nbNodes, nbTriangles = 0;
-  map< const SMDS_MeshNode*,int >::iterator it;
-  SMDS_ElemIteratorPtr nodeIt;
-  const SMDS_MeshElement* elem;
+  int nbInitialNodes = theNodeByGhs3dId.size();
+  std::cout << "theNodeByGhs3dId.size(): " << nbInitialNodes << std::endl;
+  int nbMeshNodes = theMeshDS->NbNodes();
+  std::cout << "theHelper->GetMesh()->NbNodes(): " << nbMeshNodes << std::endl;
+  
+  const bool isQuadMesh = 
+    theHelper->GetMesh()->NbEdges( ORDER_QUADRATIC ) ||
+    theHelper->GetMesh()->NbFaces( ORDER_QUADRATIC ) ||
+    theHelper->GetMesh()->NbVolumes( ORDER_QUADRATIC );
+  std::cout << "isQuadMesh: " << isQuadMesh << std::endl;
+  
+  if (theHelper->GetSubShapeID() != 0)
+    theHelper->IsQuadraticSubMesh( theHelper->GetSubShape() );
+
+  // ---------------------------------
+  // Read generated elements and nodes
+  // ---------------------------------
+
+  int nbElem = 0, nbRef = 0;
+  int aGMFNodeID = 0, shapeID;
+  int *nodeAssigne;
+  const SMDS_MeshNode** GMFNode;
+  std::map <GmfKwdCod,int> tabRef;
+
+  tabRef[GmfVertices]       = 3; // for new nodes and enforced nodes
+  tabRef[GmfCorners]        = 1;
+  tabRef[GmfEdges]          = 2; // for enforced edges
+  tabRef[GmfRidges]         = 1;
+  tabRef[GmfTriangles]      = 3; // for enforced faces
+  tabRef[GmfQuadrilaterals] = 4;
+  tabRef[GmfTetrahedra]     = 4; // for new tetras
+  tabRef[GmfHexahedra]      = 8;
+
+  int ver, dim;
+  MESSAGE("Read " << theFile << " file");
+  int InpMsh = GmfOpenMesh(theFile, GmfRead, &ver, &dim);
+  if (!InpMsh)
+    return false;
+  MESSAGE("Done ");
 
-  const char* space    = "  ";
-  const int   dummyint = 0;
+  // Issue 0020682. Avoid creating nodes and tetras at place where
+  // volumic elements already exist
+  SMESH_ElementSearcher* elemSearcher = 0;
+  vector< const SMDS_MeshElement* > foundVolumes;
+  if ( theHelper->GetMesh()->NbVolumes() > 0 )
+    elemSearcher = SMESH_MeshEditor( theHelper->GetMesh() ).GetElementSearcher();
 
-  // count faces
-  nbTriangles = theMesh.NbFaces();
+  int nbVertices = GmfStatKwd(InpMsh, GmfVertices) - nbInitialNodes;
+  GMFNode = new const SMDS_MeshNode*[ nbVertices + 1 ];
+  nodeAssigne = new int[ nbVertices + 1 ];
 
-  if ( nbTriangles == 0 )
-    return false;
+  std::map <GmfKwdCod,int>::const_iterator it = tabRef.begin();
+  for ( ; it != tabRef.end() ; ++it)
+  {
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+    if(theAlgo->computeCanceled()) {
+      GmfCloseMesh(InpMsh);
+      delete [] GMFNode;
+      delete [] nodeAssigne;
+      return false;
+    }
+#endif
+    int dummy;
+    GmfKwdCod token = it->first;
+    nbRef    = it->second;
+
+    nbElem = GmfStatKwd(InpMsh, token);
+    if (nbElem > 0) {
+      GmfGotoKwd(InpMsh, token);
+      std::cout << "Read " << nbElem;
+    }
+    else
+      continue;
+
+    std::vector<int> id (nbElem*tabRef[token]); // node ids
+
+    if (token == GmfVertices) {
+      std::cout << " vertices" << std::endl;
+      std::cout << nbInitialNodes << " from input mesh " << std::endl;
+
+      // Remove orphan nodes from previous enforced mesh which was cleared
+//       if ( nbElem < nbMeshNodes ) {
+//         const SMDS_MeshNode* node;
+//         SMDS_NodeIteratorPtr nodeIt = theMeshDS->nodesIterator();
+//         while ( nodeIt->more() )
+//         {
+//           node = nodeIt->next();
+//           if (theNodeToGhs3dIdMap.find(node) != theNodeToGhs3dIdMap.end())
+//             theMeshDS->RemoveNode(node);
+//         }
+//       }
+
+      
+      int aGMFID;
+
+      float VerTab_f[3];
+      double x, y, z;
+      const SMDS_MeshNode * aGMFNode;
+
+      //shapeID = theMeshDS->ShapeToIndex( theSolid );
+      for ( int iElem = 0; iElem < nbElem; iElem++ ) {
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+        if(theAlgo->computeCanceled()) {
+          GmfCloseMesh(InpMsh);
+          delete [] GMFNode;
+          delete [] nodeAssigne;
+          return false;
+        }
+#endif
+        if (ver == GmfFloat) {
+          GmfGetLin(InpMsh, token, &VerTab_f[0], &VerTab_f[1], &VerTab_f[2], &dummy);
+          x = VerTab_f[0];
+          y = VerTab_f[1];
+          z = VerTab_f[2];
+        }
+        else {
+          GmfGetLin(InpMsh, token, &x, &y, &z, &dummy);
+        }
+        if (iElem >= nbInitialNodes) {
+          if ( elemSearcher &&
+                elemSearcher->FindElementsByPoint( gp_Pnt(x,y,z), SMDSAbs_Volume, foundVolumes))
+            aGMFNode = 0;
+          else
+            aGMFNode = theHelper->AddNode(x, y, z);
+          
+          aGMFID = iElem -nbInitialNodes +1;
+          GMFNode[ aGMFID ] = aGMFNode;
+          nodeAssigne[ aGMFID ] = 0;
+          if (aGMFID-1 < aNodeGroupByGhs3dId.size() && !aNodeGroupByGhs3dId.at(aGMFID-1).empty())
+            updateMeshGroups(theHelper->GetMesh(), aGMFNode, aNodeGroupByGhs3dId.at(aGMFID-1));
+        }
+      }
+    }
+    else if (token == GmfCorners && nbElem > 0) {
+      std::cout << " corners" << std::endl;
+      for ( int iElem = 0; iElem < nbElem; iElem++ )
+        GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]]);
+    }
+    else if (token == GmfRidges && nbElem > 0) {
+      std::cout << " ridges" << std::endl;
+      for ( int iElem = 0; iElem < nbElem; iElem++ )
+        GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]]);
+    }
+    else if (token == GmfEdges && nbElem > 0) {
+      std::cout << " edges" << std::endl;
+      for ( int iElem = 0; iElem < nbElem; iElem++ )
+        GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &dummy);
+    }
+    else if (token == GmfTriangles && nbElem > 0) {
+      std::cout << " triangles" << std::endl;
+      for ( int iElem = 0; iElem < nbElem; iElem++ )
+        GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &dummy);
+    }
+    else if (token == GmfQuadrilaterals && nbElem > 0) {
+      std::cout << " Quadrilaterals" << std::endl;
+      for ( int iElem = 0; iElem < nbElem; iElem++ )
+        GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &id[iElem*tabRef[token]+3], &dummy);
+    }
+    else if (token == GmfTetrahedra && nbElem > 0) {
+      std::cout << " Tetrahedra" << std::endl;
+      for ( int iElem = 0; iElem < nbElem; iElem++ )
+        GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &id[iElem*tabRef[token]+3], &dummy);
+    }
+    else if (token == GmfHexahedra && nbElem > 0) {
+      std::cout << " Hexahedra" << std::endl;
+      for ( int iElem = 0; iElem < nbElem; iElem++ )
+        GmfGetLin(InpMsh, token, &id[iElem*tabRef[token]], &id[iElem*tabRef[token]+1], &id[iElem*tabRef[token]+2], &id[iElem*tabRef[token]+3],
+                  &id[iElem*tabRef[token]+4], &id[iElem*tabRef[token]+5], &id[iElem*tabRef[token]+6], &id[iElem*tabRef[token]+7], &dummy);
+    }
+    std::cout << std::endl;
 
-  std::cout << "The initial 2D mesh contains " << nbTriangles << " faces and ";
+    switch (token) {
+    case GmfCorners:
+    case GmfRidges:
+    case GmfEdges:
+    case GmfTriangles:
+    case GmfQuadrilaterals:
+    case GmfTetrahedra:
+    case GmfHexahedra:
+    {
+      std::vector< const SMDS_MeshNode* > node( nbRef );
+      std::vector< int >          nodeID( nbRef );
+      std::vector< SMDS_MeshNode* > enfNode( nbRef );
+      const SMDS_MeshElement* aCreatedElem;
 
-  // NB_ELEMS DUMMY_INT
-  theFile << space << nbTriangles << space << dummyint << std::endl;
+      for ( int iElem = 0; iElem < nbElem; iElem++ )
+      {
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+        if(theAlgo->computeCanceled()) {
+          GmfCloseMesh(InpMsh);
+          delete [] GMFNode;
+          delete [] nodeAssigne;
+          return false;
+        }
+#endif
+        // Check if elem is already in input mesh. If yes => skip
+        bool fullyCreatedElement = false; // if at least one of the nodes was created
+        for ( int iRef = 0; iRef < nbRef; iRef++ )
+        {
+          aGMFNodeID = id[iElem*tabRef[token]+iRef]; // read nbRef aGMFNodeID
+          if (aGMFNodeID <= nbInitialNodes) // input nodes
+          {
+            aGMFNodeID--;
+            node[ iRef ] = theNodeByGhs3dId[aGMFNodeID];
+          }
+          else
+          {
+            fullyCreatedElement = true;
+            aGMFNodeID -= nbInitialNodes;
+            nodeID[ iRef ] = aGMFNodeID ;
+            node  [ iRef ] = GMFNode[ aGMFNodeID ];
+          }
+        }
+
+        switch (token)
+        {
+        case GmfEdges:
+          if (fullyCreatedElement) {
+            aCreatedElem = theHelper->AddEdge( node[0], node[1], /*id =*/0, /*force3d =*/false );
+            if (anEdgeGroupByGhs3dId.size() && !anEdgeGroupByGhs3dId[iElem].empty())
+              updateMeshGroups(theHelper->GetMesh(), aCreatedElem, anEdgeGroupByGhs3dId[iElem]);
+          }
+          break;
+        case GmfTriangles:
+          if (fullyCreatedElement) {
+            aCreatedElem = theHelper->AddFace( node[0], node[1], node[2], /*id =*/0, /*force3d =*/false );
+            for ( int iRef = 0; iRef < nbRef; iRef++ )
+              nodeAssigne[ nodeID[ iRef ]] = 1;
+            if (aFaceGroupByGhs3dId.size() && !aFaceGroupByGhs3dId[iElem].empty())
+              updateMeshGroups(theHelper->GetMesh(), aCreatedElem, aFaceGroupByGhs3dId[iElem]);
+          }
+          break;
+        case GmfQuadrilaterals:
+          if (fullyCreatedElement) {
+            theHelper->AddFace( node[0], node[1], node[2], node[3], /*id =*/0, /*force3d =*/false );
+            for ( int iRef = 0; iRef < nbRef; iRef++ )
+              nodeAssigne[ nodeID[ iRef ]] = 1;
+          }
+        case GmfTetrahedra:
+          if ( elemSearcher ) {
+            // Issue 0020682. Avoid creating nodes and tetras at place where
+            // volumic elements already exist
+            if ( !node[1] || !node[0] || !node[2] || !node[3] )
+              continue;
+            if ( elemSearcher->FindElementsByPoint((SMESH_TNodeXYZ(node[0]) +
+                                                    SMESH_TNodeXYZ(node[1]) +
+                                                    SMESH_TNodeXYZ(node[2]) +
+                                                    SMESH_TNodeXYZ(node[3]) ) / 4.,
+                                                    SMDSAbs_Volume, foundVolumes ))
+            break;
+          }
+          theHelper->AddVolume( node[1], node[0], node[2], node[3], /*id =*/0, /*force3d =*/false );
+//           theMeshDS->SetMeshElementOnShape( aTet, shapeID );
+          break;
+        case GmfHexahedra:
+          if ( elemSearcher ) {
+            // Issue 0020682. Avoid creating nodes and tetras at place where
+            // volumic elements already exist
+            if ( !node[1] || !node[0] || !node[2] || !node[3] || !node[4] || !node[5] || !node[6] || !node[7])
+              continue;
+            if ( elemSearcher->FindElementsByPoint((SMESH_TNodeXYZ(node[0]) +
+                                                    SMESH_TNodeXYZ(node[1]) +
+                                                    SMESH_TNodeXYZ(node[2]) +
+                                                    SMESH_TNodeXYZ(node[3]) +
+                                                    SMESH_TNodeXYZ(node[4]) +
+                                                    SMESH_TNodeXYZ(node[5]) +
+                                                    SMESH_TNodeXYZ(node[6]) +
+                                                    SMESH_TNodeXYZ(node[7])) / 8.,
+                                                    SMDSAbs_Volume, foundVolumes ))
+            break;
+          }
+          theHelper->AddVolume( node[0], node[3], node[2], node[1],
+                                node[4], node[7], node[6], node[5], /*id =*/0, /*force3d =*/false );
+//           theMeshDS->SetMeshElementOnShape( aTet, shapeID );
+          break;
+        default: continue;
+        }
+      }
+      break;
+    }
+    }
+  }
 
+  for ( int i = 0; i < nbVertices; ++i ) {
+    if ( !nodeAssigne[ i+1 ])
+      theMeshDS->SetNodeInVolume( GMFNode[ i+1 ], shapeID );
+  }
 
-  map<const SMDS_MeshNode*,int> aNodeToGhs3dIdMap;
+  GmfCloseMesh(InpMsh);
+  delete [] GMFNode;
+  delete [] nodeAssigne;
+  return true;
+}
 
-  // Loop from 1 to NB_ELEMS
+static bool writeGMFFile(const char*                                     theMeshFileName,
+                         const char*                                     theRequiredFileName,
+                         const char*                                     theSolFileName,
+                         const SMESH_ProxyMesh&                          theProxyMesh,
+                         SMESH_Mesh *                                    theMesh,
+                         std::vector <const SMDS_MeshNode*> &            theNodeByGhs3dId,
+                         std::vector <const SMDS_MeshNode*> &            theEnforcedNodeByGhs3dId,
+                         std::map<const SMDS_MeshNode*,int> &            aNodeToGhs3dIdMap,
+                         std::vector<std::string> &                      aNodeGroupByGhs3dId,
+                         std::vector<std::string> &                      anEdgeGroupByGhs3dId,
+                         std::vector<std::string> &                      aFaceGroupByGhs3dId,
+                         GHS3DPlugin_Hypothesis::TIDSortedNodeGroupMap & theEnforcedNodes,
+                         GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap & theEnforcedEdges,
+                         GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap & theEnforcedTriangles,
+                         std::map<std::vector<double>, std::string> &    enfVerticesWithGroup,
+                         GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexCoordsValues & theEnforcedVertices)
+{
+  MESSAGE("writeGMFFile w/o geometry");
+  int idx, idxRequired = 0, idxSol = 0;
+  const int dummyint = 0;
+  GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexCoordsValues::const_iterator vertexIt;
+  std::vector<double> enfVertexSizes;
+  const SMDS_MeshElement* elem;
+  TIDSortedElemSet anElemSet, theKeptEnforcedEdges, theKeptEnforcedTriangles;
+  SMDS_ElemIteratorPtr nodeIt;
+  map<const SMDS_MeshNode*,int> anEnforcedNodeToGhs3dIdMap;
+  GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap::iterator elemIt;
+  TIDSortedElemSet::iterator elemSetIt;
+  bool isOK;
+  auto_ptr< SMESH_ElementSearcher > pntCls ( SMESH_MeshEditor( theMesh ).GetElementSearcher());
+  
+  int nbEnforcedVertices = theEnforcedVertices.size();
+  
+  // count faces
+  int nbFaces = theProxyMesh.NbFaces();
+  int nbNodes;
 
-  SMDS_ElemIteratorPtr eIt = theMesh.GetFaces();
+  if ( nbFaces == 0 )
+    return false;
+  
+  idx = GmfOpenMesh(theMeshFileName, GmfWrite, GMFVERSION, GMFDIMENSION);
+  if (!idx)
+    return false;
+  
+  /* ========================== FACES ========================== */
+  /* TRIANGLES ========================== */
+  SMDS_ElemIteratorPtr eIt = theProxyMesh.GetFaces();
   while ( eIt->more() )
   {
     elem = eIt->next();
-    // NB_NODES PER FACE
-    nbNodes = elem->NbNodes();
-    theFile << space << nbNodes;
-
-    // NODE_NB_1 NODE_NB_2 ...
+    anElemSet.insert(elem);
     nodeIt = elem->nodesIterator();
-    while ( nodeIt->more() )
+    nbNodes = elem->NbCornerNodes();
+    while ( nodeIt->more() && nbNodes--)
     {
       // find GHS3D ID
       const SMDS_MeshNode* node = castToNode( nodeIt->next() );
       int newId = aNodeToGhs3dIdMap.size() + 1; // ghs3d ids count from 1
-      it = aNodeToGhs3dIdMap.insert( make_pair( node, newId )).first;
-      theFile << space << it->second;
+      aNodeToGhs3dIdMap.insert( make_pair( node, newId ));
     }
-
-    // (NB_NODES + 1) times: DUMMY_INT
-    for ( int i=0; i<=nbNodes; i++)
-      theFile << space << dummyint;
-    theFile << std::endl;
   }
-
+  
+  /* EDGES ========================== */
+  
+  // Iterate over the enforced edges
+  for(elemIt = theEnforcedEdges.begin() ; elemIt != theEnforcedEdges.end() ; ++elemIt) {
+    elem = elemIt->first;
+    isOK = true;
+    nodeIt = elem->nodesIterator();
+    nbNodes = 2;
+    while ( nodeIt->more() && nbNodes-- ) {
+      // find GHS3D ID
+      const SMDS_MeshNode* node = castToNode( nodeIt->next() );
+      // Test if point is inside shape to mesh
+      gp_Pnt myPoint(node->X(),node->Y(),node->Z());
+      TopAbs_State result = pntCls->GetPointState( myPoint );
+      if ( result != TopAbs_IN ) {
+        isOK = false;
+        break;
+      }
+    }
+    if (isOK) {
+      nodeIt = elem->nodesIterator();
+      nbNodes = 2;
+      while ( nodeIt->more() && nbNodes-- ) {
+        // find GHS3D ID
+        const SMDS_MeshNode* node = castToNode( nodeIt->next() );
+        int newId = aNodeToGhs3dIdMap.size() + anEnforcedNodeToGhs3dIdMap.size() + 1; // ghs3d ids count from 1
+        anEnforcedNodeToGhs3dIdMap.insert( make_pair( node, newId ));
+      }
+      theKeptEnforcedEdges.insert(elem);
+    }
+  }
+  
+  /* ENFORCED TRIANGLES ========================== */
+  
+  // Iterate over the enforced triangles
+  for(elemIt = theEnforcedTriangles.begin() ; elemIt != theEnforcedTriangles.end() ; ++elemIt) {
+    elem = elemIt->first;
+    isOK = true;
+    nodeIt = elem->nodesIterator();
+    nbNodes = 3;
+    while ( nodeIt->more() && nbNodes--) {
+      // find GHS3D ID
+      const SMDS_MeshNode* node = castToNode( nodeIt->next() );
+      // Test if point is inside shape to mesh
+      gp_Pnt myPoint(node->X(),node->Y(),node->Z());
+      TopAbs_State result = pntCls->GetPointState( myPoint );
+      if ( result != TopAbs_IN ) {
+        isOK = false;
+        break;
+      }
+    }
+    if (isOK) {
+      nodeIt = elem->nodesIterator();
+      nbNodes = 3;
+      while ( nodeIt->more() && nbNodes--) {
+        // find GHS3D ID
+        const SMDS_MeshNode* node = castToNode( nodeIt->next() );
+        int newId = aNodeToGhs3dIdMap.size() + anEnforcedNodeToGhs3dIdMap.size() + 1; // ghs3d ids count from 1
+        anEnforcedNodeToGhs3dIdMap.insert( make_pair( node, newId ));
+      }
+      theKeptEnforcedTriangles.insert(elem);
+    }
+  }
+  
   // put nodes to theNodeByGhs3dId vector
+  std::cout << "aNodeToGhs3dIdMap.size(): "<<aNodeToGhs3dIdMap.size()<<std::endl;
   theNodeByGhs3dId.resize( aNodeToGhs3dIdMap.size() );
   map<const SMDS_MeshNode*,int>::const_iterator n2id = aNodeToGhs3dIdMap.begin();
   for ( ; n2id != aNodeToGhs3dIdMap.end(); ++ n2id)
   {
+//     std::cout << "n2id->first: "<<n2id->first<<std::endl;
     theNodeByGhs3dId[ n2id->second - 1 ] = n2id->first; // ghs3d ids count from 1
   }
 
-  return true;
-}
-
-//=======================================================================
-//function : writePoints
-//purpose  : 
-//=======================================================================
-
-static bool writePoints (ofstream &                       theFile,
-                         SMESH_MesherHelper&              theHelper,
-                         map <int,int> &                  theSmdsToGhs3dIdMap,
-                         map <int,const SMDS_MeshNode*> & theGhs3dIdToNodeMap,
-                         map<vector<double>,double> &     theEnforcedVertices)
-{
-  // record structure:
-  //
-  // NB_NODES
-  // Loop from 1 to NB_NODES
-  //   X Y Z DUMMY_INT
-
-  SMESHDS_Mesh * theMesh = theHelper.GetMeshDS();
-  int nbNodes = theMesh->NbNodes();
-  if ( nbNodes == 0 )
-    return false;
-  int nbEnforcedVertices = theEnforcedVertices.size();
-
-  // Issue 020674: EDF 870 SMESH: Mesh generated by Netgen not usable by GHS3D
-  // The problem is in nodes on degenerated edges, we need to skip them
-  if ( theHelper.HasDegeneratedEdges() )
+  // put nodes to anEnforcedNodeToGhs3dIdMap vector
+  std::cout << "anEnforcedNodeToGhs3dIdMap.size(): "<<anEnforcedNodeToGhs3dIdMap.size()<<std::endl;
+  theEnforcedNodeByGhs3dId.resize( anEnforcedNodeToGhs3dIdMap.size() );
+  n2id = anEnforcedNodeToGhs3dIdMap.begin();
+  for ( ; n2id != anEnforcedNodeToGhs3dIdMap.end(); ++ n2id)
   {
-    // here we decrease total nb of nodes by nb of nodes on degenerated edges
-    set<int> checkedSM;
-    for (TopExp_Explorer e(theMesh->ShapeToMesh(), TopAbs_EDGE ); e.More(); e.Next())
-    {
-      SMESH_subMesh* sm = theHelper.GetMesh()->GetSubMesh( e.Current() );
-      if ( checkedSM.insert( sm->GetId() ).second && theHelper.IsDegenShape(sm->GetId() )) {
-        if ( sm->GetSubMeshDS() )
-          nbNodes -= sm->GetSubMeshDS()->NbNodes();
-      }
+//     std::cout << "n2id->first: "<<n2id->first<<std::endl;
+    theEnforcedNodeByGhs3dId[ n2id->second - aNodeToGhs3dIdMap.size() - 1 ] = n2id->first; // ghs3d ids count from 1
+  }
+  
+  
+  /* ========================== NODES ========================== */
+  vector<const SMDS_MeshNode*> theOrderedNodes, theRequiredNodes;
+  std::set< std::vector<double> > nodesCoords;
+  vector<const SMDS_MeshNode*>::const_iterator ghs3dNodeIt = theNodeByGhs3dId.begin();
+  vector<const SMDS_MeshNode*>::const_iterator after  = theNodeByGhs3dId.end();
+  
+  std::cout << theNodeByGhs3dId.size() << " nodes from mesh ..." << std::endl;
+  for ( ; ghs3dNodeIt != after; ++ghs3dNodeIt )
+  {
+    const SMDS_MeshNode* node = *ghs3dNodeIt;
+    std::vector<double> coords;
+    coords.push_back(node->X());
+    coords.push_back(node->Y());
+    coords.push_back(node->Z());
+    nodesCoords.insert(coords);
+    theOrderedNodes.push_back(node);
+  }
+  
+  // Iterate over the enforced nodes given by enforced elements
+  ghs3dNodeIt = theEnforcedNodeByGhs3dId.begin();
+  after  = theEnforcedNodeByGhs3dId.end();
+  std::cout << theEnforcedNodeByGhs3dId.size() << " nodes from enforced elements ..." << std::endl;
+  for ( ; ghs3dNodeIt != after; ++ghs3dNodeIt )
+  {
+    const SMDS_MeshNode* node = *ghs3dNodeIt;
+    std::vector<double> coords;
+    coords.push_back(node->X());
+    coords.push_back(node->Y());
+    coords.push_back(node->Z());
+    
+    if (nodesCoords.find(coords) != nodesCoords.end()) {
+      std::cout << "Node at " << node->X()<<", " <<node->Y()<<", " <<node->Z() << " found" << std::endl;
+      continue;
     }
+    
+    if (theEnforcedVertices.find(coords) != theEnforcedVertices.end())
+      continue;
+    
+    nodesCoords.insert(coords);
+    theOrderedNodes.push_back(node);
+//     theRequiredNodes.push_back(node);
   }
-  const char* space    = "  ";
-  const int   dummyint = 0;
-
-  int aGhs3dID = 1;
-  SMDS_NodeIteratorPtr it = theMesh->nodesIterator();
-  const SMDS_MeshNode* node;
+  
+  
+  // Iterate over the enforced nodes
+  GHS3DPlugin_Hypothesis::TIDSortedNodeGroupMap::const_iterator enfNodeIt;
+  std::cout << theEnforcedNodes.size() << " nodes from enforced nodes ..." << std::endl;
+  for(enfNodeIt = theEnforcedNodes.begin() ; enfNodeIt != theEnforcedNodes.end() ; ++enfNodeIt)
+  {
+    const SMDS_MeshNode* node = enfNodeIt->first;
+    std::vector<double> coords;
+    coords.push_back(node->X());
+    coords.push_back(node->Y());
+    coords.push_back(node->Z());
+    
+    if (nodesCoords.find(coords) != nodesCoords.end()) {
+      std::cout << "Node at " << node->X()<<", " <<node->Y()<<", " <<node->Z() << " found" << std::endl;
+      continue;
+    }
 
-  // NB_NODES
-  std::cout << std::endl;
-  std::cout << "The initial 2D mesh contains :" << std::endl;
-  std::cout << "    " << nbNodes << " nodes" << std::endl;
-  if (nbEnforcedVertices > 0) {
-    std::cout << "    " << nbEnforcedVertices << " enforced vertices" << std::endl;
+    if (theEnforcedVertices.find(coords) != theEnforcedVertices.end())
+      continue;
+    
+    // Test if point is inside shape to mesh
+    gp_Pnt myPoint(node->X(),node->Y(),node->Z());
+    TopAbs_State result = pntCls->GetPointState( myPoint );
+    if ( result != TopAbs_IN )
+      continue;
+    
+    nodesCoords.insert(coords);
+//     theOrderedNodes.push_back(node);
+    theRequiredNodes.push_back(node);
+  }
+  int requiredNodes = theRequiredNodes.size();
+  
+  int solSize = 0;
+  std::vector<std::vector<double> > ReqVerTab;
+  if (nbEnforcedVertices) {
+//    ReqVerTab.clear();
+    std::cout << theEnforcedVertices.size() << " nodes from enforced vertices ..." << std::endl;
+    // Iterate over the enforced vertices
+    for(vertexIt = theEnforcedVertices.begin() ; vertexIt != theEnforcedVertices.end() ; ++vertexIt) {
+      double x = vertexIt->first[0];
+      double y = vertexIt->first[1];
+      double z = vertexIt->first[2];
+      // Test if point is inside shape to mesh
+      gp_Pnt myPoint(x,y,z);
+      TopAbs_State result = pntCls->GetPointState( myPoint );
+      if ( result != TopAbs_IN )
+        continue;
+      std::vector<double> coords;
+      coords.push_back(x);
+      coords.push_back(y);
+      coords.push_back(z);
+      ReqVerTab.push_back(coords);
+      enfVertexSizes.push_back(vertexIt->second);
+      solSize++;
+    }
   }
-  std::cout << std::endl;
-  std::cout << "Start writing in 'points' file ..." << std::endl;
-  theFile << space << nbNodes << std::endl;
 
-  // Loop from 1 to NB_NODES
+  // GmfVertices
+  std::cout << "Begin writting required nodes in GmfVertices" << std::endl;
+  GmfSetKwd(idx, GmfVertices, theOrderedNodes.size()/*+solSize*/);
+  for (ghs3dNodeIt = theOrderedNodes.begin();ghs3dNodeIt != theOrderedNodes.end();++ghs3dNodeIt)
+    GmfSetLin(idx, GmfVertices, (*ghs3dNodeIt)->X(), (*ghs3dNodeIt)->Y(), (*ghs3dNodeIt)->Z(), dummyint);
 
-  while ( it->more() )
-  {
-    node = it->next();
-    if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE &&
-         theHelper.IsDegenShape( node->getshapeId() )) // Issue 020674
-      continue;
+  std::cout << "End writting required nodes in GmfVertices" << std::endl;
 
-    theSmdsToGhs3dIdMap.insert( make_pair( node->GetID(), aGhs3dID ));
-    theGhs3dIdToNodeMap.insert( make_pair( aGhs3dID, node ));
-    aGhs3dID++;
+  if (requiredNodes + solSize) {
+    std::cout << "Begin writting in req and sol file" << std::endl;
+    aNodeGroupByGhs3dId.resize( requiredNodes + solSize );
+    idxRequired = GmfOpenMesh(theRequiredFileName, GmfWrite, GMFVERSION, GMFDIMENSION);
+    if (!idxRequired) {
+      GmfCloseMesh(idx);
+      return false;
+    }
+    idxSol = GmfOpenMesh(theSolFileName, GmfWrite, GMFVERSION, GMFDIMENSION);
+    if (!idxSol) {
+      GmfCloseMesh(idx);
+      if (idxRequired)
+        GmfCloseMesh(idxRequired);
+      return false;
+    }
+    int TypTab[] = {GmfSca};
+    GmfSetKwd(idxRequired, GmfVertices, requiredNodes + solSize);
+    GmfSetKwd(idxSol, GmfSolAtVertices, requiredNodes + solSize, 1, TypTab);
+    int usedEnforcedNodes = 0;
+    for (ghs3dNodeIt = theRequiredNodes.begin();ghs3dNodeIt != theRequiredNodes.end();++ghs3dNodeIt) {
+      GmfSetLin(idxRequired, GmfVertices, (*ghs3dNodeIt)->X(), (*ghs3dNodeIt)->Y(), (*ghs3dNodeIt)->Z(), dummyint);
+      GmfSetLin(idxSol, GmfSolAtVertices, 0.0);
+      aNodeGroupByGhs3dId[usedEnforcedNodes] = theEnforcedNodes.find((*ghs3dNodeIt))->second;
+      usedEnforcedNodes++;
+    }
 
-    // X Y Z DUMMY_INT
-    theFile
-    << space << node->X()
-    << space << node->Y()
-    << space << node->Z()
-    << space << dummyint;
+    for (int i=0;i<solSize;i++) {
+      std::cout << ReqVerTab[i][0] <<" "<< ReqVerTab[i][1] << " "<< ReqVerTab[i][2] << std::endl;
+      std::cout << "enfVertexSizes.at("<<i<<"): " << enfVertexSizes.at(i) << std::endl;
+      double solTab[] = {enfVertexSizes.at(i)};
+      GmfSetLin(idxRequired, GmfVertices, ReqVerTab[i][0], ReqVerTab[i][1], ReqVerTab[i][2], dummyint);
+      GmfSetLin(idxSol, GmfSolAtVertices, solTab);
+      aNodeGroupByGhs3dId[usedEnforcedNodes] = enfVerticesWithGroup.find(ReqVerTab[i])->second;
+      std::cout << "aNodeGroupByGhs3dId["<<usedEnforcedNodes<<"] = \""<<enfVerticesWithGroup.find(ReqVerTab[i])->second<<"\""<<std::endl;
+      usedEnforcedNodes++;
+    }
+    std::cout << "End writting in req and sol file" << std::endl;
+  }
+
+  int nedge[2], ntri[3];
+    
+  // GmfEdges
+  int usedEnforcedEdges = 0;
+  if (theKeptEnforcedEdges.size()) {
+    anEdgeGroupByGhs3dId.resize( theKeptEnforcedEdges.size() );
+//    idxRequired = GmfOpenMesh(theRequiredFileName, GmfWrite, GMFVERSION, GMFDIMENSION);
+//    if (!idxRequired)
+//      return false;
+    GmfSetKwd(idx, GmfEdges, theKeptEnforcedEdges.size());
+//    GmfSetKwd(idxRequired, GmfEdges, theKeptEnforcedEdges.size());
+    for(elemSetIt = theKeptEnforcedEdges.begin() ; elemSetIt != theKeptEnforcedEdges.end() ; ++elemSetIt) {
+      elem = (*elemSetIt);
+      nodeIt = elem->nodesIterator();
+      int index=0;
+      while ( nodeIt->more() ) {
+        // find GHS3D ID
+        const SMDS_MeshNode* node = castToNode( nodeIt->next() );
+        map< const SMDS_MeshNode*,int >::iterator it = anEnforcedNodeToGhs3dIdMap.find(node);
+        if (it == anEnforcedNodeToGhs3dIdMap.end())
+          throw "Node not found";
+        nedge[index] = it->second;
+        index++;
+      }
+      GmfSetLin(idx, GmfEdges, nedge[0], nedge[1], dummyint);
+      anEdgeGroupByGhs3dId[usedEnforcedEdges] = theEnforcedEdges.find(elem)->second;
+//      GmfSetLin(idxRequired, GmfEdges, nedge[0], nedge[1], dummyint);
+      usedEnforcedEdges++;
+    }
+//    GmfCloseMesh(idxRequired);
+  }
 
-    theFile << std::endl;
 
+  if (usedEnforcedEdges) {
+    GmfSetKwd(idx, GmfRequiredEdges, usedEnforcedEdges);
+    for (int enfID=1;enfID<=usedEnforcedEdges;enfID++) {
+      GmfSetLin(idx, GmfRequiredEdges, enfID);
+    }
   }
-  
-  // Iterate over the enforced vertices
-  GHS3DPlugin_Hypothesis::TEnforcedVertexValues::const_iterator vertexIt;
-  const TopoDS_Shape shapeToMesh = theMesh->ShapeToMesh();
-  for(vertexIt = theEnforcedVertices.begin() ; vertexIt != theEnforcedVertices.end() ; ++vertexIt) {
-    double x = vertexIt->first[0];
-    double y = vertexIt->first[1];
-    double z = vertexIt->first[2];
-    // Test if point is inside shape to mesh
-    gp_Pnt myPoint(x,y,z);
-    BRepClass3d_SolidClassifier scl(shapeToMesh);
-    scl.Perform(myPoint, 1e-7);
-    TopAbs_State result = scl.State();
-    if ( result == TopAbs_IN ) {
-        MESSAGE("Adding enforced vertex (" << x << "," << y <<"," << z << ") = " << vertexIt->second);
-        // X Y Z PHY_SIZE DUMMY_INT
-        theFile
-        << space << x
-        << space << y
-        << space << z
-        << space << vertexIt->second
-        << space << dummyint;
-    
-        theFile << std::endl;
+
+  // GmfTriangles
+  int usedEnforcedTriangles = 0;
+  if (anElemSet.size()+theKeptEnforcedTriangles.size()) {
+    aFaceGroupByGhs3dId.resize( anElemSet.size()+theKeptEnforcedTriangles.size() );
+    GmfSetKwd(idx, GmfTriangles, anElemSet.size()+theKeptEnforcedTriangles.size());
+    int k=0;
+    for(elemSetIt = anElemSet.begin() ; elemSetIt != anElemSet.end() ; ++elemSetIt,++k) {
+      elem = (*elemSetIt);
+      nodeIt = elem->nodesIterator();
+      int index=0;
+      for ( int j = 0; j < 3; ++j ) {
+        // find GHS3D ID
+        const SMDS_MeshNode* node = castToNode( nodeIt->next() );
+        map< const SMDS_MeshNode*,int >::iterator it = aNodeToGhs3dIdMap.find(node);
+        if (it == aNodeToGhs3dIdMap.end())
+          throw "Node not found";
+        ntri[index] = it->second;
+        index++;
+      }
+      GmfSetLin(idx, GmfTriangles, ntri[0], ntri[1], ntri[2], dummyint);
+      aFaceGroupByGhs3dId[k] = "";
+    }
+    if (theKeptEnforcedTriangles.size()) {
+      for(elemSetIt = theKeptEnforcedTriangles.begin() ; elemSetIt != theKeptEnforcedTriangles.end() ; ++elemSetIt,++k) {
+        elem = (*elemSetIt);
+        nodeIt = elem->nodesIterator();
+        int index=0;
+        for ( int j = 0; j < 3; ++j ) {
+          // find GHS3D ID
+          const SMDS_MeshNode* node = castToNode( nodeIt->next() );
+          map< const SMDS_MeshNode*,int >::iterator it = anEnforcedNodeToGhs3dIdMap.find(node);
+          if (it == anEnforcedNodeToGhs3dIdMap.end())
+            throw "Node not found";
+          ntri[index] = it->second;
+          index++;
+        }
+        GmfSetLin(idx, GmfTriangles, ntri[0], ntri[1], ntri[2], dummyint);
+        aFaceGroupByGhs3dId[k] = theEnforcedTriangles.find(elem)->second;
+        usedEnforcedTriangles++;
+      }
     }
-    else
-        MESSAGE("Enforced vertex (" << x << "," << y <<"," << z << ") is not inside the geometry: it was not added ");
   }
+
   
-  
-  std::cout << std::endl;
-  std::cout << "End writing in 'points' file." << std::endl;
+  if (usedEnforcedTriangles) {
+    GmfSetKwd(idx, GmfRequiredTriangles, usedEnforcedTriangles);
+    for (int enfID=1;enfID<=usedEnforcedTriangles;enfID++)
+      GmfSetLin(idx, GmfRequiredTriangles, anElemSet.size()+enfID);
+  }
 
+  GmfCloseMesh(idx);
+  if (idxRequired)
+    GmfCloseMesh(idxRequired);
+  if (idxSol)
+    GmfCloseMesh(idxSol);
+  
   return true;
+  
 }
 
-//=======================================================================
-//function : writePoints
-//purpose  : 
-//=======================================================================
+// static bool writeGMFFile(const char*                                    theMeshFileName,
+//                         const char*                                     theRequiredFileName,
+//                         const char*                                     theSolFileName,
+//                         SMESH_MesherHelper&                             theHelper,
+//                         const SMESH_ProxyMesh&                          theProxyMesh,
+//                         std::map <int,int> &                            theNodeId2NodeIndexMap,
+//                         std::map <int,int> &                            theSmdsToGhs3dIdMap,
+//                         std::map <int,const SMDS_MeshNode*> &           theGhs3dIdToNodeMap,
+//                         TIDSortedNodeSet &                              theEnforcedNodes,
+//                         TIDSortedElemSet &                              theEnforcedEdges,
+//                         TIDSortedElemSet &                              theEnforcedTriangles,
+// //                         TIDSortedElemSet &                              theEnforcedQuadrangles,
+//                         GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexCoordsValues & theEnforcedVertices)
+// {
+//   MESSAGE("writeGMFFile with geometry");
+//   int idx, idxRequired, idxSol;
+//   int nbv, nbev, nben, aGhs3dID = 0;
+//   const int dummyint = 0;
+//   GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexCoordsValues::const_iterator vertexIt;
+//   std::vector<double> enfVertexSizes;
+//   TIDSortedNodeSet::const_iterator enfNodeIt;
+//   const SMDS_MeshNode* node;
+//   SMDS_NodeIteratorPtr nodeIt;
+// 
+//   idx = GmfOpenMesh(theMeshFileName, GmfWrite, GMFVERSION, GMFDIMENSION);
+//   if (!idx)
+//     return false;
+//   
+//   SMESHDS_Mesh * theMeshDS = theHelper.GetMeshDS();
+//   
+//   /* ========================== NODES ========================== */
+//   // NB_NODES
+//   nbv = theMeshDS->NbNodes();
+//   if ( nbv == 0 )
+//     return false;
+//   nbev = theEnforcedVertices.size();
+//   nben = theEnforcedNodes.size();
+//   
+//   // Issue 020674: EDF 870 SMESH: Mesh generated by Netgen not usable by GHS3D
+//   // The problem is in nodes on degenerated edges, we need to skip nodes which are free
+//   // and replace not-free nodes on edges by the node on vertex
+//   TNodeNodeMap n2nDegen; // map a node on degenerated edge to a node on vertex
+//   TNodeNodeMap::iterator n2nDegenIt;
+//   if ( theHelper.HasDegeneratedEdges() )
+//   {
+//     set<int> checkedSM;
+//     for (TopExp_Explorer e(theMeshDS->ShapeToMesh(), TopAbs_EDGE ); e.More(); e.Next())
+//     {
+//       SMESH_subMesh* sm = theHelper.GetMesh()->GetSubMesh( e.Current() );
+//       if ( checkedSM.insert( sm->GetId() ).second && theHelper.IsDegenShape(sm->GetId() ))
+//       {
+//         if ( SMESHDS_SubMesh* smDS = sm->GetSubMeshDS() )
+//         {
+//           TopoDS_Shape vertex = TopoDS_Iterator( e.Current() ).Value();
+//           const SMDS_MeshNode* vNode = SMESH_Algo::VertexNode( TopoDS::Vertex( vertex ), theMeshDS);
+//           {
+//             SMDS_NodeIteratorPtr nIt = smDS->GetNodes();
+//             while ( nIt->more() )
+//               n2nDegen.insert( make_pair( nIt->next(), vNode ));
+//           }
+//         }
+//       }
+//     }
+//   }
+//   
+//   const bool isQuadMesh = 
+//     theHelper.GetMesh()->NbEdges( ORDER_QUADRATIC ) ||
+//     theHelper.GetMesh()->NbFaces( ORDER_QUADRATIC ) ||
+//     theHelper.GetMesh()->NbVolumes( ORDER_QUADRATIC );
+// 
+//   std::vector<std::vector<double> > VerTab;
+//   std::set<std::vector<double> > VerMap;
+//   VerTab.clear();
+//   std::vector<double> aVerTab;
+//   // Loop from 1 to NB_NODES
+// 
+//   nodeIt = theMeshDS->nodesIterator();
+//   
+//   while ( nodeIt->more() )
+//   {
+//     node = nodeIt->next();
+//     if ( isQuadMesh && theHelper.IsMedium( node )) // Issue 0021238
+//       continue;
+//     if ( n2nDegen.count( node ) ) // Issue 0020674
+//       continue;
+// 
+//     std::vector<double> coords;
+//     coords.push_back(node->X());
+//     coords.push_back(node->Y());
+//     coords.push_back(node->Z());
+//     if (VerMap.find(coords) != VerMap.end()) {
+//       aGhs3dID = theSmdsToGhs3dIdMap[node->GetID()];
+//       theGhs3dIdToNodeMap[theSmdsToGhs3dIdMap[node->GetID()]] = node;
+//       continue;
+//     }
+//     VerTab.push_back(coords);
+//     VerMap.insert(coords);
+//     aGhs3dID++;
+//     theSmdsToGhs3dIdMap.insert( make_pair( node->GetID(), aGhs3dID ));
+//     theGhs3dIdToNodeMap.insert( make_pair( aGhs3dID, node ));
+//   }
+//   
+//   
+//   /* ENFORCED NODES ========================== */
+//   if (nben) {
+//     std::cout << "Add " << nben << " enforced nodes to input .mesh file" << std::endl;
+//     for(enfNodeIt = theEnforcedNodes.begin() ; enfNodeIt != theEnforcedNodes.end() ; ++enfNodeIt) {
+//       double x = (*enfNodeIt)->X();
+//       double y = (*enfNodeIt)->Y();
+//       double z = (*enfNodeIt)->Z();
+//       // Test if point is inside shape to mesh
+//       gp_Pnt myPoint(x,y,z);
+//       BRepClass3d_SolidClassifier scl(theMeshDS->ShapeToMesh());
+//       scl.Perform(myPoint, 1e-7);
+//       TopAbs_State result = scl.State();
+//       if ( result != TopAbs_IN )
+//         continue;
+//       std::vector<double> coords;
+//       coords.push_back(x);
+//       coords.push_back(y);
+//       coords.push_back(z);
+//       if (theEnforcedVertices.find(coords) != theEnforcedVertices.end())
+//         continue;
+//       if (VerMap.find(coords) != VerMap.end())
+//         continue;
+//       VerTab.push_back(coords);
+//       VerMap.insert(coords);
+//       aGhs3dID++;
+//       theNodeId2NodeIndexMap.insert( make_pair( (*enfNodeIt)->GetID(), aGhs3dID ));
+//     }
+//   }
+//     
+//   
+//   /* ENFORCED VERTICES ========================== */
+//   int solSize = 0;
+//   std::vector<std::vector<double> > ReqVerTab;
+//   ReqVerTab.clear();
+//   if (nbev) {
+//     std::cout << "Add " << nbev << " enforced vertices to input .mesh file" << std::endl;
+//     for(vertexIt = theEnforcedVertices.begin() ; vertexIt != theEnforcedVertices.end() ; ++vertexIt) {
+//       double x = vertexIt->first[0];
+//       double y = vertexIt->first[1];
+//       double z = vertexIt->first[2];
+//       // Test if point is inside shape to mesh
+//       gp_Pnt myPoint(x,y,z);
+//       BRepClass3d_SolidClassifier scl(theMeshDS->ShapeToMesh());
+//       scl.Perform(myPoint, 1e-7);
+//       TopAbs_State result = scl.State();
+//       if ( result != TopAbs_IN )
+//         continue;
+//       enfVertexSizes.push_back(vertexIt->second);
+//       std::vector<double> coords;
+//       coords.push_back(x);
+//       coords.push_back(y);
+//       coords.push_back(z);
+//       if (VerMap.find(coords) != VerMap.end())
+//         continue;
+//       ReqVerTab.push_back(coords);
+//       VerMap.insert(coords);
+//       solSize++;
+//     }
+//   }
+// 
+//   
+//   /* ========================== FACES ========================== */
+//   
+//   int nbTriangles = 0/*, nbQuadrangles = 0*/, aSmdsID;
+//   TopTools_IndexedMapOfShape facesMap, trianglesMap/*, quadranglesMap*/;
+//   TIDSortedElemSet::const_iterator elemIt;
+//   const SMESHDS_SubMesh* theSubMesh;
+//   TopoDS_Shape aShape;
+//   SMDS_ElemIteratorPtr itOnSubMesh, itOnSubFace;
+//   const SMDS_MeshElement* aFace;
+//   map<int,int>::const_iterator itOnMap;
+//   std::vector<std::vector<int> > tt, qt,et;
+//   tt.clear();
+//   qt.clear();
+//   et.clear();
+//   std::vector<int> att, aqt, aet;
+//   
+//   TopExp::MapShapes( theMeshDS->ShapeToMesh(), TopAbs_FACE, facesMap );
+// 
+//   for ( int i = 1; i <= facesMap.Extent(); ++i )
+//     if (( theSubMesh  = theProxyMesh.GetSubMesh( facesMap(i))))
+//     {
+//       SMDS_ElemIteratorPtr it = theSubMesh->GetElements();
+//       while (it->more())
+//       {
+//         const SMDS_MeshElement *elem = it->next();
+//         int nbCornerNodes = elem->NbCornerNodes();
+//         if (nbCornerNodes == 3)
+//         {
+//           trianglesMap.Add(facesMap(i));
+//           nbTriangles ++;
+//         }
+// //         else if (nbCornerNodes == 4)
+// //         {
+// //           quadranglesMap.Add(facesMap(i));
+// //           nbQuadrangles ++;
+// //         }
+//       }
+//     }
+//     
+//   /* TRIANGLES ========================== */
+//   if (nbTriangles) {
+//     for ( int i = 1; i <= trianglesMap.Extent(); i++ )
+//     {
+//       aShape = trianglesMap(i);
+//       theSubMesh = theProxyMesh.GetSubMesh(aShape);
+//       if ( !theSubMesh ) continue;
+//       itOnSubMesh = theSubMesh->GetElements();
+//       while ( itOnSubMesh->more() )
+//       {
+//         aFace = itOnSubMesh->next();
+//         itOnSubFace = aFace->nodesIterator();
+//         att.clear();
+//         for ( int j = 0; j < 3; ++j ) {
+//           // find GHS3D ID
+//           node = castToNode( itOnSubFace->next() );
+//           if (( n2nDegenIt = n2nDegen.find( node )) != n2nDegen.end() )
+//             node = n2nDegenIt->second;
+//           aSmdsID = node->GetID();
+//           itOnMap = theSmdsToGhs3dIdMap.find( aSmdsID );
+//           ASSERT( itOnMap != theSmdsToGhs3dIdMap.end() );
+//           att.push_back((*itOnMap).second);
+//         }
+//         tt.push_back(att);
+//       }
+//     }
+//   }
+// 
+//   if (theEnforcedTriangles.size()) {
+//     std::cout << "Add " << theEnforcedTriangles.size() << " enforced triangles to input .mesh file" << std::endl;
+//     // Iterate over the enforced triangles
+//     for(elemIt = theEnforcedTriangles.begin() ; elemIt != theEnforcedTriangles.end() ; ++elemIt) {
+//       aFace = (*elemIt);
+//       itOnSubFace = aFace->nodesIterator();
+//       bool isOK = true;
+//       att.clear();
+//       
+//       for ( int j = 0; j < 3; ++j ) {
+//         node = castToNode( itOnSubFace->next() );
+//         if (( n2nDegenIt = n2nDegen.find( node )) != n2nDegen.end() )
+//           node = n2nDegenIt->second;
+// //         std::cout << node;
+//         double x = node->X();
+//         double y = node->Y();
+//         double z = node->Z();
+//         // Test if point is inside shape to mesh
+//         gp_Pnt myPoint(x,y,z);
+//         BRepClass3d_SolidClassifier scl(theMeshDS->ShapeToMesh());
+//         scl.Perform(myPoint, 1e-7);
+//         TopAbs_State result = scl.State();
+//         if ( result != TopAbs_IN ) {
+//           isOK = false;
+//           theEnforcedTriangles.erase(elemIt);
+//           continue;
+//         }
+//         std::vector<double> coords;
+//         coords.push_back(x);
+//         coords.push_back(y);
+//         coords.push_back(z);
+//         if (VerMap.find(coords) != VerMap.end()) {
+//           att.push_back(theNodeId2NodeIndexMap[node->GetID()]);
+//           continue;
+//         }
+//         VerTab.push_back(coords);
+//         VerMap.insert(coords);
+//         aGhs3dID++;
+//         theNodeId2NodeIndexMap.insert( make_pair( node->GetID(), aGhs3dID ));
+//         att.push_back(aGhs3dID);
+//       }
+//       if (isOK)
+//         tt.push_back(att);
+//     }
+//   }
+// 
+// 
+//   /* ========================== EDGES ========================== */
+// 
+//   if (theEnforcedEdges.size()) {
+//     // Iterate over the enforced edges
+//     std::cout << "Add " << theEnforcedEdges.size() << " enforced edges to input .mesh file" << std::endl;
+//     for(elemIt = theEnforcedEdges.begin() ; elemIt != theEnforcedEdges.end() ; ++elemIt) {
+//       aFace = (*elemIt);
+//       bool isOK = true;
+//       itOnSubFace = aFace->nodesIterator();
+//       aet.clear();
+//       for ( int j = 0; j < 2; ++j ) {
+//         node = castToNode( itOnSubFace->next() );
+//         if (( n2nDegenIt = n2nDegen.find( node )) != n2nDegen.end() )
+//           node = n2nDegenIt->second;
+//         double x = node->X();
+//         double y = node->Y();
+//         double z = node->Z();
+//         // Test if point is inside shape to mesh
+//         gp_Pnt myPoint(x,y,z);
+//         BRepClass3d_SolidClassifier scl(theMeshDS->ShapeToMesh());
+//         scl.Perform(myPoint, 1e-7);
+//         TopAbs_State result = scl.State();
+//         if ( result != TopAbs_IN ) {
+//           isOK = false;
+//           theEnforcedEdges.erase(elemIt);
+//           continue;
+//         }
+//         std::vector<double> coords;
+//         coords.push_back(x);
+//         coords.push_back(y);
+//         coords.push_back(z);
+//         if (VerMap.find(coords) != VerMap.end()) {
+//           aet.push_back(theNodeId2NodeIndexMap[node->GetID()]);
+//           continue;
+//         }
+//         VerTab.push_back(coords);
+//         VerMap.insert(coords);
+//         
+//         aGhs3dID++;
+//         theNodeId2NodeIndexMap.insert( make_pair( node->GetID(), aGhs3dID ));
+//         aet.push_back(aGhs3dID);
+//       }
+//       if (isOK)
+//         et.push_back(aet);
+//     }
+//   }
+// 
+// 
+//   /* Write vertices number */
+//   MESSAGE("Number of vertices: "<<aGhs3dID);
+//   MESSAGE("Size of vector: "<<VerTab.size());
+//   GmfSetKwd(idx, GmfVertices, aGhs3dID/*+solSize*/);
+//   for (int i=0;i<aGhs3dID;i++)
+//     GmfSetLin(idx, GmfVertices, VerTab[i][0], VerTab[i][1], VerTab[i][2], dummyint);
+// //   for (int i=0;i<solSize;i++) {
+// //     std::cout << ReqVerTab[i][0] <<" "<< ReqVerTab[i][1] << " "<< ReqVerTab[i][2] << std::endl;
+// //     GmfSetLin(idx, GmfVertices, ReqVerTab[i][0], ReqVerTab[i][1], ReqVerTab[i][2], dummyint);
+// //   }
+// 
+//   if (solSize) {
+//     idxRequired = GmfOpenMesh(theRequiredFileName, GmfWrite, GMFVERSION, GMFDIMENSION);
+//     if (!idxRequired) {
+//       GmfCloseMesh(idx);
+//       return false;
+//     }
+//     idxSol = GmfOpenMesh(theSolFileName, GmfWrite, GMFVERSION, GMFDIMENSION);
+//     if (!idxSol){
+//       GmfCloseMesh(idx);
+//       if (idxRequired)
+//         GmfCloseMesh(idxRequired);
+//       return false;
+//     }
+//     
+//     int TypTab[] = {GmfSca};
+//     GmfSetKwd(idxRequired, GmfVertices, solSize);
+//     GmfSetKwd(idxSol, GmfSolAtVertices, solSize, 1, TypTab);
+//     
+//     for (int i=0;i<solSize;i++) {
+//       double solTab[] = {enfVertexSizes.at(i)};
+//       GmfSetLin(idxRequired, GmfVertices, ReqVerTab[i][0], ReqVerTab[i][1], ReqVerTab[i][2], dummyint);
+//       GmfSetLin(idxSol, GmfSolAtVertices, solTab);
+//     }
+//     GmfCloseMesh(idxRequired);
+//     GmfCloseMesh(idxSol);
+//   }
+//   
+//   /* Write triangles number */
+//   if (tt.size()) {
+//     GmfSetKwd(idx, GmfTriangles, tt.size());
+//     for (int i=0;i<tt.size();i++)
+//       GmfSetLin(idx, GmfTriangles, tt[i][0], tt[i][1], tt[i][2], dummyint);
+//   }  
+//   
+//   /* Write edges number */
+//   if (et.size()) {
+//     GmfSetKwd(idx, GmfEdges, et.size());
+//     for (int i=0;i<et.size();i++)
+//       GmfSetLin(idx, GmfEdges, et[i][0], et[i][1], dummyint);
+//   }
+// 
+//   /* QUADRANGLES ========================== */
+//   // TODO: add pyramids ?
+// //   if (nbQuadrangles) {
+// //     for ( int i = 1; i <= quadranglesMap.Extent(); i++ )
+// //     {
+// //       aShape = quadranglesMap(i);
+// //       theSubMesh = theProxyMesh.GetSubMesh(aShape);
+// //       if ( !theSubMesh ) continue;
+// //       itOnSubMesh = theSubMesh->GetElements();
+// //       for ( int j = 0; j < 4; ++j )
+// //       {
+// //         aFace = itOnSubMesh->next();
+// //         itOnSubFace = aFace->nodesIterator();
+// //         aqt.clear();
+// //         while ( itOnSubFace->more() ) {
+// //           // find GHS3D ID
+// //           aSmdsID = itOnSubFace->next()->GetID();
+// //           itOnMap = theSmdsToGhs3dIdMap.find( aSmdsID );
+// //           ASSERT( itOnMap != theSmdsToGhs3dIdMap.end() );
+// //           aqt.push_back((*itOnMap).second);
+// //         }
+// //         qt.push_back(aqt);
+// //       }
+// //     }
+// //   }
+// // 
+// //   if (theEnforcedQuadrangles.size()) {
+// //     // Iterate over the enforced triangles
+// //     for(elemIt = theEnforcedQuadrangles.begin() ; elemIt != theEnforcedQuadrangles.end() ; ++elemIt) {
+// //       aFace = (*elemIt);
+// //       bool isOK = true;
+// //       itOnSubFace = aFace->nodesIterator();
+// //       aqt.clear();
+// //       for ( int j = 0; j < 4; ++j ) {
+// //         int aNodeID = itOnSubFace->next()->GetID();
+// //         itOnMap = theNodeId2NodeIndexMap.find(aNodeID);
+// //         if (itOnMap != theNodeId2NodeIndexMap.end())
+// //           aqt.push_back((*itOnMap).second);
+// //         else {
+// //           isOK = false;
+// //           theEnforcedQuadrangles.erase(elemIt);
+// //           break;
+// //         }
+// //       }
+// //       if (isOK)
+// //         qt.push_back(aqt);
+// //     }
+// //   }
+// //  
+//   
+// //   /* Write quadrilaterals number */
+// //   if (qt.size()) {
+// //     GmfSetKwd(idx, GmfQuadrilaterals, qt.size());
+// //     for (int i=0;i<qt.size();i++)
+// //       GmfSetLin(idx, GmfQuadrilaterals, qt[i][0], qt[i][1], qt[i][2], qt[i][3], dummyint);
+// //   }
+// 
+//   GmfCloseMesh(idx);
+//   return true;
+// }
+
+
+//=======================================================================
+//function : writeFaces
+//purpose  : 
+//=======================================================================
 
-static bool writePoints (ofstream &                            theFile,
-                         SMESH_Mesh *                          theMesh,
-                         const vector <const SMDS_MeshNode*> & theNodeByGhs3dId,
-                         map<vector<double>,double> &          theEnforcedVertices)
+static bool writeFaces (ofstream &              theFile,
+                        const SMESH_ProxyMesh&  theMesh,
+                        const TopoDS_Shape&     theShape,
+                        const map <int,int> &   theSmdsToGhs3dIdMap,
+                        const map <int,int> &   theEnforcedNodeIdToGhs3dIdMap,
+                        GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap & theEnforcedEdges,
+                        GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap & theEnforcedTriangles)
 {
   // record structure:
   //
-  // NB_NODES
-  // Loop from 1 to NB_NODES
-  //   X Y Z DUMMY_INT
-  
-  int nbNodes = theNodeByGhs3dId.size();
-  if ( nbNodes == 0 )
-    return false;
-
-  int nbEnforcedVertices = theEnforcedVertices.size();
+  // NB_ELEMS DUMMY_INT
+  // Loop from 1 to NB_ELEMS
+  // NB_NODES NODE_NB_1 NODE_NB_2 ... (NB_NODES + 1) times: DUMMY_INT
 
+  TopoDS_Shape aShape;
+  const SMESHDS_SubMesh* theSubMesh;
+  const SMDS_MeshElement* aFace;
   const char* space    = "  ";
   const int   dummyint = 0;
+  map<int,int>::const_iterator itOnMap;
+  SMDS_ElemIteratorPtr itOnSubMesh, itOnSubFace;
+  int nbNodes, aSmdsID;
 
-  const SMDS_MeshNode* node;
-
-  // NB_NODES
-  std::cout << std::endl;
-  std::cout << "The initial 2D mesh contains :" << std::endl;
-  std::cout << "    " << nbNodes << " nodes" << std::endl;
-  std::cout << "    " << nbEnforcedVertices << " enforced vertices" << std::endl;
-  std::cout << std::endl;
-  std::cout << "Start writing in 'points' file ..." << std::endl;
-  theFile << space << nbNodes << std::endl;
-
-  // Loop from 1 to NB_NODES
+  TIDSortedElemSet::const_iterator elemIt;
+  int nbEnforcedEdges       = theEnforcedEdges.size();
+  int nbEnforcedTriangles   = theEnforcedTriangles.size();
 
-  vector<const SMDS_MeshNode*>::const_iterator nodeIt = theNodeByGhs3dId.begin();
-  vector<const SMDS_MeshNode*>::const_iterator after  = theNodeByGhs3dId.end();
-  for ( ; nodeIt != after; ++nodeIt )
-  {
-    node = *nodeIt;
+  // count triangles bound to geometry
+  int nbTriangles = 0;
 
-    // X Y Z DUMMY_INT
-    theFile
-    << space << node->X()
-    << space << node->Y()
-    << space << node->Z()
-    << space << dummyint;
+  TopTools_IndexedMapOfShape facesMap, trianglesMap;
+  TopExp::MapShapes( theShape, TopAbs_FACE, facesMap );
 
-    theFile << std::endl;
+  for ( int i = 1; i <= facesMap.Extent(); ++i )
+    if (( theSubMesh  = theMesh.GetSubMesh( facesMap(i))))
+      nbTriangles += theSubMesh->NbElements();
 
-  }
-  
-  // Iterate over the enforced vertices
-  GHS3DPlugin_Hypothesis::TEnforcedVertexValues::const_iterator vertexIt;
-  auto_ptr< SMESH_ElementSearcher > pntCls ( SMESH_MeshEditor( theMesh ).GetElementSearcher());
-  for(vertexIt = theEnforcedVertices.begin() ; vertexIt != theEnforcedVertices.end() ; ++vertexIt) {
-    double x = vertexIt->first[0];
-    double y = vertexIt->first[1];
-    double z = vertexIt->first[2];
-    // Test if point is inside shape to mesh
-    gp_Pnt myPoint(x,y,z);
-    TopAbs_State result = pntCls->GetPointState( myPoint );
-    if ( result == TopAbs_IN ) {
-        std::cout << "Adding enforced vertex (" << x << "," << y <<"," << z << ") = " << vertexIt->second << std::endl;
-
-        // X Y Z PHY_SIZE DUMMY_INT
-        theFile
-        << space << x
-        << space << y
-        << space << z
-        << space << vertexIt->second
-        << space << dummyint;
-    
-        theFile << std::endl;
-    }
-  }
+  std::cout << "    " << facesMap.Extent() << " shapes of 2D dimension and" << std::endl;
+  if (nbEnforcedEdges+nbEnforcedTriangles)
+    std::cout << "    " << nbEnforcedEdges+nbEnforcedTriangles 
+                        << " enforced shapes:" << std::endl;
+  if (nbEnforcedEdges)
+    std::cout << "      " << nbEnforcedEdges << " enforced edges" << std::endl;
+  if (nbEnforcedTriangles)
+    std::cout << "      " << nbEnforcedTriangles << " enforced triangles" << std::endl;
   std::cout << std::endl;
-  std::cout << "End writing in 'points' file." << std::endl;
 
-  return true;
-}
-
-//================================================================================
-/*!
- * \brief returns true if a triangle defined by the nodes is a temporary face on a
- * side facet of pyramid and defines sub-domian inside the pyramid
- */
-//================================================================================
+//   theFile << space << nbTriangles << space << dummyint << std::endl;
+  std::ostringstream globalStream, localStream, aStream;
 
-static bool isTmpFace(const SMDS_MeshNode* node1,
-                      const SMDS_MeshNode* node2,
-                      const SMDS_MeshNode* node3)
-{
-  // find a pyramid sharing the 3 nodes
-  //const SMDS_MeshElement* pyram = 0;
-  SMDS_ElemIteratorPtr vIt1 = node1->GetInverseElementIterator(SMDSAbs_Volume);
-  while ( vIt1->more() )
+  for ( int i = 1; i <= facesMap.Extent(); i++ )
   {
-    const SMDS_MeshElement* pyram = vIt1->next();
-    if ( pyram->NbCornerNodes() != 5 ) continue;
-    int i2, i3;
-    if ( (i2 = pyram->GetNodeIndex( node2 )) >= 0 &&
-         (i3 = pyram->GetNodeIndex( node3 )) >= 0 )
+    aShape = facesMap(i);
+    theSubMesh = theMesh.GetSubMesh(aShape);
+    if ( !theSubMesh ) continue;
+    itOnSubMesh = theSubMesh->GetElements();
+    while ( itOnSubMesh->more() )
     {
-      // Triangle defines sub-domian inside the pyramid if it's
-      // normal points out of the pyram
+      aFace = itOnSubMesh->next();
+      nbNodes = aFace->NbCornerNodes();
 
-      // make i2 and i3 hold indices of base nodes of the pyram while
-      // keeping the nodes order in the triangle
-      const int iApex = 4;
-      if ( i2 == iApex )
-        i2 = i3, i3 = pyram->GetNodeIndex( node1 );
-      else if ( i3 == iApex )
-        i3 = i2, i2 = pyram->GetNodeIndex( node1 );
+      localStream << nbNodes << space;
 
-      int i3base = (i2+1) % 4; // next index after i2 within the pyramid base
-      return ( i3base != i3 );
+      itOnSubFace = aFace->nodesIterator();
+      for ( int j = 0; j < 3; ++j ) {
+        // find GHS3D ID
+        aSmdsID = itOnSubFace->next()->GetID();
+        itOnMap = theSmdsToGhs3dIdMap.find( aSmdsID );
+        // if ( itOnMap == theSmdsToGhs3dIdMap.end() ) {
+        //   cout << "not found node: " << aSmdsID << endl;
+        //   return false;
+        // }
+        ASSERT( itOnMap != theSmdsToGhs3dIdMap.end() );
+
+        localStream << (*itOnMap).second << space ;
+      }
+
+      // (NB_NODES + 1) times: DUMMY_INT
+      for ( int j=0; j<=nbNodes; j++)
+        localStream << dummyint << space ;
+
+      localStream << std::endl;
     }
   }
-  return false;
+  
+  globalStream << localStream.str();
+  localStream.str("");
+
+  //
+  //        FACES : END
+  //
+
+//   //
+//   //        ENFORCED EDGES : BEGIN
+//   //
+//   
+//   // Iterate over the enforced edges
+//   int usedEnforcedEdges = 0;
+//   bool isOK;
+//   for(elemIt = theEnforcedEdges.begin() ; elemIt != theEnforcedEdges.end() ; ++elemIt) {
+//     aFace = (*elemIt);
+//     isOK = true;
+//     itOnSubFace = aFace->nodesIterator();
+//     aStream.str("");
+//     aStream << "2" << space ;
+//     for ( int j = 0; j < 2; ++j ) {
+//       aSmdsID = itOnSubFace->next()->GetID();
+//       itOnMap = theEnforcedNodeIdToGhs3dIdMap.find(aSmdsID);
+//       if (itOnMap != theEnforcedNodeIdToGhs3dIdMap.end())
+//         aStream << (*itOnMap).second << space;
+//       else {
+//         isOK = false;
+//         break;
+//       }
+//     }
+//     if (isOK) {
+//       for ( int j=0; j<=2; j++)
+//         aStream << dummyint << space ;
+// //       aStream << dummyint << space << dummyint;
+//       localStream << aStream.str() << std::endl;
+//       usedEnforcedEdges++;
+//     }
+//   }
+//   
+//   if (usedEnforcedEdges) {
+//     globalStream << localStream.str();
+//     localStream.str("");
+//   }
+// 
+//   //
+//   //        ENFORCED EDGES : END
+//   //
+//   //
+// 
+//   //
+//   //        ENFORCED TRIANGLES : BEGIN
+//   //
+//     // Iterate over the enforced triangles
+//   int usedEnforcedTriangles = 0;
+//   for(elemIt = theEnforcedTriangles.begin() ; elemIt != theEnforcedTriangles.end() ; ++elemIt) {
+//     aFace = (*elemIt);
+//     nbNodes = aFace->NbCornerNodes();
+//     isOK = true;
+//     itOnSubFace = aFace->nodesIterator();
+//     aStream.str("");
+//     aStream << nbNodes << space ;
+//     for ( int j = 0; j < 3; ++j ) {
+//       aSmdsID = itOnSubFace->next()->GetID();
+//       itOnMap = theEnforcedNodeIdToGhs3dIdMap.find(aSmdsID);
+//       if (itOnMap != theEnforcedNodeIdToGhs3dIdMap.end())
+//         aStream << (*itOnMap).second << space;
+//       else {
+//         isOK = false;
+//         break;
+//       }
+//     }
+//     if (isOK) {
+//       for ( int j=0; j<=3; j++)
+//         aStream << dummyint << space ;
+//       localStream << aStream.str() << std::endl;
+//       usedEnforcedTriangles++;
+//     }
+//   }
+//   
+//   if (usedEnforcedTriangles) {
+//     globalStream << localStream.str();
+//     localStream.str("");
+//   }
+// 
+//   //
+//   //        ENFORCED TRIANGLES : END
+//   //
+  
+  theFile
+  << nbTriangles/*+usedEnforcedTriangles+usedEnforcedEdges*/
+  << " 0" << std::endl
+  << globalStream.str();
+
+  return true;
 }
 
 //=======================================================================
-//function : findShapeID
-//purpose  : find the solid corresponding to GHS3D sub-domain following
-//           the technique proposed in GHS3D manual (available within
-//           ghs3d installation) in chapter "B.4 Subdomain (sub-region) assignment".
-//           In brief: normal of the triangle defined by the given nodes
-//           points out of the domain it is associated to
+//function : writePoints
+//purpose  : 
 //=======================================================================
 
-static int findShapeID(SMESH_Mesh&          mesh,
-                       const SMDS_MeshNode* node1,
-                       const SMDS_MeshNode* node2,
-                       const SMDS_MeshNode* node3,
-                       const bool           toMeshHoles)
+static bool writePoints (ofstream &                       theFile,
+                         SMESH_MesherHelper&              theHelper,
+                         map <int,int> &                  theSmdsToGhs3dIdMap,
+                         map <int,int> &                  theEnforcedNodeIdToGhs3dIdMap,
+                         map <int,const SMDS_MeshNode*> & theGhs3dIdToNodeMap,
+                         GHS3DPlugin_Hypothesis::TID2SizeMap & theNodeIDToSizeMap,
+                         GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexCoordsValues & theEnforcedVertices,
+                         GHS3DPlugin_Hypothesis::TIDSortedNodeGroupMap & theEnforcedNodes,
+                         GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap & theEnforcedEdges,
+                         GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap & theEnforcedTriangles)
 {
-  const int invalidID = 0;
-  SMESHDS_Mesh* meshDS = mesh.GetMeshDS();
-
-  // face the nodes belong to
-  const SMDS_MeshElement * face = meshDS->FindFace(node1,node2,node3);
-  if ( !face )
-    return isTmpFace(node1, node2, node3) ? HOLE_ID : invalidID;
-#ifdef _DEBUG_
-  std::cout << "bnd face " << face->GetID() << " - ";
-#endif
-  // geom face the face assigned to
-  SMESH_MeshEditor editor(&mesh);
-  int geomFaceID = editor.FindShape( face );
-  if ( !geomFaceID )
-    return isTmpFace(node1, node2, node3) ? HOLE_ID : invalidID;
-  TopoDS_Shape shape = meshDS->IndexToShape( geomFaceID );
-  if ( shape.IsNull() || shape.ShapeType() != TopAbs_FACE )
-    return invalidID;
-  TopoDS_Face geomFace = TopoDS::Face( shape );
+  // record structure:
+  //
+  // NB_NODES
+  // Loop from 1 to NB_NODES
+  //   X Y Z DUMMY_INT
 
-  // solids bounded by geom face
-  TopTools_IndexedMapOfShape solids, shells;
-  TopTools_ListIteratorOfListOfShape ansIt = mesh.GetAncestors(geomFace);
-  for ( ; ansIt.More(); ansIt.Next() ) {
-    switch ( ansIt.Value().ShapeType() ) {
-    case TopAbs_SOLID:
-      solids.Add( ansIt.Value() ); break;
-    case TopAbs_SHELL:
-      shells.Add( ansIt.Value() ); break;
-    default:;
-    }
-  }
-  // analyse found solids
-  if ( solids.Extent() == 0 || shells.Extent() == 0)
-    return invalidID;
+  SMESHDS_Mesh * theMeshDS = theHelper.GetMeshDS();
+  int nbNodes = theMeshDS->NbNodes();
+  if ( nbNodes == 0 )
+    return false;
+  
+  int nbEnforcedVertices = theEnforcedVertices.size();
+  int nbEnforcedNodes    = theEnforcedNodes.size();
+  
+  const TopoDS_Shape shapeToMesh = theMeshDS->ShapeToMesh();
+  
+  int aGhs3dID = 1;
+  SMDS_NodeIteratorPtr nodeIt = theMeshDS->nodesIterator();
+  const SMDS_MeshNode* node;
 
-  const TopoDS_Solid& solid1 = TopoDS::Solid( solids(1) );
-  if ( solids.Extent() == 1 )
+  // Issue 020674: EDF 870 SMESH: Mesh generated by Netgen not usable by GHS3D
+  // The problem is in nodes on degenerated edges, we need to skip nodes which are free
+  // and replace not-free nodes on degenerated edges by the node on vertex
+  TNodeNodeMap n2nDegen; // map a node on degenerated edge to a node on vertex
+  TNodeNodeMap::iterator n2nDegenIt;
+  if ( theHelper.HasDegeneratedEdges() )
   {
-    if ( toMeshHoles )
-      return meshDS->ShapeToIndex( solid1 );
-
-    // - Are we at a hole boundary face?
-    if ( shells(1).IsSame( BRepTools::OuterShell( solid1 )) )
-    { // - No, but maybe a hole is bound by two shapes? Does shells(1) touches another shell?
-      bool touch = false;
-      TopExp_Explorer eExp( shells(1), TopAbs_EDGE );
-      // check if any edge of shells(1) belongs to another shell
-      for ( ; eExp.More() && !touch; eExp.Next() ) {
-        ansIt = mesh.GetAncestors( eExp.Current() );
-        for ( ; ansIt.More() && !touch; ansIt.Next() ) {
-          if ( ansIt.Value().ShapeType() == TopAbs_SHELL )
-            touch = ( !ansIt.Value().IsSame( shells(1) ));
+    set<int> checkedSM;
+    for (TopExp_Explorer e(theMeshDS->ShapeToMesh(), TopAbs_EDGE ); e.More(); e.Next())
+    {
+      SMESH_subMesh* sm = theHelper.GetMesh()->GetSubMesh( e.Current() );
+      if ( checkedSM.insert( sm->GetId() ).second && theHelper.IsDegenShape(sm->GetId() ))
+      {
+        if ( SMESHDS_SubMesh* smDS = sm->GetSubMeshDS() )
+        {
+          TopoDS_Shape vertex = TopoDS_Iterator( e.Current() ).Value();
+          const SMDS_MeshNode* vNode = SMESH_Algo::VertexNode( TopoDS::Vertex( vertex ), theMeshDS);
+          {
+            SMDS_NodeIteratorPtr nIt = smDS->GetNodes();
+            while ( nIt->more() )
+              n2nDegen.insert( make_pair( nIt->next(), vNode ));
+          }
         }
       }
-      if (!touch)
-        return meshDS->ShapeToIndex( solid1 );
     }
+    nbNodes -= n2nDegen.size();
   }
-  // find orientation of geom face within the first solid
-  TopExp_Explorer fExp( solid1, TopAbs_FACE );
-  for ( ; fExp.More(); fExp.Next() )
-    if ( geomFace.IsSame( fExp.Current() )) {
-      geomFace = TopoDS::Face( fExp.Current() );
-      break;
-    }
-  if ( !fExp.More() )
-    return invalidID; // face not found
-
-  // normale to triangle
-  gp_Pnt node1Pnt ( node1->X(), node1->Y(), node1->Z() );
-  gp_Pnt node2Pnt ( node2->X(), node2->Y(), node2->Z() );
-  gp_Pnt node3Pnt ( node3->X(), node3->Y(), node3->Z() );
-  gp_Vec vec12( node1Pnt, node2Pnt );
-  gp_Vec vec13( node1Pnt, node3Pnt );
-  gp_Vec meshNormal = vec12 ^ vec13;
-  if ( meshNormal.SquareMagnitude() < DBL_MIN )
-    return invalidID;
 
-  // get normale to geomFace at any node
-  bool geomNormalOK = false;
-  gp_Vec geomNormal;
-  const SMDS_MeshNode* nodes[3] = { node1, node2, node3 };
-  SMESH_MesherHelper helper( mesh ); helper.SetSubShape( geomFace );
-  for ( int i = 0; !geomNormalOK && i < 3; ++i )
+  const bool isQuadMesh = 
+    theHelper.GetMesh()->NbEdges( ORDER_QUADRATIC ) ||
+    theHelper.GetMesh()->NbFaces( ORDER_QUADRATIC ) ||
+    theHelper.GetMesh()->NbVolumes( ORDER_QUADRATIC );
+  if ( isQuadMesh )
   {
-    // find UV of i-th node on geomFace
-    const SMDS_MeshNode* nNotOnSeamEdge = 0;
-    if ( helper.IsSeamShape( nodes[i]->getshapeId() )) {
-      if ( helper.IsSeamShape( nodes[(i+1)%3]->getshapeId() ))
-        nNotOnSeamEdge = nodes[(i+2)%3];
-      else
-        nNotOnSeamEdge = nodes[(i+1)%3];
+    // descrease nbNodes by nb of medium nodes
+    while ( nodeIt->more() )
+    {
+      node = nodeIt->next();
+      if ( !theHelper.IsDegenShape( node->getshapeId() ))
+        nbNodes -= int( theHelper.IsMedium( node ));
     }
-    bool uvOK;
-    gp_XY uv = helper.GetNodeUV( geomFace, nodes[i], nNotOnSeamEdge, &uvOK );
-    // check that uv is correct
-    if (uvOK) {
-      double tol = 1e-6;
-      TopoDS_Shape nodeShape = helper.GetSubShapeByNode( nodes[i], meshDS );
-      if ( !nodeShape.IsNull() )
-        switch ( nodeShape.ShapeType() )
-        {
-        case TopAbs_FACE:   tol = BRep_Tool::Tolerance( TopoDS::Face( nodeShape )); break;
-        case TopAbs_EDGE:   tol = BRep_Tool::Tolerance( TopoDS::Edge( nodeShape )); break;
-        case TopAbs_VERTEX: tol = BRep_Tool::Tolerance( TopoDS::Vertex( nodeShape )); break;
-        default:;
-        }
-      gp_Pnt nodePnt ( nodes[i]->X(), nodes[i]->Y(), nodes[i]->Z() );
-      BRepAdaptor_Surface surface( geomFace );
-      uvOK = ( nodePnt.Distance( surface.Value( uv.X(), uv.Y() )) < 2 * tol );
-      if ( uvOK ) {
-        // normale to geomFace at UV
-        gp_Vec du, dv;
-        surface.D1( uv.X(), uv.Y(), nodePnt, du, dv );
-        geomNormal = du ^ dv;
-        if ( geomFace.Orientation() == TopAbs_REVERSED )
-          geomNormal.Reverse();
-        geomNormalOK = ( geomNormal.SquareMagnitude() > DBL_MIN * 1e3 );
-      }
+    nodeIt = theMeshDS->nodesIterator();
+  }
+
+  const char* space    = "  ";
+  const int   dummyint = 0;
+
+  // NB_NODES
+  std::cout << std::endl;
+  std::cout << "The initial 2D mesh contains :" << std::endl;
+  std::cout << "    " << nbNodes << " nodes" << std::endl;
+  if (nbEnforcedVertices > 0)
+    std::cout << "    " << nbEnforcedVertices << " enforced vertices" << std::endl;
+  if (nbEnforcedNodes > 0)
+    std::cout << "    " << nbEnforcedNodes << " enforced nodes" << std::endl;
+  std::cout << std::endl;
+  std::cout << "Start writing in 'points' file ..." << std::endl;
+
+  theFile << nbNodes << std::endl;
+
+  // Loop from 1 to NB_NODES
+
+  while ( nodeIt->more() )
+  {
+    node = nodeIt->next();
+    if ( isQuadMesh && theHelper.IsMedium( node )) // Issue 0021238
+      continue;
+    if ( n2nDegen.count( node ) ) // Issue 0020674
+      continue;
+
+    theSmdsToGhs3dIdMap.insert( make_pair( node->GetID(), aGhs3dID ));
+    theGhs3dIdToNodeMap.insert( make_pair( aGhs3dID, node ));
+    aGhs3dID++;
+
+    // X Y Z DUMMY_INT
+    theFile
+    << node->X() << space 
+    << node->Y() << space 
+    << node->Z() << space 
+    << dummyint;
+
+    theFile << std::endl;
+
+  }
+  
+  // Iterate over the enforced nodes
+  std::map<int,double> enfVertexIndexSizeMap;
+  if (nbEnforcedNodes) {
+    GHS3DPlugin_Hypothesis::TIDSortedNodeGroupMap::const_iterator nodeIt = theEnforcedNodes.begin();
+    for( ; nodeIt != theEnforcedNodes.end() ; ++nodeIt) {
+      double x = nodeIt->first->X();
+      double y = nodeIt->first->Y();
+      double z = nodeIt->first->Z();
+      // Test if point is inside shape to mesh
+      gp_Pnt myPoint(x,y,z);
+      BRepClass3d_SolidClassifier scl(shapeToMesh);
+      scl.Perform(myPoint, 1e-7);
+      TopAbs_State result = scl.State();
+      if ( result != TopAbs_IN )
+        continue;
+      std::vector<double> coords;
+      coords.push_back(x);
+      coords.push_back(y);
+      coords.push_back(z);
+      if (theEnforcedVertices.find(coords) != theEnforcedVertices.end())
+        continue;
+        
+      double size = theNodeIDToSizeMap.find(nodeIt->first->GetID())->second;
+  //       theGhs3dIdToNodeMap.insert( make_pair( nbNodes + i, (*nodeIt) ));
+  //       MESSAGE("Adding enforced node (" << x << "," << y <<"," << z << ")");
+      // X Y Z PHY_SIZE DUMMY_INT
+      theFile
+      << x << space 
+      << y << space 
+      << z << space
+      << size << space
+      << dummyint << space;
+      theFile << std::endl;
+      theEnforcedNodeIdToGhs3dIdMap.insert( make_pair( nodeIt->first->GetID(), aGhs3dID ));
+      enfVertexIndexSizeMap[aGhs3dID] = -1;
+      aGhs3dID++;
+  //     else
+  //         MESSAGE("Enforced vertex (" << x << "," << y <<"," << z << ") is not inside the geometry: it was not added ");
     }
   }
-  if ( !geomNormalOK)
-    return invalidID;
-
-  // compare normals
-  bool isReverse = ( meshNormal * geomNormal ) < 0;
-  if ( !isReverse )
-    return meshDS->ShapeToIndex( solid1 );
+  
+  if (nbEnforcedVertices) {
+    // Iterate over the enforced vertices
+    GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexCoordsValues::const_iterator vertexIt = theEnforcedVertices.begin();
+    for( ; vertexIt != theEnforcedVertices.end() ; ++vertexIt) {
+      double x = vertexIt->first[0];
+      double y = vertexIt->first[1];
+      double z = vertexIt->first[2];
+      // Test if point is inside shape to mesh
+      gp_Pnt myPoint(x,y,z);
+      BRepClass3d_SolidClassifier scl(shapeToMesh);
+      scl.Perform(myPoint, 1e-7);
+      TopAbs_State result = scl.State();
+      if ( result != TopAbs_IN )
+        continue;
+      MESSAGE("Adding enforced vertex (" << x << "," << y <<"," << z << ") = " << vertexIt->second);
+      // X Y Z PHY_SIZE DUMMY_INT
+      theFile
+      << x << space 
+      << y << space 
+      << z << space
+      << vertexIt->second << space 
+      << dummyint << space;
+      theFile << std::endl;
+      enfVertexIndexSizeMap[aGhs3dID] = vertexIt->second;
+      aGhs3dID++;
+    }
+  }
+  
+  
+  std::cout << std::endl;
+  std::cout << "End writing in 'points' file." << std::endl;
 
-  if ( solids.Extent() == 1 )
-    return HOLE_ID; // we are inside a hole
-  else
-    return meshDS->ShapeToIndex( solids(2) );
+  return true;
 }
 
 //=======================================================================
 //function : readResultFile
-//purpose  : 
+//purpose  : readResultFile with geometry
 //=======================================================================
 
 static bool readResultFile(const int                       fileOpen,
@@ -809,13 +2575,17 @@ static bool readResultFile(const int                       fileOpen,
 #ifdef WITH_SMESH_CANCEL_COMPUTE
                            GHS3DPlugin_GHS3D*              theAlgo,
 #endif
-                           SMESH_Mesh&                     theMesh,
+                           SMESH_MesherHelper&             theHelper,
                            TopoDS_Shape                    tabShape[],
                            double**                        tabBox,
                            const int                       nbShape,
                            map <int,const SMDS_MeshNode*>& theGhs3dIdToNodeMap,
+                           std::map <int,int> &            theNodeId2NodeIndexMap,
                            bool                            toMeshHoles,
-                           int                             nbEnforcedVertices)
+                           int                             nbEnforcedVertices,
+                           int                             nbEnforcedNodes,
+                           GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap & theEnforcedEdges,
+                           GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap & theEnforcedTriangles)
 {
   MESSAGE("GHS3DPlugin_GHS3D::readResultFile()");
   Kernel_Utils::Localizer loc;
@@ -826,11 +2596,9 @@ static bool readResultFile(const int                       fileOpen,
   char *tetraPtr;
   char *shapePtr;
 
-  SMESHDS_Mesh* theMeshDS = theMesh.GetMeshDS();
+  SMESHDS_Mesh* theMeshDS = theHelper.GetMeshDS();
 
-  int fileStat;
   int nbElems, nbNodes, nbInputNodes;
-  int nodeId/*, triangleId*/;
   int nbTriangle;
   int ID, shapeID, ghs3dShapeID;
   int IdShapeRef = 1;
@@ -842,7 +2610,6 @@ static bool readResultFile(const int                       fileOpen,
   const SMDS_MeshNode **node;
 
   tab    = new int[3];
-  //tabID  = new int[nbShape];
   nodeID = new int[4];
   coord  = new double[3];
   node   = new const SMDS_MeshNode*[4];
@@ -856,7 +2623,7 @@ static bool readResultFile(const int                       fileOpen,
 #endif
 
   // Read the file state
-  fileStat = fstat(fileOpen, &status);
+  fstat(fileOpen, &status);
   length   = status.st_size;
 
   // Mapping the result file into memory
@@ -885,10 +2652,11 @@ static bool readResultFile(const int                       fileOpen,
 
   // Reading the nodeId
   for (int i=0; i < 4*nbElems; i++)
-    nodeId = strtol(ptr, &ptr, 10);
+    strtol(ptr, &ptr, 10);
 
   MESSAGE("nbInputNodes: "<<nbInputNodes);
   MESSAGE("nbEnforcedVertices: "<<nbEnforcedVertices);
+  MESSAGE("nbEnforcedNodes: "<<nbEnforcedNodes);
   // Reading the nodeCoor and update the nodeMap
   for (int iNode=1; iNode <= nbNodes; iNode++) {
 #ifdef WITH_SMESH_CANCEL_COMPUTE
@@ -898,7 +2666,7 @@ static bool readResultFile(const int                       fileOpen,
     for (int iCoor=0; iCoor < 3; iCoor++)
       coord[ iCoor ] = strtod(ptr, &ptr);
     nodeAssigne[ iNode ] = 1;
-    if ( iNode > (nbInputNodes-nbEnforcedVertices) ) {
+    if ( iNode > (nbInputNodes-(nbEnforcedVertices+nbEnforcedNodes)) ) {
       // Creating SMESH nodes
       // - for enforced vertices
       // - for vertices of forced edges
@@ -929,9 +2697,14 @@ static bool readResultFile(const int                       fileOpen,
       const SMDS_MeshNode* n1 = theGhs3dIdToNodeMap[ nodeId1 ];
       const SMDS_MeshNode* n2 = theGhs3dIdToNodeMap[ nodeId2 ];
       const SMDS_MeshNode* n3 = theGhs3dIdToNodeMap[ nodeId3 ];
+      if (!n1 || !n2 || !n3) {
+        tabID[i] = HOLE_ID;
+        continue;
+      }
       try {
         OCC_CATCH_SIGNALS;
-        tabID[i] = findShapeID( theMesh, n1, n2, n3, toMeshHoles );
+//         tabID[i] = findShapeID( theHelper, n1, n2, n3, toMeshHoles );
+        tabID[i] = findShapeID( *theHelper.GetMesh(), n1, n2, n3, toMeshHoles );
         // -- 0020330: Pb with ghs3d as a submesh
         // check that found shape is to be meshed
         if ( tabID[i] > 0 ) {
@@ -1024,13 +2797,82 @@ static bool readResultFile(const int                       fileOpen,
       }
     }
     if ( toMeshHoles || shapeID != HOLE_ID ) {
-      aTet = theMeshDS->AddVolume( node[1], node[0], node[2], node[3] );
+      aTet = theHelper.AddVolume( node[1], node[0], node[2], node[3],
+                                  /*id=*/0, /*force3d=*/false);
       theMeshDS->SetMeshElementOnShape( aTet, shapeID );
     }
 #ifdef _DEBUG_
     shapeIDs.insert( shapeID );
 #endif
   }
+  
+  // Add enforced elements
+  GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap::const_iterator elemIt;
+  const SMDS_MeshElement* anElem;
+  SMDS_ElemIteratorPtr itOnEnfElem;
+  map<int,int>::const_iterator itOnMap;
+  shapeID = compoundID;
+  // Enforced edges
+  if (theEnforcedEdges.size()) {
+    std::cout << "Add " << theEnforcedEdges.size() << " enforced edges" << std::endl;
+    std::vector< const SMDS_MeshNode* > node( 2 );
+    // Iterate over the enforced edges
+    for(elemIt = theEnforcedEdges.begin() ; elemIt != theEnforcedEdges.end() ; ++elemIt) {
+      anElem = elemIt->first;
+      bool addElem = true;
+      itOnEnfElem = anElem->nodesIterator();
+      for ( int j = 0; j < 2; ++j ) {
+        int aNodeID = itOnEnfElem->next()->GetID();
+        itOnMap = theNodeId2NodeIndexMap.find(aNodeID);
+        if (itOnMap != theNodeId2NodeIndexMap.end()) {
+          itOnNode = theGhs3dIdToNodeMap.find((*itOnMap).second);
+          if (itOnNode != theGhs3dIdToNodeMap.end()) {
+            node.push_back((*itOnNode).second);
+//             shapeID =(*itOnNode).second->getshapeId();
+          }
+          else
+            addElem = false;
+        }
+        else
+          addElem = false;
+      }
+      if (addElem) {
+        aTet = theHelper.AddEdge( node[0], node[1], 0,  false);
+        theMeshDS->SetMeshElementOnShape( aTet, shapeID );
+      }
+    }
+  }
+  // Enforced faces
+  if (theEnforcedTriangles.size()) {
+    std::cout << "Add " << theEnforcedTriangles.size() << " enforced triangles" << std::endl;
+    std::vector< const SMDS_MeshNode* > node( 3 );
+    // Iterate over the enforced triangles
+    for(elemIt = theEnforcedTriangles.begin() ; elemIt != theEnforcedTriangles.end() ; ++elemIt) {
+      anElem = elemIt->first;
+      bool addElem = true;
+      itOnEnfElem = anElem->nodesIterator();
+      for ( int j = 0; j < 3; ++j ) {
+        int aNodeID = itOnEnfElem->next()->GetID();
+        itOnMap = theNodeId2NodeIndexMap.find(aNodeID);
+        if (itOnMap != theNodeId2NodeIndexMap.end()) {
+          itOnNode = theGhs3dIdToNodeMap.find((*itOnMap).second);
+          if (itOnNode != theGhs3dIdToNodeMap.end()) {
+            node.push_back((*itOnNode).second);
+//             shapeID =(*itOnNode).second->getshapeId();
+          }
+          else
+            addElem = false;
+        }
+        else
+          addElem = false;
+      }
+      if (addElem) {
+        aTet = theHelper.AddFace( node[0], node[1], node[2], 0,  false);
+        theMeshDS->SetMeshElementOnShape( aTet, shapeID );
+      }
+    }
+  }
+
   // Remove nodes of tetras inside holes if !toMeshHoles
   if ( !toMeshHoles ) {
     itOnNode = theGhs3dIdToNodeMap.find( nbInputNodes );
@@ -1074,170 +2916,10 @@ static bool readResultFile(const int                       fileOpen,
   return true;
 }
 
-//=======================================================================
-//function : readResultFile
-//purpose  : 
-//=======================================================================
-
-static bool readResultFile(const int                      fileOpen,
-#ifdef WNT
-                           const char*                    fileName,
-#endif
-#ifdef WITH_SMESH_CANCEL_COMPUTE
-                           GHS3DPlugin_GHS3D*             theAlgo,
-#endif
-                           SMESH_Mesh&                    theMesh,
-                           TopoDS_Shape                   aSolid,
-                           vector <const SMDS_MeshNode*>& theNodeByGhs3dId,
-                           int                            nbEnforcedVertices)
-{
-  SMESHDS_Mesh* theMeshDS = theMesh.GetMeshDS();
-
-  Kernel_Utils::Localizer loc;
-  struct stat  status;
-  size_t       length;
-
-  char *ptr, *mapPtr;
-  char *tetraPtr;
-  char *shapePtr;
-
-  int fileStat;
-  int nbElems, nbNodes, nbInputNodes;
-  int nodeId, triangleId;
-  int nbTriangle;
-  int ID, shapeID;
-
-  int *tab;
-  double *coord;
-  const SMDS_MeshNode **node;
-
-  tab   = new int[3];
-  coord = new double[3];
-  node  = new const SMDS_MeshNode*[4];
-
-  SMDS_MeshNode * aNewNode;
-  map <int,const SMDS_MeshNode*>::iterator IdNode;
-  SMDS_MeshElement* aTet;
-
-  // Read the file state
-  fileStat = fstat(fileOpen, &status);
-  length   = status.st_size;
-
-  // Mapping the result file into memory
-#ifdef WNT
-  HANDLE fd = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ,
-                         NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
-  HANDLE hMapObject = CreateFileMapping(fd, NULL, PAGE_READONLY,
-                                        0, (DWORD)length, NULL);
-  ptr = ( char* ) MapViewOfFile(hMapObject, FILE_MAP_READ, 0, 0, 0 );
-#else
-  ptr = (char *) mmap(0,length,PROT_READ,MAP_PRIVATE,fileOpen,0);
-#endif
-  mapPtr = ptr;
-
-  ptr      = readMapIntLine(ptr, tab);
-  tetraPtr = ptr;
-
-  nbElems      = tab[0];
-  nbNodes      = tab[1];
-  nbInputNodes = tab[2];
-
-  theNodeByGhs3dId.resize( nbNodes );
-
-  // Reading the nodeId
-  for (int i=0; i < 4*nbElems; i++)
-    nodeId = strtol(ptr, &ptr, 10);
-
-  // Issue 0020682. Avoid creating nodes and tetras at place where
-  // volumic elements already exist
-  SMESH_ElementSearcher* elemSearcher = 0;
-  vector< const SMDS_MeshElement* > foundVolumes;
-  if ( theMesh.NbVolumes() > 0 )
-    elemSearcher = SMESH_MeshEditor( &theMesh ).GetElementSearcher();
-
-  // Reading the nodeCoord and update the nodeMap
-  shapeID = theMeshDS->ShapeToIndex( aSolid );
-  for (int iNode=0; iNode < nbNodes; iNode++) {
-#ifdef WITH_SMESH_CANCEL_COMPUTE
-    if(theAlgo->computeCanceled())
-      return false;
-#endif
-    for (int iCoor=0; iCoor < 3; iCoor++)
-      coord[ iCoor ] = strtod(ptr, &ptr);
-    if ((iNode+1) > (nbInputNodes-nbEnforcedVertices)) {
-      // Issue 0020682. Avoid creating nodes and tetras at place where
-      // volumic elements already exist
-      if ( elemSearcher &&
-           elemSearcher->FindElementsByPoint( gp_Pnt(coord[0],coord[1],coord[2]),
-                                              SMDSAbs_Volume, foundVolumes ))
-      {
-        theNodeByGhs3dId[ iNode ] = 0;
-      }
-      else
-      {
-        aNewNode = theMeshDS->AddNode( coord[0],coord[1],coord[2] );
-        theMeshDS->SetNodeInVolume( aNewNode, shapeID );
-        theNodeByGhs3dId[ iNode ] = aNewNode;
-      }
-    }
-  }
-
-  // Reading the triangles
-  nbTriangle = strtol(ptr, &ptr, 10);
-
-  for (int i=0; i < 3*nbTriangle; i++)
-    triangleId = strtol(ptr, &ptr, 10);
-
-  shapePtr = ptr;
-
-  // Associating the tetrahedrons to the shapes
-  for (int iElem = 0; iElem < nbElems; iElem++) {
-#ifdef WITH_SMESH_CANCEL_COMPUTE
-    if(theAlgo->computeCanceled())
-      return false;
-#endif
-    for (int iNode = 0; iNode < 4; iNode++) {
-      ID = strtol(tetraPtr, &tetraPtr, 10);
-      node[ iNode ] = theNodeByGhs3dId[ ID-1 ];
-    }
-    if ( elemSearcher )
-    {
-      // Issue 0020682. Avoid creating nodes and tetras at place where
-      // volumic elements already exist
-      if ( !node[1] || !node[0] || !node[2] || !node[3] )
-        continue;
-      if ( elemSearcher->FindElementsByPoint(( SMESH_TNodeXYZ(node[0]) +
-                                               SMESH_TNodeXYZ(node[1]) +
-                                               SMESH_TNodeXYZ(node[2]) +
-                                               SMESH_TNodeXYZ(node[3]) ) / 4.,
-                                             SMDSAbs_Volume, foundVolumes ))
-        continue;
-    }
-    aTet = theMeshDS->AddVolume( node[1], node[0], node[2], node[3] );
-    shapeID = theMeshDS->ShapeToIndex( aSolid );
-    theMeshDS->SetMeshElementOnShape( aTet, shapeID );
-  }
-  if ( nbElems )
-    cout << nbElems << " tetrahedrons have been associated to " << nbTriangle << " shapes" << endl;
-#ifdef WNT
-  UnmapViewOfFile(mapPtr);
-  CloseHandle(hMapObject);
-  CloseHandle(fd);
-#else
-  munmap(mapPtr, length);
-#endif
-  close(fileOpen);
-
-  delete [] tab;
-  delete [] coord;
-  delete [] node;
-
-  return true;
-}
 
 //=============================================================================
 /*!
- *Here we are going to use the GHS3D mesher
+ *Here we are going to use the GHS3D mesher with geometry
  */
 //=============================================================================
 
@@ -1281,15 +2963,31 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
   TCollection_AsciiString aGenericName
     = (char*) GHS3DPlugin_Hypothesis::GetFileName(_hyp).c_str();
 
-  TCollection_AsciiString aFacesFileName, aPointsFileName, aResultFileName;
-  TCollection_AsciiString aBadResFileName, aBbResFileName, aLogFileName;
+  TCollection_AsciiString aResultFileName;
+  TCollection_AsciiString aLogFileName    = aGenericName + ".log";    // log
+  // The output .mesh file does not contain yet the subdomain-info (Ghs3D 4.2)
+//   TCollection_AsciiString aGMFFileName, aRequiredVerticesFileName, aSolFileName;
+//   TCollection_AsciiString aGenericNameRequired = aGenericName + "_required";
+// #ifdef _DEBUG_
+//   aGMFFileName    = aGenericName + ".mesh"; // GMF mesh file
+//   aResultFileName = aGenericName + "Vol.mesh"; // GMF mesh file
+//   aRequiredVerticesFileName    = aGenericNameRequired + ".mesh"; // GMF required vertices mesh file
+//   aSolFileName    = aGenericName + "_required.sol"; // GMF solution file
+// #else
+//   aGMFFileName    = aGenericName + ".meshb"; // GMF mesh file
+//   aResultFileName = aGenericName + "Vol.meshb"; // GMF mesh file
+//   aRequiredVerticesFileName    = aGenericNameRequired + ".meshb"; // GMF required vertices mesh file
+//   aSolFileName    = aGenericName + "_required.solb"; // GMF solution file
+// #endif
+
+  TCollection_AsciiString aFacesFileName, aPointsFileName, aBadResFileName, aBbResFileName;
+
   aFacesFileName  = aGenericName + ".faces";  // in faces
   aPointsFileName = aGenericName + ".points"; // in points
   aResultFileName = aGenericName + ".noboite";// out points and volumes
   aBadResFileName = aGenericName + ".boite";  // out bad result
   aBbResFileName  = aGenericName + ".bb";     // out vertex stepsize
-  aLogFileName    = aGenericName + ".log";    // log
-
+  
   // -----------------
   // make input files
   // -----------------
@@ -1303,17 +3001,22 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
     INFOS( "Can't write into " << aFacesFileName);
     return error(SMESH_Comment("Can't write into ") << aFacesFileName);
   }
-  map <int,int> aSmdsToGhs3dIdMap;
-  map <int,const SMDS_MeshNode*> aGhs3dIdToNodeMap;
-  map<vector<double>,double> enforcedVertices;
-  int nbEnforcedVertices = 0;
-  try {
-    enforcedVertices = GHS3DPlugin_Hypothesis::GetEnforcedVertices(_hyp);
-    nbEnforcedVertices = enforcedVertices.size();
-  }
-  catch(...) {
-  }
 
+  std::map <int,int> aNodeId2NodeIndexMap, aSmdsToGhs3dIdMap, anEnforcedNodeIdToGhs3dIdMap;
+  std::map <int,const SMDS_MeshNode*> aGhs3dIdToNodeMap;
+  std::map <int, int> nodeID2nodeIndexMap;
+  GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexCoordsValues coordsSizeMap = GHS3DPlugin_Hypothesis::GetEnforcedVerticesCoordsSize(_hyp);
+  GHS3DPlugin_Hypothesis::TIDSortedNodeGroupMap enforcedNodes = GHS3DPlugin_Hypothesis::GetEnforcedNodes(_hyp);
+  GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap enforcedEdges = GHS3DPlugin_Hypothesis::GetEnforcedEdges(_hyp);
+  GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap enforcedTriangles = GHS3DPlugin_Hypothesis::GetEnforcedTriangles(_hyp);
+//   TIDSortedElemSet enforcedQuadrangles = GHS3DPlugin_Hypothesis::GetEnforcedQuadrangles(_hyp);
+  GHS3DPlugin_Hypothesis::TID2SizeMap nodeIDToSizeMap = GHS3DPlugin_Hypothesis::GetNodeIDToSizeMap(_hyp);
+
+  int nbEnforcedVertices = coordsSizeMap.size();
+  int nbEnforcedNodes = enforcedNodes.size();
+  std::cout << nbEnforcedNodes << " enforced nodes from hypo" << std::endl;
+  std::cout << nbEnforcedVertices << " enforced vertices from hypo" << std::endl;
+  
   SMESH_MesherHelper helper( theMesh );
   helper.SetSubShape( theShape );
 
@@ -1346,33 +3049,46 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
         return false;
     }
 
-    Ok = (writePoints( aPointsFile, helper, aSmdsToGhs3dIdMap, aGhs3dIdToNodeMap, enforcedVertices)
+    Ok = (writePoints( aPointsFile, helper, 
+                       aSmdsToGhs3dIdMap, anEnforcedNodeIdToGhs3dIdMap, aGhs3dIdToNodeMap, 
+                       nodeIDToSizeMap,
+                       coordsSizeMap, enforcedNodes, enforcedEdges, enforcedTriangles)
           &&
-          writeFaces ( aFacesFile, *proxyMesh, theShape, aSmdsToGhs3dIdMap ));
+          writeFaces ( aFacesFile, *proxyMesh, theShape, 
+                       aSmdsToGhs3dIdMap, anEnforcedNodeIdToGhs3dIdMap,
+                       enforcedEdges, enforcedTriangles ));
+//     Ok = writeGMFFile(aGMFFileName.ToCString(), aRequiredVerticesFileName.ToCString(), aSolFileName.ToCString(),
+//                       helper, *proxyMesh,
+//                       aNodeId2NodeIndexMap, aSmdsToGhs3dIdMap, aGhs3dIdToNodeMap,
+//                       enforcedNodes, enforcedEdges, enforcedTriangles, /*enforcedQuadrangles,*/
+//                       coordsSizeMap);
   }
 
   // Write aSmdsToGhs3dIdMap to temp file
   TCollection_AsciiString aSmdsToGhs3dIdMapFileName;
   aSmdsToGhs3dIdMapFileName = aGenericName + ".ids";  // ids relation
   ofstream aIdsFile  ( aSmdsToGhs3dIdMapFileName.ToCString()  , ios::out);
-  Ok =
-    aIdsFile.rdbuf()->is_open();
+  Ok = aIdsFile.rdbuf()->is_open();
   if (!Ok) {
     INFOS( "Can't write into " << aSmdsToGhs3dIdMapFileName);
     return error(SMESH_Comment("Can't write into ") << aSmdsToGhs3dIdMapFileName);
   }
+  INFOS( "Writing ids relation into " << aSmdsToGhs3dIdMapFileName);
   aIdsFile << "Smds Ghs3d" << std::endl;
   map <int,int>::const_iterator myit;
   for (myit=aSmdsToGhs3dIdMap.begin() ; myit != aSmdsToGhs3dIdMap.end() ; ++myit) {
     aIdsFile << myit->first << " " << myit->second << std::endl;
   }
 
+  aIdsFile.close();
   aFacesFile.close();
   aPointsFile.close();
-  aIdsFile.close();
   
   if ( ! Ok ) {
     if ( !_keepFiles ) {
+//       removeFile( aGMFFileName );
+//       removeFile( aRequiredVerticesFileName );
+//       removeFile( aSolFileName );
       removeFile( aFacesFileName );
       removeFile( aPointsFileName );
       removeFile( aSmdsToGhs3dIdMapFileName );
@@ -1385,9 +3101,14 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
   // run ghs3d mesher
   // -----------------
 
-  TCollection_AsciiString cmd(char*)GHS3DPlugin_Hypothesis::CommandToRun( _hyp ).c_str() );
+  TCollection_AsciiString cmd = TCollection_AsciiString((char*)GHS3DPlugin_Hypothesis::CommandToRun( _hyp ).c_str() );
   cmd += TCollection_AsciiString(" -f ") + aGenericName;  // file to read
   cmd += TCollection_AsciiString(" 1>" ) + aLogFileName;  // dump into file
+  // The output .mesh file does not contain yet the subdomain-info (Ghs3D 4.2)
+//   cmd += TCollection_AsciiString(" --in ") + aGenericName;
+//   cmd += TCollection_AsciiString(" --required_vertices ") + aGenericNameRequired;
+//    cmd += TCollection_AsciiString(" --out ") + aResultGMFFileName;
+//   cmd += TCollection_AsciiString(" 1>" ) + aLogFileName;  // dump into file
 
   std::cout << std::endl;
   std::cout << "Ghs3d execution..." << std::endl;
@@ -1419,6 +3140,10 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
   else {
     bool toMeshHoles =
       _hyp ? _hyp->GetToMeshHoles(true) : GHS3DPlugin_Hypothesis::DefaultMeshHoles();
+
+    helper.IsQuadraticSubMesh( theShape );
+    helper.SetElementsOnShape( false );
+
     Ok = readResultFile( fileOpen,
 #ifdef WNT
                          aResultFileName.ToCString(),
@@ -1426,10 +3151,25 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
 #ifdef WITH_SMESH_CANCEL_COMPUTE
                          this,
 #endif
-                         theMesh, tabShape, tabBox, _nbShape, aGhs3dIdToNodeMap,
-                         toMeshHoles, nbEnforcedVertices );
+                         /*theMesh, */helper, tabShape, tabBox, _nbShape, 
+                         aGhs3dIdToNodeMap, aNodeId2NodeIndexMap,
+                         toMeshHoles, 
+                         nbEnforcedVertices, nbEnforcedNodes, 
+                         enforcedEdges, enforcedTriangles );
+                         
+//       Ok = readGMFFile(
+// #ifndef GMF_HAS_SUBDOMAIN_INFO
+//                        fileOpen,
+// #endif
+//                        aGenericName.ToCString(), theMesh,
+//                        _nbShape, tabShape, tabBox, 
+//                        aGhs3dIdToNodeMap, toMeshHoles,
+//                        nbEnforcedVertices, nbEnforcedNodes);
   }
 
+
+
+
   // ---------------------
   // remove working files
   // ---------------------
@@ -1485,49 +3225,117 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
  */
 //=============================================================================
 bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
-                                SMESH_MesherHelper* aHelper)
+                                SMESH_MesherHelper* theHelper)
 {
   MESSAGE("GHS3DPlugin_GHS3D::Compute()");
 
   //SMESHDS_Mesh* meshDS = theMesh.GetMeshDS();
-  TopoDS_Shape theShape = aHelper->GetSubShape();
+  TopoDS_Shape theShape = theHelper->GetSubShape();
 
   // a unique working file name
   // to avoid access to the same files by eg different users
   TCollection_AsciiString aGenericName
     = (char*) GHS3DPlugin_Hypothesis::GetFileName(_hyp).c_str();
+  TCollection_AsciiString aGenericNameRequired = aGenericName + "_required";
 
-  TCollection_AsciiString aFacesFileName, aPointsFileName, aResultFileName;
-  TCollection_AsciiString aBadResFileName, aBbResFileName, aLogFileName;
-  aFacesFileName  = aGenericName + ".faces";  // in faces
-  aPointsFileName = aGenericName + ".points"; // in points
-  aResultFileName = aGenericName + ".noboite";// out points and volumes
-  aBadResFileName = aGenericName + ".boite";  // out bad result
-  aBbResFileName  = aGenericName + ".bb";     // out vertex stepsize
-  aLogFileName    = aGenericName + ".log";    // log
-
-  // -----------------
-  // make input files
-  // -----------------
-
-  ofstream aFacesFile  ( aFacesFileName.ToCString()  , ios::out);
-  ofstream aPointsFile  ( aPointsFileName.ToCString()  , ios::out);
-  bool Ok =
-    aFacesFile.rdbuf()->is_open() && aPointsFile.rdbuf()->is_open();
+  TCollection_AsciiString aLogFileName    = aGenericName + ".log";    // log
+  TCollection_AsciiString aResultFileName;
+  bool Ok;
 
-  if (!Ok)
-    return error( SMESH_Comment("Can't write into ") << aPointsFileName);
+  TCollection_AsciiString aGMFFileName, aRequiredVerticesFileName, aSolFileName;
+#ifdef _DEBUG_
+  aGMFFileName    = aGenericName + ".mesh"; // GMF mesh file
+  aResultFileName = aGenericName + "Vol.mesh"; // GMF mesh file
+  aRequiredVerticesFileName    = aGenericNameRequired + ".mesh"; // GMF required vertices mesh file
+  aSolFileName    = aGenericNameRequired + ".sol"; // GMF solution file
+#else
+  aGMFFileName    = aGenericName + ".meshb"; // GMF mesh file
+  aResultFileName = aGenericName + "Vol.meshb"; // GMF mesh file
+  aRequiredVerticesFileName    = aGenericNameRequired + ".meshb"; // GMF required vertices mesh file
+  aSolFileName    = aGenericNameRequired + ".solb"; // GMF solution file
+#endif
   
-  GHS3DPlugin_Hypothesis::TEnforcedVertexValues enforcedVertices;
-  int nbEnforcedVertices = 0;
-  try {
-    enforcedVertices = GHS3DPlugin_Hypothesis::GetEnforcedVertices(_hyp);
-    nbEnforcedVertices = enforcedVertices.size();
-  }
-  catch(...) {
+  std::map <int, int> nodeID2nodeIndexMap;
+  std::map<std::vector<double>, std::string> enfVerticesWithGroup;
+  GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexCoordsValues coordsSizeMap;
+  TopoDS_Shape GeomShape;
+  TopAbs_ShapeEnum GeomType;
+  std::vector<double> coords;
+  gp_Pnt aPnt;
+  GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex* enfVertex;
+  
+  GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexList enfVertices = GHS3DPlugin_Hypothesis::GetEnforcedVertices(_hyp);
+  GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexList::const_iterator enfVerIt = enfVertices.begin();
+  for ( ; enfVerIt != enfVertices.end() ; ++enfVerIt)
+  {
+    enfVertex = (*enfVerIt);
+    if (enfVertex->geomEntry.empty() && enfVertex->coords.size()) {
+      coordsSizeMap.insert(make_pair(enfVertex->coords,enfVertex->size));
+      enfVerticesWithGroup.insert(make_pair(coords,enfVertex->groupName));
+    }
+    if (!enfVertex->geomEntry.empty()) {
+      GeomShape = entryToShape(enfVertex->geomEntry);
+      GeomType = GeomShape.ShapeType();
+      
+      if (GeomType == TopAbs_VERTEX) {
+        coords.clear();
+        aPnt = BRep_Tool::Pnt(TopoDS::Vertex(GeomShape));
+        coords.push_back(aPnt.X());
+        coords.push_back(aPnt.Y());
+        coords.push_back(aPnt.Z());
+        if (coordsSizeMap.find(coords) == coordsSizeMap.end()) {
+          coordsSizeMap.insert(make_pair(coords,enfVertex->size));
+          enfVerticesWithGroup.insert(make_pair(coords,enfVertex->groupName));
+        }
+      }
+      
+      // Group Management
+      if (GeomType == TopAbs_COMPOUND){
+        for (TopoDS_Iterator it (GeomShape); it.More(); it.Next()){
+          coords.clear();
+          if (it.Value().ShapeType() == TopAbs_VERTEX){
+            aPnt = BRep_Tool::Pnt(TopoDS::Vertex(it.Value()));
+            coords.push_back(aPnt.X());
+            coords.push_back(aPnt.Y());
+            coords.push_back(aPnt.Z());
+            if (coordsSizeMap.find(coords) == coordsSizeMap.end()) {
+              coordsSizeMap.insert(make_pair(coords,enfVertex->size));
+              enfVerticesWithGroup.insert(make_pair(coords,enfVertex->groupName));
+            }
+          }
+        }
+      }
+    }
   }
-
-  vector <const SMDS_MeshNode*> aNodeByGhs3dId;
+  
+//   const SMDS_MeshNode* enfNode;
+  GHS3DPlugin_Hypothesis::TIDSortedNodeGroupMap enforcedNodes = GHS3DPlugin_Hypothesis::GetEnforcedNodes(_hyp);
+//   GHS3DPlugin_Hypothesis::TIDSortedNodeGroupMap::const_iterator enfNodeIt = enforcedNodes.begin();
+//   for ( ; enfNodeIt != enforcedNodes.end() ; ++enfNodeIt)
+//   {
+//     enfNode = enfNodeIt->first;
+//     coords.clear();
+//     coords.push_back(enfNode->X());
+//     coords.push_back(enfNode->Y());
+//     coords.push_back(enfNode->Z());
+//     if (enfVerticesWithGro
+//       enfVerticesWithGroup.insert(make_pair(coords,enfNodeIt->second));
+//   }
+  
+  
+  GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap enforcedEdges = GHS3DPlugin_Hypothesis::GetEnforcedEdges(_hyp);
+  GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap enforcedTriangles = GHS3DPlugin_Hypothesis::GetEnforcedTriangles(_hyp);
+//   TIDSortedElemSet enforcedQuadrangles = GHS3DPlugin_Hypothesis::GetEnforcedQuadrangles(_hyp);
+  GHS3DPlugin_Hypothesis::TID2SizeMap nodeIDToSizeMap = GHS3DPlugin_Hypothesis::GetNodeIDToSizeMap(_hyp);
+
+  int nbEnforcedVertices = coordsSizeMap.size();
+  int nbEnforcedNodes = enforcedNodes.size();
+  std::cout << nbEnforcedNodes << " enforced nodes from hypo" << std::endl;
+  std::cout << nbEnforcedVertices << " enforced vertices from hypo" << std::endl;
+  
+  std::vector <const SMDS_MeshNode*> aNodeByGhs3dId, anEnforcedNodeByGhs3dId;
+  std::map<const SMDS_MeshNode*,int> aNodeToGhs3dIdMap;
+  std::vector<std::string> aNodeGroupByGhs3dId, anEdgeGroupByGhs3dId, aFaceGroupByGhs3dId;
   {
     SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( theMesh ));
     if ( theMesh.NbQuadrangles() > 0 )
@@ -1537,29 +3345,29 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
       proxyMesh.reset( aQuad2Trias );
     }
 
-    Ok = (writeFaces ( aFacesFile, *proxyMesh, aNodeByGhs3dId ) &&
-          writePoints( aPointsFile, &theMesh, aNodeByGhs3dId,enforcedVertices));
-  }  
-  aFacesFile.close();
-  aPointsFile.close();
-  
-  if ( ! Ok ) {
-    if ( !_keepFiles ) {
-      removeFile( aFacesFileName );
-      removeFile( aPointsFileName );
-    }
-    return error(COMPERR_BAD_INPUT_MESH);
+    Ok = writeGMFFile(aGMFFileName.ToCString(), aRequiredVerticesFileName.ToCString(), aSolFileName.ToCString(),
+                      *proxyMesh, &theMesh,
+                      aNodeByGhs3dId, anEnforcedNodeByGhs3dId, aNodeToGhs3dIdMap, 
+                      aNodeGroupByGhs3dId, anEdgeGroupByGhs3dId, aFaceGroupByGhs3dId,
+                      enforcedNodes, enforcedEdges, enforcedTriangles,
+                      enfVerticesWithGroup, coordsSizeMap);
   }
-  removeFile( aResultFileName ); // needed for boundary recovery module usage
 
   // -----------------
   // run ghs3d mesher
   // -----------------
 
-  TCollection_AsciiString cmd =
-    (char*)GHS3DPlugin_Hypothesis::CommandToRun( _hyp, false ).c_str();
-  cmd += TCollection_AsciiString(" -f ") + aGenericName;  // file to read
+  TCollection_AsciiString cmd = TCollection_AsciiString((char*)GHS3DPlugin_Hypothesis::CommandToRun( _hyp, false ).c_str());
+
+  cmd += TCollection_AsciiString(" --in ") + aGenericName;
+  if ( nbEnforcedVertices + nbEnforcedNodes)
+    cmd += TCollection_AsciiString(" --required_vertices ") + aGenericNameRequired;
+  cmd += TCollection_AsciiString(" --out ") + aResultFileName;
   cmd += TCollection_AsciiString(" 1>" ) + aLogFileName;  // dump into file
+
+  std::cout << std::endl;
+  std::cout << "Ghs3d execution..." << std::endl;
+  std::cout << cmd << std::endl;
   
 #ifdef WITH_SMESH_CANCEL_COMPUTE
   _compute_canceled = false;
@@ -1567,28 +3375,19 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
 
   system( cmd.ToCString() ); // run
 
+  std::cout << std::endl;
+  std::cout << "End of Ghs3d execution !" << std::endl;
+
   // --------------
   // read a result
   // --------------
-  int fileOpen;
-  fileOpen = open( aResultFileName.ToCString(), O_RDONLY);
-  if ( fileOpen < 0 ) {
-    std::cout << std::endl;
-    std::cout << "Error when opening the " << aResultFileName.ToCString() << " file" << std::endl;
-    std::cout << "Log: " << aLogFileName << std::endl;
-    std::cout << std::endl;
-    Ok = false;
-  }
-  else {
-    Ok = readResultFile( fileOpen,
-#ifdef WNT
-                         aResultFileName.ToCString(),
-#endif
+
+  Ok = readGMFFile(aResultFileName.ToCString(),
 #ifdef WITH_SMESH_CANCEL_COMPUTE
-                         this,
+                   this,
 #endif
-                         theMesh, theShape ,aNodeByGhs3dId, nbEnforcedVertices );
-  }
+                   theHelper, theShape, aNodeByGhs3dId, aNodeToGhs3dIdMap,
+                   aNodeGroupByGhs3dId, anEdgeGroupByGhs3dId, aFaceGroupByGhs3dId);
   
   // ---------------------
   // remove working files
@@ -1619,13 +3418,7 @@ bool GHS3DPlugin_GHS3D::Compute(SMESH_Mesh&         theMesh,
       if(_compute_canceled)
         removeFile( aLogFileName );
 #endif
-    removeFile( aFacesFileName );
-    removeFile( aPointsFileName );
-    removeFile( aResultFileName );
-    removeFile( aBadResFileName );
-    removeFile( aBbResFileName );
   }
-  
   return Ok;
 }
 
@@ -2225,3 +4018,20 @@ bool GHS3DPlugin_GHS3D::Evaluate(SMESH_Mesh& aMesh,
   return true;
 }
 
+bool GHS3DPlugin_GHS3D::importGMFMesh(const char* theGMFFileName, SMESH_Mesh& theMesh)
+{
+  SMESH_MesherHelper* helper  = new SMESH_MesherHelper(theMesh );
+//   TopoDS_Shape theShape = theMesh.GetShapeToMesh();
+  std::vector <const SMDS_MeshNode*> dummyNodeVector;
+  std::map<const SMDS_MeshNode*,int> dummyNodeMap;
+  std::map<std::vector<double>, std::string> dummyEnfVertGroup;
+  std::vector<std::string> dummyElemGroup;
+  
+  bool ok = readGMFFile(theGMFFileName, 
+#ifdef WITH_SMESH_CANCEL_COMPUTE
+                        this,
+#endif
+                        helper, theMesh.GetShapeToMesh(), dummyNodeVector, dummyNodeMap, dummyElemGroup, dummyElemGroup, dummyElemGroup);
+  theMesh.GetMeshDS()->Modified();
+  return ok;
+}
index 1c2c32082a5c0272565681e99be7ad56f2bc5c89..e4d15c924121cf196a170c44cb3954aa37fa1293 100644 (file)
@@ -1,20 +1,20 @@
-//  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+// Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 //=============================================================================
 #define _GHS3DPlugin_GHS3D_HXX_
 
 #include "SMESH_3D_Algo.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_Gen_i.hxx"
 
 #include <map>
 #include <vector>
 
+extern "C"
+{
+  #include "libmesh5.h"
+}
+
+#ifndef GMFVERSION
+#define GMFVERSION GmfDouble
+#endif
+#define GMFDIMENSION 3
+
 class GHS3DPlugin_Hypothesis;
 class SMDS_MeshNode;
 class SMESH_Mesh;
 class StdMeshers_ViscousLayers;
 class TCollection_AsciiString;
 class _Ghs2smdsConvertor;
+class TopoDS_Shape;
 
 class GHS3DPlugin_GHS3D: public SMESH_3D_Algo
 {
@@ -62,16 +75,21 @@ public:
   virtual bool Compute(SMESH_Mesh&         theMesh,
                        SMESH_MesherHelper* aHelper);
 
+  bool importGMFMesh(const char* aGMFFileName, SMESH_Mesh& aMesh);
+
 private:
 
   bool storeErrorDescription(const TCollection_AsciiString& logFile,
                              const _Ghs2smdsConvertor &     toSmdsConvertor );
-
+  TopoDS_Shape entryToShape(std::string entry);
+  
   int  _iShape;
   int  _nbShape;
   bool _keepFiles;
   const GHS3DPlugin_Hypothesis* _hyp;
   const StdMeshers_ViscousLayers* _viscousLayersHyp;
+  SALOMEDS::Study_var myStudy;
+  SMESH_Gen_i* smeshGen_i;
 
 #ifdef WITH_SMESH_CANCEL_COMPUTE
   volatile bool _compute_canceled;
index c63525a0cd92e5a9ed4810172710cf04703d56a2..18cfe4a99cf55466e4b3dd5dbc98ca60c9604bc1 100644 (file)
@@ -1,20 +1,20 @@
-//  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+// Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 //  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
 //
 #include "GHS3DPlugin_GHS3D_i.hxx"
 #include "SMESH_Gen.hxx"
+#include "SMESH_Mesh_i.hxx"
+#include "SMESH_Gen_i.hxx"
 #include "GHS3DPlugin_GHS3D.hxx"
+#include "SMESH_PythonDump.hxx"
 
 #include "utilities.h"
+#include <cstring>
 
 using namespace std;
 
@@ -80,3 +84,35 @@ GHS3DPlugin_GHS3D_i::~GHS3DPlugin_GHS3D_i()
   return ( ::GHS3DPlugin_GHS3D* )myBaseImpl;
 }
 
+//=============================================================================
+/*!
+ *  GHS3DPlugin_GHS3D_i::~GHS3DPlugin_GHS3D_i
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+SMESH::SMESH_Mesh_ptr GHS3DPlugin_GHS3D_i::importGMFMesh(const char* theGMFFileName)
+{
+  MESSAGE( "GHS3DPlugin_GHS3D_i::importGMFMesh" );
+  SMESH_Gen_i* smeshGen = SMESH_Gen_i::GetSMESHGen();
+  SMESH::SMESH_Mesh_ptr theMesh = smeshGen->CreateEmptyMesh();
+  smeshGen->RemoveLastFromPythonScript(smeshGen->GetCurrentStudy()->StudyId());
+  SALOMEDS::SObject_ptr theSMesh = smeshGen->ObjectToSObject(smeshGen->GetCurrentStudy(), theMesh);
+#ifdef WINNT
+#define SEP '\\'
+#else
+#define SEP '/'
+#endif
+  string strFileName (theGMFFileName);
+  strFileName = strFileName.substr(strFileName.rfind(SEP)+1);
+  strFileName.erase(strFileName.rfind('.'));
+  smeshGen->SetName(theSMesh, strFileName.c_str());
+  SMESH_Mesh_i* meshServant = dynamic_cast<SMESH_Mesh_i*>( smeshGen->GetServant( theMesh ).in() );
+  ASSERT( meshServant );
+  if ( meshServant ) {
+    if (GetImpl()->importGMFMesh(theGMFFileName, meshServant->GetImpl()))
+      SMESH::TPythonDump() << theSMesh << " = " << _this() << ".importGMFMesh( \"" << theGMFFileName << "\")";
+  }
+  return theMesh;
+}
index e61fb45cdd7eef386e38189af9b23a355c2b9d59..8cb760b914b18007634e03b042b243521b485f97 100644 (file)
@@ -1,20 +1,20 @@
-//  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+// Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 //  File   : GHS3DPlugin_GHS3D_i.hxx
@@ -49,6 +49,8 @@ public:
  
   // Get implementation
   ::GHS3DPlugin_GHS3D* GetImpl();
+
+  virtual SMESH::SMESH_Mesh_ptr importGMFMesh(const char* theGMFFileName);
 };
 
 #endif
index bdfa2b9fe502ad6fbd6b9436eabcc0c49d513f83..c18cc42867d00d9f5c6d2356470198bf9c7647cf 100644 (file)
@@ -1,20 +1,20 @@
-//  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+// Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 //=============================================================================
@@ -24,6 +24,9 @@
 //=============================================================================
 //
 #include "GHS3DPlugin_Hypothesis.hxx"
+#include <SMESH_ProxyMesh.hxx>
+#include <SMESH_Group.hxx>
+#include <StdMeshers_QuadToTriaAdaptor.hxx>
 
 #include <TCollection_AsciiString.hxx>
 
@@ -49,7 +52,16 @@ GHS3DPlugin_Hypothesis::GHS3DPlugin_Hypothesis(int hypId, int studyId, SMESH_Gen
   myToUseBoundaryRecoveryVersion(DefaultToUseBoundaryRecoveryVersion()),
   myToUseFemCorrection(DefaultToUseFEMCorrection()),
   myToRemoveCentralPoint(DefaultToRemoveCentralPoint()),
-  myEnforcedVertices(DefaultEnforcedVertices())
+  _enfVertexList(DefaultGHS3DEnforcedVertexList()),
+  _enfVertexCoordsSizeList(DefaultGHS3DEnforcedVertexCoordsValues()),
+  _enfVertexEntrySizeList(DefaultGHS3DEnforcedVertexEntryValues()),
+  _coordsEnfVertexMap(DefaultCoordsGHS3DEnforcedVertexMap()),
+  _geomEntryEnfVertexMap(DefaultGeomEntryGHS3DEnforcedVertexMap()),
+  _enfNodes(TIDSortedNodeGroupMap()),
+  _enfEdges(TIDSortedElemGroupMap()),
+  _enfTriangles(TIDSortedElemGroupMap()),
+  _nodeIDToSizeMap(DefaultID2SizeMap()),
+  _elementIDToSizeMap(DefaultID2SizeMap())
 {
   _name = "GHS3D_Parameters";
   _param_algo_dim = 3;
@@ -318,54 +330,294 @@ std::string GHS3DPlugin_Hypothesis::GetTextOption() const
 //function : SetEnforcedVertex
 //=======================================================================
 
-void GHS3DPlugin_Hypothesis::SetEnforcedVertex(double x, double y, double z, double size)
+bool GHS3DPlugin_Hypothesis::SetEnforcedVertex(std::string theName, std::string theEntry, std::string theGroupName,
+                                               double size, double x, double y, double z)
 {
-  std::vector<double> coord(3);
-  coord[0] = x;
-  coord[1] = y;
-  coord[2] = z;
-  myEnforcedVertices[coord] = size;
-  NotifySubMeshesHypothesisModification();
+  MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedVertex("<< theName << ", "<< theEntry << ", " << theGroupName << ", "
+                                                      << size << ", " << x << ", " << y << ", " << z  << ")");
+
+  bool toNotify = false;
+  bool toCreate = true;
+
+  TGHS3DEnforcedVertex *oldEnVertex;
+  TGHS3DEnforcedVertex *newEnfVertex = new TGHS3DEnforcedVertex();
+  newEnfVertex->name = theName;
+  newEnfVertex->geomEntry = theEntry;
+  newEnfVertex->coords.clear();
+  if (theEntry == "") {
+    newEnfVertex->coords.push_back(x);
+    newEnfVertex->coords.push_back(y);
+    newEnfVertex->coords.push_back(z);
+  }
+  newEnfVertex->groupName = theGroupName;
+  newEnfVertex->size = size;
+  
+  
+  // update _enfVertexList
+  TGHS3DEnforcedVertexList::iterator it = _enfVertexList.find(newEnfVertex);
+  if (it != _enfVertexList.end()) {
+    toCreate = false;
+    oldEnVertex = (*it);
+    MESSAGE("Enforced Vertex was found => Update");
+    if (oldEnVertex->name != theName) {
+      MESSAGE("Update name from \"" << oldEnVertex->name << "\" to \"" << theName << "\"");
+      oldEnVertex->name = theName;
+      toNotify = true;
+    }
+    if (oldEnVertex->groupName != theGroupName) {
+      MESSAGE("Update group name from \"" << oldEnVertex->groupName << "\" to \"" << theGroupName << "\"");
+      oldEnVertex->groupName = theGroupName;
+      toNotify = true;
+    }
+    if (oldEnVertex->size != size) {
+      MESSAGE("Update size from \"" << oldEnVertex->size << "\" to \"" << size << "\"");
+      oldEnVertex->size = size;
+      toNotify = true;
+    }
+    if (toNotify) {
+      // update map coords / enf vertex if needed
+      if (oldEnVertex->coords.size()) {
+        _coordsEnfVertexMap[oldEnVertex->coords] = oldEnVertex;
+        _enfVertexCoordsSizeList[oldEnVertex->coords] = size;
+      }
+
+      // update map geom entry / enf vertex if needed
+      if (oldEnVertex->geomEntry != "") {
+        _geomEntryEnfVertexMap[oldEnVertex->geomEntry] = oldEnVertex;
+        _enfVertexEntrySizeList[oldEnVertex->geomEntry] = size;
+      }
+    }
+  }
+
+//   //////// CREATE ////////////
+  if (toCreate) {
+    toNotify = true;
+    MESSAGE("Creating new enforced vertex");
+    _enfVertexList.insert(newEnfVertex);
+    if (theEntry == "") {
+      _coordsEnfVertexMap[newEnfVertex->coords] = newEnfVertex;
+      _enfVertexCoordsSizeList[newEnfVertex->coords] = size;
+    }
+    else {
+      _geomEntryEnfVertexMap[newEnfVertex->geomEntry] = newEnfVertex;
+      _enfVertexEntrySizeList[newEnfVertex->geomEntry] = size;
+    }
+  }
+
+  if (toNotify)
+    NotifySubMeshesHypothesisModification();
+
+  MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedVertex END");
+  return toNotify;
+}
+
+
+//=======================================================================
+//function : SetEnforcedMesh
+//=======================================================================
+bool GHS3DPlugin_Hypothesis::SetEnforcedMesh(SMESH_Mesh& theMesh, SMESH::ElementType elementType, double size, std::string groupName)
+{
+  TIDSortedElemSet theElemSet;
+  SMDS_ElemIteratorPtr eIt = theMesh.GetMeshDS()->elementsIterator(SMDSAbs_ElementType(elementType));
+  while ( eIt->more() )
+    theElemSet.insert( eIt->next() );
+  MESSAGE("Add "<<theElemSet.size()<<" types["<<elementType<<"] from source mesh");
+  return SetEnforcedElements( theElemSet, elementType, size, groupName);
+}
+
+//=======================================================================
+//function : SetEnforcedGroup
+//=======================================================================
+bool GHS3DPlugin_Hypothesis::SetEnforcedGroup(const SMESHDS_Mesh* theMeshDS, SMESH::long_array_var theIDs, SMESH::ElementType elementType, double size, std::string groupName)
+{
+  MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedGroup");
+  TIDSortedElemSet theElemSet;
+    if ( theIDs->length() == 0 ){MESSAGE("The source group is empty");}
+    for (int i=0; i < theIDs->length(); i++) {
+      CORBA::Long ind = theIDs[i];
+      if (elementType == SMESH::NODE)
+      {
+        const SMDS_MeshNode * node = theMeshDS->FindNode(ind);
+        if (node)
+          theElemSet.insert( node );
+      }
+      else
+      {
+        const SMDS_MeshElement * elem = theMeshDS->FindElement(ind);
+        if (elem)
+          theElemSet.insert( elem );
+      }
+    }
+
+//   SMDS_ElemIteratorPtr it = theGroup->GetGroupDS()->GetElements();
+//   while ( it->more() ) 
+//     theElemSet.insert( it->next() );
+
+  MESSAGE("Add "<<theElemSet.size()<<" types["<<elementType<<"] from source group ");
+  return SetEnforcedElements( theElemSet, elementType, size, groupName);
 }
 
+//=======================================================================
+//function : SetEnforcedElements
+//=======================================================================
+bool GHS3DPlugin_Hypothesis::SetEnforcedElements(TIDSortedElemSet theElemSet, SMESH::ElementType elementType, double size, std::string groupName)
+{
+  MESSAGE("GHS3DPlugin_Hypothesis::SetEnforcedElements");
+  TIDSortedElemSet::const_iterator it = theElemSet.begin();
+  const SMDS_MeshElement* elem;
+  const SMDS_MeshNode* node;
+  bool added = false;
+  for (;it != theElemSet.end();++it)
+  {
+    elem = (*it);
+    switch (elementType) {
+      case SMESH::NODE:
+        node = dynamic_cast<const SMDS_MeshNode*>(elem);
+        if (node) {
+          _enfNodes.insert(make_pair(node,groupName));
+          _nodeIDToSizeMap.insert(make_pair(node->GetID(), size));
+          added = true;
+        }
+        else {
+          SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
+          for (;nodeIt->more();) {
+            node = dynamic_cast<const SMDS_MeshNode*>(nodeIt->next());
+            _enfNodes.insert(make_pair(node,groupName));
+            _nodeIDToSizeMap.insert(make_pair(node->GetID(), size));
+          }
+          added = true;
+        }
+        break;
+      case SMESH::EDGE:
+        if (elem->GetType() == SMDSAbs_Edge) {
+          _enfEdges.insert(make_pair(elem,groupName));
+          _elementIDToSizeMap.insert(make_pair(elem->GetID(), size));
+          added = true;
+        }
+        else if (elem->GetType() > SMDSAbs_Edge) {
+          SMDS_ElemIteratorPtr it = elem->edgesIterator();
+          for (;it->more();) {
+            const SMDS_MeshElement* anEdge = it->next();
+            _enfEdges.insert(make_pair(anEdge,groupName));
+            _elementIDToSizeMap.insert(make_pair(anEdge->GetID(), size));
+          }
+          added = true;
+        }
+        break;
+      case SMESH::FACE:
+        if (elem->GetType() == SMDSAbs_Face)
+        {
+          if (elem->NbCornerNodes() == 3) {
+            _enfTriangles.insert(make_pair(elem,groupName));
+            _elementIDToSizeMap.insert(make_pair(elem->GetID(), size));
+            added = true;
+          }
+        }
+        else if (elem->GetType() > SMDSAbs_Face) { // Group of faces
+          SMDS_ElemIteratorPtr it = elem->facesIterator();
+          for (;it->more();) {
+            const SMDS_MeshElement* aFace = it->next();
+            if (aFace->NbCornerNodes() == 3) {
+              _enfTriangles.insert(make_pair(aFace,groupName));
+              _elementIDToSizeMap.insert(make_pair(aFace->GetID(), size));
+              added = true;
+            }
+          }
+        }
+        break;
+      default:
+        break;
+    };
+  }
+  if (added)
+    NotifySubMeshesHypothesisModification();
+  return added;
+}
+
+
 //=======================================================================
 //function : GetEnforcedVertex
 //=======================================================================
 
-double GHS3DPlugin_Hypothesis::GetEnforcedVertex(double x, double y, double z)
+GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex* GHS3DPlugin_Hypothesis::GetEnforcedVertex(double x, double y, double z)
   throw (std::invalid_argument)
 {
   std::vector<double> coord(3);
   coord[0] = x;
   coord[1] = y;
   coord[2] = z;
-  if (myEnforcedVertices.count(coord)>0)
-    return myEnforcedVertices[coord];
+  if (_coordsEnfVertexMap.count(coord)>0)
+    return _coordsEnfVertexMap[coord];
   std::ostringstream msg ;
   msg << "No enforced vertex at " << x << ", " << y << ", " << z;
   throw std::invalid_argument(msg.str());
 }
 
+GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex* GHS3DPlugin_Hypothesis::GetEnforcedVertex(const std::string theEntry)
+  throw (std::invalid_argument)
+{
+  if (_geomEntryEnfVertexMap.count(theEntry)>0)
+    return _geomEntryEnfVertexMap[theEntry];
+  
+  std::ostringstream msg ;
+  msg << "No enforced vertex with entry " << theEntry;
+  throw std::invalid_argument(msg.str());
+}
+
 //=======================================================================
 //function : RemoveEnforcedVertex
 //=======================================================================
 
-void GHS3DPlugin_Hypothesis::RemoveEnforcedVertex(double x, double y, double z)
+bool GHS3DPlugin_Hypothesis::RemoveEnforcedVertex(double x, double y, double z, const std::string theEntry)
   throw (std::invalid_argument)
 {
-    std::vector<double> coord(3);
-    coord[0] = x;
-    coord[1] = y;
-    coord[2] = z;
-    TEnforcedVertexValues::iterator it = myEnforcedVertices.find(coord);
-    if (it != myEnforcedVertices.end()) {
-        myEnforcedVertices.erase(it);
-        NotifySubMeshesHypothesisModification();
-        return;
+  bool toNotify = false;
+  std::ostringstream msg;
+  TGHS3DEnforcedVertex *oldEnfVertex;
+  std::vector<double> coords(3);
+  coords[0] = x;
+  coords[1] = y;
+  coords[2] = z;
+  
+  // check that enf vertex with given enf vertex entry exists
+  TGeomEntryGHS3DEnforcedVertexMap::iterator it_enfVertexEntry = _geomEntryEnfVertexMap.find(theEntry);
+  if (it_enfVertexEntry != _geomEntryEnfVertexMap.end()) {
+    // Success
+    MESSAGE("Found enforced vertex with geom entry " << theEntry);
+    oldEnfVertex = it_enfVertexEntry->second;
+    _geomEntryEnfVertexMap.erase(it_enfVertexEntry);
+  } else {
+    // Fail
+    MESSAGE("Enforced vertex with geom entry " << theEntry << " not found");
+    // check that enf vertex with given coords exists
+    TCoordsGHS3DEnforcedVertexMap::iterator it_coords_enf = _coordsEnfVertexMap.find(coords);
+    if (it_coords_enf != _coordsEnfVertexMap.end()) {
+      // Success
+      MESSAGE("Found enforced vertex with coords " << x << ", " << y << ", " << z);
+      oldEnfVertex = it_coords_enf->second;
+      _coordsEnfVertexMap.erase(it_coords_enf);
+      _enfVertexCoordsSizeList.erase(_enfVertexCoordsSizeList.find(coords));
+    } else {
+      // Fail
+      MESSAGE("Enforced vertex with coords " << x << ", " << y << ", " << z << " not found");
+      throw std::invalid_argument(msg.str());
     }
-    std::ostringstream msg ;
-    msg << "No enforced vertex at " << x << ", " << y << ", " << z;
-    throw std::invalid_argument(msg.str());
+  }
+
+  MESSAGE("Remove enf vertex from _enfVertexList");
+
+  // update _enfVertexList
+  TGHS3DEnforcedVertexList::iterator it = _enfVertexList.find(oldEnfVertex);
+  if (it != _enfVertexList.end()) {
+    _enfVertexList.erase(it);
+    toNotify = true;
+    MESSAGE("Done");
+  }
+
+  if (toNotify)
+    NotifySubMeshesHypothesisModification();
+
+  return toNotify;
 }
 
 //=======================================================================
@@ -373,10 +625,28 @@ void GHS3DPlugin_Hypothesis::RemoveEnforcedVertex(double x, double y, double z)
 //=======================================================================
 void GHS3DPlugin_Hypothesis::ClearEnforcedVertices()
 {
-    myEnforcedVertices.clear();
+    _enfVertexList.clear();
+    _coordsEnfVertexMap.clear();
+    _geomEntryEnfVertexMap.clear();
+    _enfVertexCoordsSizeList.clear();
+    _enfVertexEntrySizeList.clear();
     NotifySubMeshesHypothesisModification();
 }
 
+//=======================================================================
+//function : ClearEnforcedMeshes
+//=======================================================================
+void GHS3DPlugin_Hypothesis::ClearEnforcedMeshes()
+{
+   _enfNodes.clear();
+   _enfEdges.clear();
+   _enfTriangles.clear();
+   _nodeIDToSizeMap.clear();
+   _elementIDToSizeMap.clear();
+   NotifySubMeshesHypothesisModification();
+}
+
+
 //=======================================================================
 //function : DefaultMeshHoles
 //=======================================================================
@@ -516,12 +786,12 @@ bool GHS3DPlugin_Hypothesis::DefaultToRemoveCentralPoint()
 }
 
 //=======================================================================
-//function : DefaultEnforcedVertices
+//function : DefaultID2SizeMap
 //=======================================================================
 
-GHS3DPlugin_Hypothesis::TEnforcedVertexValues GHS3DPlugin_Hypothesis::DefaultEnforcedVertices()
+GHS3DPlugin_Hypothesis::TID2SizeMap GHS3DPlugin_Hypothesis::DefaultID2SizeMap()
 {
-  return GHS3DPlugin_Hypothesis::TEnforcedVertexValues();
+  return GHS3DPlugin_Hypothesis::TID2SizeMap();
 }
 
 
@@ -549,14 +819,37 @@ std::ostream & GHS3DPlugin_Hypothesis::SaveTo(std::ostream & save)
   }
   
 
-  TEnforcedVertexValues::iterator it  = myEnforcedVertices.begin();
-  if (it != myEnforcedVertices.end()) {
+  TGHS3DEnforcedVertexList::iterator it  = _enfVertexList.begin();
+  if (it != _enfVertexList.end()) {
     save << "__ENFORCED_VERTICES_BEGIN__ ";
-    for ( ; it != myEnforcedVertices.end(); ++it ) {
-        save << it->first[0] << " "
-             << it->first[1] << " "
-             << it->first[2] << " "
-             << it->second << " ";
+    for ( ; it != _enfVertexList.end(); ++it ) {
+      TGHS3DEnforcedVertex *enfVertex = (*it);
+      save << " " << "__BEGIN_VERTEX__";
+      if (!enfVertex->name.empty()) {
+        save << " " << "__BEGIN_NAME__";
+        save << " " << enfVertex->name;
+        save << " " << "__END_NAME__";
+      }
+      if (!enfVertex->geomEntry.empty()) {
+        save << " " << "__BEGIN_ENTRY__";
+        save << " " << enfVertex->geomEntry;
+        save << " " << "__END_ENTRY__";
+      }
+      if (!enfVertex->groupName.empty()) {
+        save << " " << "__BEGIN_GROUP__";
+        save << " " << enfVertex->groupName;
+        save << " " << "__END_GROUP__";
+      }
+      if (enfVertex->coords.size()) {
+        save << " " << "__BEGIN_COORDS__";
+        for (int i=0;i<enfVertex->coords.size();i++)
+          save << " " << enfVertex->coords[i];
+        save << " " << "__END_COORDS__";
+      }
+      save << " " << "__BEGIN_SIZE__";
+      save << " " << enfVertex->size;
+      save << " " << "__BEGIN_SIZE__";
+      save << " " << "__END_VERTEX__";
     }
     save << "__ENFORCED_VERTICES_END__ ";
   }
@@ -570,145 +863,209 @@ std::ostream & GHS3DPlugin_Hypothesis::SaveTo(std::ostream & save)
 
 std::istream & GHS3DPlugin_Hypothesis::LoadFrom(std::istream & load)
 {
-    bool isOK = true;
-    int i;
-    
-    isOK = (load >> i);
-    if (isOK)
-        myToMeshHoles = i;
-    else
-        load.clear(ios::badbit | load.rdstate());
-    
-    isOK = (load >> i);
-    if (isOK)
-        myMaximumMemory = i;
-    else
-        load.clear(ios::badbit | load.rdstate());
-    
-    isOK = (load >> i);
-    if (isOK)
-        myInitialMemory = i;
-    else
-        load.clear(ios::badbit | load.rdstate());
-    
-    isOK = (load >> i);
-    if (isOK)
-        myOptimizationLevel = i;
-    else
-        load.clear(ios::badbit | load.rdstate());
-    
-    isOK = (load >> myWorkingDirectory);
-    if (isOK) {
-        if ( myWorkingDirectory == "0") { // myWorkingDirectory was empty
-            myKeepFiles = false;
-            myWorkingDirectory.clear();
-        }
-        else if ( myWorkingDirectory == "1" ) {
-            myKeepFiles = true;
-            myWorkingDirectory.clear();
-        }
+  bool isOK = true;
+  int i;
+  
+  isOK = (load >> i);
+  if (isOK)
+    myToMeshHoles = i;
+  else
+    load.clear(ios::badbit | load.rdstate());
+  
+  isOK = (load >> i);
+  if (isOK)
+    myMaximumMemory = i;
+  else
+    load.clear(ios::badbit | load.rdstate());
+  
+  isOK = (load >> i);
+  if (isOK)
+    myInitialMemory = i;
+  else
+    load.clear(ios::badbit | load.rdstate());
+  
+  isOK = (load >> i);
+  if (isOK)
+    myOptimizationLevel = i;
+  else
+    load.clear(ios::badbit | load.rdstate());
+  
+  isOK = (load >> myWorkingDirectory);
+  if (isOK) {
+    if ( myWorkingDirectory == "0") { // myWorkingDirectory was empty
+      myKeepFiles = false;
+      myWorkingDirectory.clear();
     }
-    else
-        load.clear(ios::badbit | load.rdstate());
-    
-    if ( !myWorkingDirectory.empty() ) {
-        isOK = (load >> i);
-        if (isOK)
-            myKeepFiles = i;
-        else
-            load.clear(ios::badbit | load.rdstate());
+    else if ( myWorkingDirectory == "1" ) {
+      myKeepFiles = true;
+      myWorkingDirectory.clear();
     }
-    
-    isOK = (load >> i);
-    if (isOK)
-        myVerboseLevel = (short) i;
-    else
-        load.clear(ios::badbit | load.rdstate());
-    
-    isOK = (load >> i);
-    if (isOK)
-        myToCreateNewNodes = (bool) i;
-    else
-        load.clear(ios::badbit | load.rdstate());
-    
-    isOK = (load >> i);
-    if (isOK)
-        myToUseBoundaryRecoveryVersion = (bool) i;
-    else
-        load.clear(ios::badbit | load.rdstate());
-    
-    isOK = (load >> i);
-    if (isOK)
-        myToUseFemCorrection = (bool) i;
-    else
-        load.clear(ios::badbit | load.rdstate());
-    
+  }
+  else
+    load.clear(ios::badbit | load.rdstate());
+  
+  if ( !myWorkingDirectory.empty() ) {
     isOK = (load >> i);
     if (isOK)
-        myToRemoveCentralPoint = (bool) i;
+      myKeepFiles = i;
     else
-        load.clear(ios::badbit | load.rdstate());
-    
-    std::string separator;
-    bool hasOptions = false;
-    bool hasEnforcedVertices = false;
-    isOK = (load >> separator);
-
-    if (isOK) {
-        if (separator == "__OPTIONS_BEGIN__")
-            hasOptions = true;
-        else if (separator == "__ENFORCED_VERTICES_BEGIN__")
-            hasEnforcedVertices = true;
-    }
+      load.clear(ios::badbit | load.rdstate());
+  }
+  
+  isOK = (load >> i);
+  if (isOK)
+    myVerboseLevel = (short) i;
+  else
+    load.clear(ios::badbit | load.rdstate());
+  
+  isOK = (load >> i);
+  if (isOK)
+    myToCreateNewNodes = (bool) i;
+  else
+    load.clear(ios::badbit | load.rdstate());
+  
+  isOK = (load >> i);
+  if (isOK)
+    myToUseBoundaryRecoveryVersion = (bool) i;
+  else
+    load.clear(ios::badbit | load.rdstate());
+  
+  isOK = (load >> i);
+  if (isOK)
+    myToUseFemCorrection = (bool) i;
+  else
+    load.clear(ios::badbit | load.rdstate());
+  
+  isOK = (load >> i);
+  if (isOK)
+    myToRemoveCentralPoint = (bool) i;
+  else
+    load.clear(ios::badbit | load.rdstate());
+  
+  std::string separator;
+  bool hasOptions = false;
+  bool hasEnforcedVertices = false;
+  isOK = (load >> separator);
+
+  if (isOK) {
+    if (separator == "__OPTIONS_BEGIN__")
+      hasOptions = true;
+    else if (separator == "__ENFORCED_VERTICES_BEGIN__")
+      hasEnforcedVertices = true;
+  }
 
-    if (hasOptions) {
-        std::string txt;
-        while (isOK) {
-            isOK = (load >> txt);
-            if (isOK) {
-                if (txt == "__OPTIONS_END__") {
-                    if (!myTextOption.empty()) {
-                        // Remove last space
-                        myTextOption.erase(myTextOption.end()-1);
-                    }
-                    isOK = false;
-                    break;
-                }
-                myTextOption += txt;
-                myTextOption += " ";
-            }
+  if (hasOptions) {
+    std::string txt;
+    while (isOK) {
+      isOK = (load >> txt);
+      if (isOK) {
+        if (txt == "__OPTIONS_END__") {
+          if (!myTextOption.empty()) {
+            // Remove last space
+            myTextOption.erase(myTextOption.end()-1);
+          }
+          isOK = false;
+          break;
         }
+        myTextOption += txt;
+        myTextOption += " ";
+      }
     }
+  }
 
-    if (hasOptions) {
-        isOK = (load >> separator);
-        if (isOK)
-            if (separator == "__ENFORCED_VERTICES_BEGIN__")
-                hasEnforcedVertices = true;
-    }
+  if (hasOptions) {
+    isOK = (load >> separator);
+    if (isOK && separator == "__ENFORCED_VERTICES_BEGIN__")
+      hasEnforcedVertices = true;
+  }
 
-    if (hasEnforcedVertices) {
-        std::string txt;
-        double x,y,z,size;
+  if (hasEnforcedVertices) {
+    std::string txt, name, entry, groupName;
+    double size, coords[3];
+    bool hasCoords = false;
+    while (isOK) {
+      isOK = (load >> txt);  // __BEGIN_VERTEX__
+      if (isOK) {
+        if (txt == "__ENFORCED_VERTICES_END__")
+          isOK = false;
+
+        TGHS3DEnforcedVertex *enfVertex = new TGHS3DEnforcedVertex();
         while (isOK) {
-            isOK = (load >> txt);
-            if (isOK) {
-                if (txt == "__ENFORCED_VERTICES_END__") {
-                    isOK = false;
-                    break;
-                }
-                x = atof(txt.c_str());
-                isOK = (load >> y >> z >> size);
+          isOK = (load >> txt);
+          if (txt == "__END_VERTEX__") {
+            enfVertex->name = name;
+            enfVertex->geomEntry = entry;
+            enfVertex->groupName = groupName;
+            enfVertex->coords.clear();
+            if (hasCoords)
+              enfVertex->coords.assign(coords,coords+3);
+            
+            _enfVertexList.insert(enfVertex);
+            
+            if (enfVertex->coords.size())
+              _coordsEnfVertexMap[enfVertex->coords] = enfVertex;
+            if (!enfVertex->geomEntry.empty())
+              _geomEntryEnfVertexMap[enfVertex->geomEntry] = enfVertex;
+            
+            name.clear();
+            entry.clear();
+            groupName.clear();
+            hasCoords = false;
+            isOK = false;
+          }
+          
+          if (txt == "__BEGIN_NAME__") {  // __BEGIN_NAME__
+            while (isOK && (txt != "__END_NAME__")) {
+              isOK = (load >> txt);
+              if (txt != "__END_NAME__") {
+                if (!name.empty())
+                  name += " ";
+                name += txt;
+              }
             }
-            if (isOK) {
-                std::vector<double> coord;
-                coord.push_back(x);
-                coord.push_back(y);
-                coord.push_back(z);
-                myEnforcedVertices[ coord ] = size;
+            MESSAGE("name: " <<name);
+          }
+            
+          if (txt == "__BEGIN_ENTRY__") {  // __BEGIN_ENTRY__
+            isOK = (load >> entry);
+            isOK = (load >> txt); // __END_ENTRY__
+            if (txt != "__END_ENTRY__")
+              throw std::exception();
+            MESSAGE("entry: " << entry);
+          }
+            
+          if (txt == "__BEGIN_GROUP__") {  // __BEGIN_GROUP__
+            while (isOK && (txt != "__END_GROUP__")) {
+              isOK = (load >> txt);
+              if (txt != "__END_GROUP__") {
+                if (!groupName.empty())
+                  groupName += " ";
+                groupName += txt;
+              }
             }
+            MESSAGE("groupName: " << groupName);
+          }
+            
+          if (txt == "__BEGIN_COORDS__") {  // __BEGIN_COORDS__
+            hasCoords = true;
+            isOK = (load >> coords[0] >> coords[1] >> coords[2]);
+            isOK = (load >> txt); // __END_COORDS__
+            if (txt != "__END_COORDS__")
+              throw std::exception();
+            MESSAGE("coords: " << coords[0] <<","<< coords[1] <<","<< coords[2]);
+          } 
+            
+          if (txt == "__BEGIN_SIZE__") {  // __BEGIN_ENTRY__
+            isOK = (load >> size);
+            isOK = (load >> txt); // __END_ENTRY__
+            if (txt != "__END_SIZE__")
+              throw std::exception();
+            MESSAGE("size: " << size);
+          }
         }
+      }
     }
+  }
 
   return load;
 }
@@ -744,7 +1101,11 @@ bool GHS3DPlugin_Hypothesis::SetParametersByDefaults(const TDefaults&  /*dflts*/
 std::string GHS3DPlugin_Hypothesis::CommandToRun(const GHS3DPlugin_Hypothesis* hyp,
                                             const bool                    hasShapeToMesh)
 {
-  TCollection_AsciiString cmd( "ghs3d" );
+  TCollection_AsciiString cmd;
+  if (hasShapeToMesh)
+    cmd = "ghs3d-41"; // to use old mesh2 format
+  else
+    cmd = "ghs3d"; // to use new mesh format
   // check if any option is overridden by hyp->myTextOption
   bool m   = hyp ? ( hyp->myTextOption.find("-m")  == std::string::npos ) : true;
   bool M   = hyp ? ( hyp->myTextOption.find("-M")  == std::string::npos ) : true;
@@ -876,8 +1237,52 @@ std::string GHS3DPlugin_Hypothesis::GetFileName(const GHS3DPlugin_Hypothesis* hy
 */
 //================================================================================
 
-GHS3DPlugin_Hypothesis::TEnforcedVertexValues GHS3DPlugin_Hypothesis::GetEnforcedVertices(const GHS3DPlugin_Hypothesis* hyp)
+GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexList GHS3DPlugin_Hypothesis::GetEnforcedVertices(const GHS3DPlugin_Hypothesis* hyp)
+{
+  return hyp ? hyp->_GetEnforcedVertices():DefaultGHS3DEnforcedVertexList();
+}
+
+GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexCoordsValues GHS3DPlugin_Hypothesis::GetEnforcedVerticesCoordsSize (const GHS3DPlugin_Hypothesis* hyp)
+{  
+  return hyp ? hyp->_GetEnforcedVerticesCoordsSize(): DefaultGHS3DEnforcedVertexCoordsValues();
+}
+
+GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexEntryValues GHS3DPlugin_Hypothesis::GetEnforcedVerticesEntrySize (const GHS3DPlugin_Hypothesis* hyp)
+{  
+  return hyp ? hyp->_GetEnforcedVerticesEntrySize(): DefaultGHS3DEnforcedVertexEntryValues();
+}
+
+GHS3DPlugin_Hypothesis::TCoordsGHS3DEnforcedVertexMap GHS3DPlugin_Hypothesis::GetEnforcedVerticesByCoords (const GHS3DPlugin_Hypothesis* hyp)
+{  
+  return hyp ? hyp->_GetEnforcedVerticesByCoords(): DefaultCoordsGHS3DEnforcedVertexMap();
+}
+
+GHS3DPlugin_Hypothesis::TGeomEntryGHS3DEnforcedVertexMap GHS3DPlugin_Hypothesis::GetEnforcedVerticesByEntry (const GHS3DPlugin_Hypothesis* hyp)
+{  
+  return hyp ? hyp->_GetEnforcedVerticesByEntry(): DefaultGeomEntryGHS3DEnforcedVertexMap();
+}
+
+GHS3DPlugin_Hypothesis::TIDSortedNodeGroupMap GHS3DPlugin_Hypothesis::GetEnforcedNodes(const GHS3DPlugin_Hypothesis* hyp)
+{
+  return hyp ? hyp->_GetEnforcedNodes():DefaultIDSortedNodeGroupMap();
+}
+
+GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap GHS3DPlugin_Hypothesis::GetEnforcedEdges(const GHS3DPlugin_Hypothesis* hyp)
 {
-    return hyp ? hyp->_GetEnforcedVertices():DefaultEnforcedVertices();
+  return hyp ? hyp->_GetEnforcedEdges():DefaultIDSortedElemGroupMap();
 }
 
+GHS3DPlugin_Hypothesis::TIDSortedElemGroupMap GHS3DPlugin_Hypothesis::GetEnforcedTriangles(const GHS3DPlugin_Hypothesis* hyp)
+{
+  return hyp ? hyp->_GetEnforcedTriangles():DefaultIDSortedElemGroupMap();
+}
+
+GHS3DPlugin_Hypothesis::TID2SizeMap GHS3DPlugin_Hypothesis::GetNodeIDToSizeMap(const GHS3DPlugin_Hypothesis* hyp)
+{
+  return hyp ? hyp->_GetNodeIDToSizeMap(): DefaultID2SizeMap();
+}
+
+GHS3DPlugin_Hypothesis::TID2SizeMap GHS3DPlugin_Hypothesis::GetElementIDToSizeMap(const GHS3DPlugin_Hypothesis* hyp)
+{
+  return hyp ? hyp->_GetElementIDToSizeMap(): DefaultID2SizeMap();
+}
index 28fe2bb64b201c5d9c2c4e9a175bb3870b152353..481619f48ac6eaeb0b2e4e471a05a206a809afe7 100644 (file)
@@ -1,20 +1,20 @@
-//  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+// Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 //  GHS3DPlugin : C++ implementation
 
 #include "GHS3DPlugin_Defs.hxx"
 
-#include <SMESH_Hypothesis.hxx>
-#include <utilities.h>
+#include <SMDS_MeshNode.hxx>
+
+#include "SMESH_Hypothesis.hxx"
+#include "SMESH_Mesh_i.hxx"
+#include "SMESH_Gen_i.hxx"
+#include "SMESH_TypeDefs.hxx"
+#include "utilities.h"
 
 #include <stdexcept>
 #include <map>
@@ -41,6 +46,41 @@ public:
 
   GHS3DPlugin_Hypothesis(int hypId, int studyId, SMESH_Gen * gen);
 
+  typedef std::map<std::vector<double>,double> TGHS3DEnforcedVertexCoordsValues;
+  typedef std::map<std::string,double> TGHS3DEnforcedVertexEntryValues;
+  
+  struct TGHS3DEnforcedVertex {
+    std::string name;
+    std::string geomEntry;
+    std::vector<double> coords;
+    std::string groupName;
+    double size;
+  };
+  
+  struct CompareGHS3DEnforcedVertex {
+    bool operator () (const TGHS3DEnforcedVertex* e1, const TGHS3DEnforcedVertex* e2) const {
+      if (e1 && e2) {
+        if (e1->coords.size() && e2->coords.size())
+          return (e1->coords < e2->coords);
+        else
+          return (e1->geomEntry < e2->geomEntry);
+      }
+      return false;
+    }
+  };
+  typedef std::set< TGHS3DEnforcedVertex*, CompareGHS3DEnforcedVertex > TGHS3DEnforcedVertexList;
+  // Map Coords / Enforced node
+  typedef std::map< std::vector<double>, TGHS3DEnforcedVertex* > TCoordsGHS3DEnforcedVertexMap;
+  // Map geom entry / Enforced ndoe
+  typedef std::map< std::string, TGHS3DEnforcedVertex* > TGeomEntryGHS3DEnforcedVertexMap;
+  // Map groupName / Enforced ndoe
+  typedef std::map< std::string, TGHS3DEnforcedVertex* > TGroupNameGHS3DEnforcedVertexMap;
+  
+  typedef std::map<int,double> TID2SizeMap;
+  
+  typedef std::map<const SMDS_MeshElement*, std::string, TIDCompare > TIDSortedElemGroupMap;
+  typedef std::map<const SMDS_MeshNode*, std::string, TIDCompare > TIDSortedNodeGroupMap;
+  
   /*!
    * To mesh "holes" in a solid or not. Default is to mesh.
    */
@@ -114,16 +154,67 @@ public:
    */
   void SetTextOption(const std::string& option);
   std::string GetTextOption() const;
+    
+  
+//   struct TEnforcedEdge {
+//     long ID;
+//     long node1;
+//     long node2;
+//     std::string groupName;
+//   };
+  
+
+  /*!
+   * \brief Return command to run ghs3d mesher excluding file prefix (-f)
+   */
+  static std::string CommandToRun(const GHS3DPlugin_Hypothesis* hyp,
+                                  const bool                    hasShapeToMesh=true);
+  /*!
+   * \brief Return a unique file name
+   */
+  static std::string GetFileName(const GHS3DPlugin_Hypothesis* hyp);
+
   /*!
    * To set an enforced vertex
    */
-  typedef std::map<std::vector<double>,double> TEnforcedVertexValues;
-  void SetEnforcedVertex(double x, double y, double z, double size);
-  double GetEnforcedVertex(double x, double y, double z) throw (std::invalid_argument);
-  void RemoveEnforcedVertex(double x, double y, double z) throw (std::invalid_argument);
-  const TEnforcedVertexValues _GetEnforcedVertices() const { return myEnforcedVertices; }
+  bool SetEnforcedVertex(std::string aName, std::string anEntry, std::string aGroupName,
+                         double size, double x=0.0, double y=0.0, double z=0.0);
+  TGHS3DEnforcedVertex* GetEnforcedVertex(double x, double y, double z) throw (std::invalid_argument);
+  TGHS3DEnforcedVertex* GetEnforcedVertex(const std::string anEntry) throw (std::invalid_argument);
+  bool RemoveEnforcedVertex(double x=0.0, double y=0.0, double z=0.0, const std::string anEntry="" ) throw (std::invalid_argument);
+  const TGHS3DEnforcedVertexCoordsValues _GetEnforcedVerticesCoordsSize() const {return _enfVertexCoordsSizeList; }
+  const TGHS3DEnforcedVertexEntryValues  _GetEnforcedVerticesEntrySize() const {return _enfVertexEntrySizeList; }
+  const TGHS3DEnforcedVertexList         _GetEnforcedVertices() const { return _enfVertexList; }
+  const TCoordsGHS3DEnforcedVertexMap    _GetEnforcedVerticesByCoords() const { return _coordsEnfVertexMap; }
+  const TGeomEntryGHS3DEnforcedVertexMap _GetEnforcedVerticesByEntry() const { return _geomEntryEnfVertexMap; }
   void ClearEnforcedVertices();
 
+  /*!
+   * To set enforced elements
+   */
+  bool SetEnforcedMesh(SMESH_Mesh& theMesh, SMESH::ElementType elementType, double size, std::string groupName = "");
+  bool SetEnforcedGroup(const SMESHDS_Mesh* theMeshDS, SMESH::long_array_var theIDs, SMESH::ElementType elementType, double size, std::string groupName = "");
+  bool SetEnforcedElements(TIDSortedElemSet theElemSet, SMESH::ElementType elementType, double size, std::string groupName = "");
+  void ClearEnforcedMeshes();
+  const TIDSortedNodeGroupMap _GetEnforcedNodes() const { return _enfNodes; }
+  const TIDSortedElemGroupMap _GetEnforcedEdges() const { return _enfEdges; }
+  const TIDSortedElemGroupMap _GetEnforcedTriangles() const { return _enfTriangles; }
+  const TID2SizeMap _GetNodeIDToSizeMap() const {return _nodeIDToSizeMap; }
+  const TID2SizeMap _GetElementIDToSizeMap() const {return _elementIDToSizeMap; }
+  /*!
+   * \brief Return the enforced vertices
+   */
+  static TGHS3DEnforcedVertexList GetEnforcedVertices(const GHS3DPlugin_Hypothesis* hyp);
+  static TGHS3DEnforcedVertexCoordsValues GetEnforcedVerticesCoordsSize(const GHS3DPlugin_Hypothesis* hyp);
+  static TGHS3DEnforcedVertexEntryValues  GetEnforcedVerticesEntrySize(const GHS3DPlugin_Hypothesis* hyp);
+  static TCoordsGHS3DEnforcedVertexMap GetEnforcedVerticesByCoords(const GHS3DPlugin_Hypothesis* hyp);
+  static TGeomEntryGHS3DEnforcedVertexMap GetEnforcedVerticesByEntry(const GHS3DPlugin_Hypothesis* hyp);
+  static TIDSortedNodeGroupMap GetEnforcedNodes(const GHS3DPlugin_Hypothesis* hyp);
+  static TIDSortedElemGroupMap GetEnforcedEdges(const GHS3DPlugin_Hypothesis* hyp);
+  static TIDSortedElemGroupMap GetEnforcedTriangles(const GHS3DPlugin_Hypothesis* hyp);
+  static TID2SizeMap GetNodeIDToSizeMap(const GHS3DPlugin_Hypothesis* hyp);
+  static TID2SizeMap GetElementIDToSizeMap(const GHS3DPlugin_Hypothesis* hyp);
+  
   static bool   DefaultMeshHoles();
   static short  DefaultMaximumMemory();
   static short  DefaultInitialMemory();
@@ -135,22 +226,17 @@ public:
   static bool   DefaultToUseBoundaryRecoveryVersion();
   static bool   DefaultToUseFEMCorrection();
   static bool   DefaultToRemoveCentralPoint();
-  static TEnforcedVertexValues DefaultEnforcedVertices();
-
-  /*!
-   * \brief Return command to run ghs3d mesher excluding file prefix (-f)
-   */
-  static std::string CommandToRun(const GHS3DPlugin_Hypothesis* hyp,
-                                  const bool                    hasShapeToMesh=true);
-  /*!
-   * \brief Return a unique file name
-   */
-  static std::string GetFileName(const GHS3DPlugin_Hypothesis* hyp);
-  /*!
-   * \brief Return the enforced vertices
-   */
-  static TEnforcedVertexValues GetEnforcedVertices(const GHS3DPlugin_Hypothesis* hyp);
-
+  static TGHS3DEnforcedVertex DefaultGHS3DEnforcedVertex() {return TGHS3DEnforcedVertex();}
+  static TGHS3DEnforcedVertexList DefaultGHS3DEnforcedVertexList() {return TGHS3DEnforcedVertexList();}
+  static TGHS3DEnforcedVertexCoordsValues DefaultGHS3DEnforcedVertexCoordsValues() {return TGHS3DEnforcedVertexCoordsValues();}
+  static TGHS3DEnforcedVertexEntryValues DefaultGHS3DEnforcedVertexEntryValues() {return TGHS3DEnforcedVertexEntryValues();}
+  static TCoordsGHS3DEnforcedVertexMap DefaultCoordsGHS3DEnforcedVertexMap() {return TCoordsGHS3DEnforcedVertexMap();}
+  static TGeomEntryGHS3DEnforcedVertexMap DefaultGeomEntryGHS3DEnforcedVertexMap() {return TGeomEntryGHS3DEnforcedVertexMap();}
+  static TGroupNameGHS3DEnforcedVertexMap DefaultGroupNameGHS3DEnforcedVertexMap() {return TGroupNameGHS3DEnforcedVertexMap();}
+  static TIDSortedNodeGroupMap DefaultIDSortedNodeGroupMap() {return TIDSortedNodeGroupMap();}
+  static TIDSortedElemGroupMap DefaultIDSortedElemGroupMap() {return TIDSortedElemGroupMap();}
+  static TID2SizeMap DefaultID2SizeMap();
+  
   // Persistence
   virtual std::ostream & SaveTo(std::ostream & save);
   virtual std::istream & LoadFrom(std::istream & load);
@@ -181,8 +267,19 @@ private:
   bool   myToUseFemCorrection;
   bool   myToRemoveCentralPoint;
   std::string myTextOption;
-  TEnforcedVertexValues myEnforcedVertices;
-  
+  TGHS3DEnforcedVertexList _enfVertexList;
+  TGHS3DEnforcedVertexCoordsValues _enfVertexCoordsSizeList;
+  TGHS3DEnforcedVertexEntryValues _enfVertexEntrySizeList;
+  // map to get "manual" enf vertex (through the coordinates)
+  TCoordsGHS3DEnforcedVertexMap _coordsEnfVertexMap;
+  // map to get "geom" enf vertex (through the geom entries)
+  TGeomEntryGHS3DEnforcedVertexMap _geomEntryEnfVertexMap;
+  TIDSortedNodeGroupMap _enfNodes;
+  TIDSortedElemGroupMap _enfEdges;
+  TIDSortedElemGroupMap _enfTriangles;
+  TID2SizeMap _nodeIDToSizeMap;
+  TID2SizeMap _elementIDToSizeMap;
+  std::map<std::string, TIDSortedElemSet > _entryToElemsMap;
 };
 
 
index ff3953e3d1fda035db4dc22733064dde56c62a16..2e9a740042f7cf26ae1fe2de00b9511b8819b091 100644 (file)
@@ -1,20 +1,20 @@
-//  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+// Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 // File      : GHS3DPlugin_Hypothesis_i.cxx
 //
 #include "GHS3DPlugin_Hypothesis_i.hxx"
 
-#include <SMESH_Gen.hxx>
-#include <SMESH_PythonDump.hxx>
-
-#include <Utils_CorbaException.hxx>
-#include <utilities.h>
-#include <SMESH_Mesh_i.hxx>
-
+#include "SMESH_Gen.hxx"
+#include "SMESH_PythonDump.hxx"
+//#include "SMESH_Mesh.hxx"
+//#include "SMESH_ProxyMesh.hxx"
+//#include <StdMeshers_QuadToTriaAdaptor.hxx>
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+#include "SMESH_Mesh_i.hxx"
+#include "SMESH_Group_i.hxx"
+#include "SMESH_Gen_i.hxx"
+#include "SMESH_TypeDefs.hxx"
+#include "SMESHDS_GroupBase.hxx"
+
+#ifndef GHS3D_VERSION
+#define GHS3D_VERSION 41
+#endif
 //=======================================================================
 //function : GHS3DPlugin_Hypothesis_i
 //=======================================================================
@@ -341,11 +351,160 @@ char* GHS3DPlugin_Hypothesis_i::GetTextOption()
 //function : SetEnforcedVertex
 //=======================================================================
 
-void GHS3DPlugin_Hypothesis_i::SetEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z, CORBA::Double size)
-{
+bool GHS3DPlugin_Hypothesis_i::SetEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z, CORBA::Double size)
+    throw (SALOME::SALOME_Exception) {
+  ASSERT(myBaseImpl);
+  MESSAGE("IDL : SetEnforcedVertex( "<< x << ", " << y << ", " << z << ", " << size << ")");
+  return _SetEnforcedVertex(size, x, y, z);
+}
+
+bool GHS3DPlugin_Hypothesis_i::SetEnforcedVertexWithGroup(CORBA::Double x, CORBA::Double y, CORBA::Double z, CORBA::Double size, const char* theGroupName)
+    throw (SALOME::SALOME_Exception) {
+  ASSERT(myBaseImpl);
+  MESSAGE("IDL : SetEnforcedVertexWithGroup( "<< x << ", " << y << ", " << z << ", " << size << ", " << theGroupName << ")");
+  return _SetEnforcedVertex(size, x, y, z, "", "", theGroupName);
+}
+
+bool GHS3DPlugin_Hypothesis_i::SetEnforcedVertexGeom(GEOM::GEOM_Object_ptr theVertex, CORBA::Double size)
+    throw (SALOME::SALOME_Exception) {
   ASSERT(myBaseImpl);
-  this->GetImpl()->SetEnforcedVertex(x,y,z,size);
-  SMESH::TPythonDump() << _this() << ".SetEnforcedVertex( " << x << ", " << y << ", " << z << ", " << size  << " )";
+  
+  if ((theVertex->GetShapeType() != GEOM::VERTEX) && (theVertex->GetShapeType() != GEOM::COMPOUND)) {
+    MESSAGE("theVertex shape type is not VERTEX or COMPOUND");
+    THROW_SALOME_CORBA_EXCEPTION("theVertex shape type is not VERTEX or COMPOUND", SALOME::BAD_PARAM);
+  }
+  
+  string theVertexEntry = theVertex->GetStudyEntry();
+  if (theVertexEntry.empty()) {
+    GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine();
+    SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen();
+    string aName;
+    if (theVertex->GetShapeType() == GEOM::VERTEX)
+      aName = "Vertex_";
+    if (theVertex->GetShapeType() == GEOM::COMPOUND)
+      aName = "Compound_";
+    aName += theVertex->GetEntry();
+    SALOMEDS::SObject_ptr theSVertex = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theVertex, aName.c_str());
+    if (!theSVertex->_is_nil())
+      theVertexEntry = theSVertex->GetID();
+  }
+  if (theVertexEntry.empty())
+    THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM );
+
+  string theVertexName = theVertex->GetName();
+  MESSAGE("IDL : SetEnforcedVertexGeom( "<< theVertexEntry << ", " << size<< ")");
+  
+  return _SetEnforcedVertex(size, 0, 0, 0, theVertexName.c_str(), theVertexEntry.c_str());
+}
+
+bool GHS3DPlugin_Hypothesis_i::SetEnforcedVertexGeomWithGroup(GEOM::GEOM_Object_ptr theVertex, CORBA::Double size, const char* theGroupName)
+    throw (SALOME::SALOME_Exception) {
+  ASSERT(myBaseImpl);
+  
+  if ((theVertex->GetShapeType() != GEOM::VERTEX) && (theVertex->GetShapeType() != GEOM::COMPOUND)) {
+    MESSAGE("theVertex shape type is not VERTEX or COMPOUND");
+    THROW_SALOME_CORBA_EXCEPTION("theVertex shape type is not VERTEX or COMPOUND", SALOME::BAD_PARAM);
+  }
+  
+  string theVertexEntry = theVertex->GetStudyEntry();
+  if (theVertexEntry.empty()) {
+    GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine();
+    SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen();
+    string aName;
+    if (theVertex->GetShapeType() == GEOM::VERTEX)
+      aName = "Vertex_";
+    if (theVertex->GetShapeType() == GEOM::COMPOUND)
+      aName = "Compound_";
+    aName += theVertex->GetEntry();
+    SALOMEDS::SObject_ptr theSVertex = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theVertex, aName.c_str());
+    if (!theSVertex->_is_nil())
+      theVertexEntry = theSVertex->GetID();
+  }
+  if (theVertexEntry.empty())
+    THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM );
+
+  string theVertexName = theVertex->GetName();
+  MESSAGE("IDL : SetEnforcedVertexGeomWithGroup( "<< theVertexEntry << ", " << size<< ", " << theGroupName << ")");
+  
+  return _SetEnforcedVertex(size, 0, 0, 0, theVertexName.c_str(), theVertexEntry.c_str(), theGroupName);
+}
+
+bool GHS3DPlugin_Hypothesis_i:: _SetEnforcedVertex(CORBA::Double size, CORBA::Double x, CORBA::Double y, CORBA::Double z,
+                                                   const char* theVertexName, const char* theVertexEntry, const char* theGroupName)
+    throw (SALOME::SALOME_Exception) {
+  ASSERT(myBaseImpl);
+  MESSAGE("IDL : _SetEnforcedVertex(" << size << ", " << x << ", " << y << ", " << z << ", \"" << theVertexName << "\", \"" << theVertexEntry << "\", \"" << theGroupName << "\")");
+  bool newValue = false;
+
+  if (string(theVertexEntry).empty()) {
+    ::GHS3DPlugin_Hypothesis::TCoordsGHS3DEnforcedVertexMap coordsList = this->GetImpl()->_GetEnforcedVerticesByCoords();
+    std::vector<double> coords;
+    coords.push_back(x);
+    coords.push_back(y);
+    coords.push_back(z);
+    if (coordsList.find(coords) == coordsList.end()) {
+      MESSAGE("Coords not found: add it in coordsList");
+      newValue = true;
+    } else {
+      MESSAGE("Coords already found, compare names");
+      ::GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex *enfVertex = this->GetImpl()->GetEnforcedVertex(x, y, z);
+      if ((enfVertex->name != theVertexName) || (enfVertex->groupName != theGroupName) || (enfVertex->size != size)) {
+        MESSAGE("The names or size are different: update");
+//          this->GetImpl()->ClearEnforcedVertex(theFaceEntry, x, y, z);
+        newValue = true;
+      }
+      else {
+        MESSAGE("The names and size are identical");
+      }
+    }
+
+    if (newValue) {
+      if (string(theVertexName).empty()) {
+        if (string(theGroupName).empty())
+          SMESH::TPythonDump() << "isDone = " << _this() << ".SetEnforcedVertex(" << x << ", " << y << ", " << z << ", " << size << ")";
+        else
+          SMESH::TPythonDump() << "isDone = " << _this() << ".SetEnforcedVertexWithGroup(" << x << ", " << y << ", " << z << ", " << size << ", \"" << theGroupName << "\")";
+//       else
+//         if (string(theGroupName).empty())
+//           SMESH::TPythonDump() << _this() << ".SetEnforcedVertexNamed(" << theFaceEntry << ", " << x << ", " << y << ", " << z << ", \"" << theVertexName << "\")";
+//         else
+//           SMESH::TPythonDump() << _this() << ".SetEnforcedVertexNamedWithGroup(" << theFaceEntry << ", " << x << ", " << y << ", " << z << ", \"" 
+//                                           << theVertexName << "\", \"" << theGroupName << "\")";
+      }
+    }
+  } else {
+    ::GHS3DPlugin_Hypothesis::TGeomEntryGHS3DEnforcedVertexMap enfVertexEntryList = this->GetImpl()->_GetEnforcedVerticesByEntry();
+//     ::BLSURFPlugin_Hypothesis::TGeomEntryGHS3DEnforcedVertexMap::const_iterator it = enfVertexEntryList.find(theVertexEntry);
+    if ( enfVertexEntryList.find(theVertexEntry) == enfVertexEntryList.end()) {
+      MESSAGE("Geom entry not found: add it in enfVertexEntryList");
+      newValue = true;
+    }
+    else {
+      MESSAGE("Geom entry already found, compare names");
+      ::GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex *enfVertex = this->GetImpl()->GetEnforcedVertex(theVertexEntry);
+      if ((enfVertex->name != theVertexName) || (enfVertex->groupName != theGroupName) || (enfVertex->size != size)) {
+        MESSAGE("The names or size are different: update");
+//          this->GetImpl()->ClearEnforcedVertex(theFaceEntry, x, y, z);
+        newValue = true;
+      }
+      else {
+        MESSAGE("The names and size are identical");
+      }
+    }
+
+    if (newValue) {
+      if (string(theGroupName).empty())
+        SMESH::TPythonDump() << "isDone = " << _this() << ".SetEnforcedVertexGeom(" << theVertexEntry << ", " << size << ")";
+      else
+        SMESH::TPythonDump() << "isDone = " << _this() << ".SetEnforcedVertexGeomWithGroup(" << theVertexEntry << ", " << size << ", \"" << theGroupName << "\")";
+    }
+  }
+
+  if (newValue)
+    this->GetImpl()->SetEnforcedVertex(theVertexName, theVertexEntry, theGroupName, size, x, y, z);
+
+  MESSAGE("IDL : SetEnforcedVertexEntry END");
+  return newValue;
 }
 
 //=======================================================================
@@ -357,20 +516,72 @@ CORBA::Double GHS3DPlugin_Hypothesis_i::GetEnforcedVertex(CORBA::Double x, CORBA
 {
   ASSERT(myBaseImpl);
   try {
-    return this->GetImpl()->GetEnforcedVertex(x,y,z);
+    bool isDone = this->GetImpl()->GetEnforcedVertex(x,y,z)->size;
+    SMESH::TPythonDump() << "aSize = " << _this() << ".GetEnforcedVertex(" << x << ", " << y << ", " << z << ")";
+    return isDone;
+  }
+  catch (const std::invalid_argument& ex) {
+    SALOME::ExceptionStruct ExDescription;
+    ExDescription.text = ex.what();
+    ExDescription.type = SALOME::BAD_PARAM;
+    ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx";
+    ExDescription.lineNumber = 513;
+    throw SALOME::SALOME_Exception(ExDescription);
+  }
+  catch (SALOME_Exception& ex) {
+    THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM );
+  }
+}
+
+//=======================================================================
+//function : GetEnforcedVertex
+//=======================================================================
+
+CORBA::Double GHS3DPlugin_Hypothesis_i::GetEnforcedVertexGeom(GEOM::GEOM_Object_ptr theVertex)
+  throw (SALOME::SALOME_Exception)
+{
+  ASSERT(myBaseImpl);
+  
+  if ((theVertex->GetShapeType() != GEOM::VERTEX) && (theVertex->GetShapeType() != GEOM::COMPOUND)) {
+    MESSAGE("theVertex shape type is not VERTEX or COMPOUND");
+    THROW_SALOME_CORBA_EXCEPTION("theVertex shape type is not VERTEX or COMPOUND", SALOME::BAD_PARAM);
+  }
+  
+  string theVertexEntry = theVertex->GetStudyEntry();
+  if (theVertexEntry.empty()) {
+    GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine();
+    SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen();
+    string aName;
+    if (theVertex->GetShapeType() == GEOM::VERTEX)
+      aName = "Vertex_";
+    if (theVertex->GetShapeType() == GEOM::COMPOUND)
+      aName = "Compound_";
+    aName += theVertex->GetEntry();
+    SALOMEDS::SObject_ptr theSVertex = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theVertex, aName.c_str());
+    if (!theSVertex->_is_nil())
+      theVertexEntry = theSVertex->GetID();
+  }
+  if (theVertexEntry.empty())
+    THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM );
+
+  string theVertexName = theVertex->GetName();
+  
+  try {
+    bool isDone = this->GetImpl()->GetEnforcedVertex(theVertexName)->size;
+    SMESH::TPythonDump() << "aSize = " << _this() << ".GetEnforcedVertexGeom(" << theVertex << ")";
+    return isDone;
   }
   catch (const std::invalid_argument& ex) {
     SALOME::ExceptionStruct ExDescription;
     ExDescription.text = ex.what();
     ExDescription.type = SALOME::BAD_PARAM;
-    ExDescription.sourceFile = "GHS3DPlugin_Hypothesis::GetEnforcedVertex(x,y,z)";
-    ExDescription.lineNumber = 0;
+    ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx";
+    ExDescription.lineNumber = 538;
     throw SALOME::SALOME_Exception(ExDescription);
   }
   catch (SALOME_Exception& ex) {
     THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM );
   }
-  return 0;
 }
 
 //=======================================================================
@@ -382,21 +593,33 @@ GHS3DPlugin::GHS3DEnforcedVertexList* GHS3DPlugin_Hypothesis_i::GetEnforcedVerti
   ASSERT(myBaseImpl);
   GHS3DPlugin::GHS3DEnforcedVertexList_var result = new GHS3DPlugin::GHS3DEnforcedVertexList();
 
-  const ::GHS3DPlugin_Hypothesis::TEnforcedVertexValues sizeMaps = this->GetImpl()->_GetEnforcedVertices();
-  int size = sizeMaps.size();
-  result->length( size );
-
-  ::GHS3DPlugin_Hypothesis::TEnforcedVertexValues::const_iterator it;
-  int i = 0;
-  for (it = sizeMaps.begin() ; it != sizeMaps.end(); it++ ) {
-    GHS3DPlugin::GHS3DEnforcedVertex_var myVertex = new GHS3DPlugin::GHS3DEnforcedVertex();
-    myVertex->x = it->first[0];
-    myVertex->y = it->first[1];
-    myVertex->z = it->first[2];
-    myVertex->size = it->second;
-    result[i]=myVertex;
-    i++;
+  const ::GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexList enfVertexList = this->GetImpl()->_GetEnforcedVertices();
+  result->length( enfVertexList.size() );
+
+  ::GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertexList::const_iterator it = enfVertexList.begin();
+
+  for (int i = 0 ; it != enfVertexList.end(); ++it, ++i ) {
+    ::GHS3DPlugin_Hypothesis::TGHS3DEnforcedVertex* currentVertex = (*it);
+    GHS3DPlugin::GHS3DEnforcedVertex_var enfVertex = new GHS3DPlugin::GHS3DEnforcedVertex();
+    // Name
+    enfVertex->name = CORBA::string_dup(currentVertex->name.c_str());
+    // Geom Vertex Entry
+    enfVertex->geomEntry = CORBA::string_dup(currentVertex->geomEntry.c_str());
+    // Coords
+    GHS3DPlugin::TCoords_var coords = new GHS3DPlugin::TCoords();
+    coords->length(currentVertex->coords.size());
+    for (int ind = 0; ind < currentVertex->coords.size(); ind++)
+      coords[ind] = currentVertex->coords[ind];
+    enfVertex->coords = coords;
+    // Group Name
+    enfVertex->groupName = CORBA::string_dup(currentVertex->groupName.c_str());
+    // Size
+    enfVertex->size = currentVertex->size;
+    
+    result[i]=enfVertex;
     }
+  
+  SMESH::TPythonDump() << "allEnforcedVertices = " << _this() << ".GetEnforcedVertices()";
 
   return result._retn();
 }
@@ -405,20 +628,66 @@ GHS3DPlugin::GHS3DEnforcedVertexList* GHS3DPlugin_Hypothesis_i::GetEnforcedVerti
 //function : RemoveEnforcedVertex
 //=======================================================================
 
-void GHS3DPlugin_Hypothesis_i::RemoveEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z)
+bool GHS3DPlugin_Hypothesis_i::RemoveEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z)
   throw (SALOME::SALOME_Exception)
 {
   ASSERT(myBaseImpl);
   try {
-    this->GetImpl()->RemoveEnforcedVertex(x,y,z);
-    SMESH::TPythonDump() << _this() << ".RemoveEnforcedVertex( " << x << ", " << y << ", " << z << " )";
+    bool res = this->GetImpl()->RemoveEnforcedVertex(x,y,z);
+    SMESH::TPythonDump() << " isDone = " << _this() << ".RemoveEnforcedVertex( " << x << ", " << y << ", " << z << " )";
+    return res;
+  }
+  catch (const std::invalid_argument& ex) {
+    SALOME::ExceptionStruct ExDescription;
+    ExDescription.text = ex.what();
+    ExDescription.type = SALOME::BAD_PARAM;
+    ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx";
+    ExDescription.lineNumber = 625;
+    throw SALOME::SALOME_Exception(ExDescription);
+  }
+  catch (SALOME_Exception& ex) {
+    THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM );
+  }
+}
+
+bool GHS3DPlugin_Hypothesis_i::RemoveEnforcedVertexGeom(GEOM::GEOM_Object_ptr theVertex)
+  throw (SALOME::SALOME_Exception)
+{
+  ASSERT(myBaseImpl);
+  
+  if ((theVertex->GetShapeType() != GEOM::VERTEX) && (theVertex->GetShapeType() != GEOM::COMPOUND)) {
+    MESSAGE("theVertex shape type is not VERTEX or COMPOUND");
+    THROW_SALOME_CORBA_EXCEPTION("theVertex shape type is not VERTEX or COMPOUND", SALOME::BAD_PARAM);
+  }
+  
+  string theVertexEntry = theVertex->GetStudyEntry();
+  if (theVertexEntry.empty()) {
+    GEOM::GEOM_Gen_ptr geomGen = SMESH_Gen_i::GetGeomEngine();
+    SMESH_Gen_i *smeshGen = SMESH_Gen_i::GetSMESHGen();
+    string aName;
+    if (theVertex->GetShapeType() == GEOM::VERTEX)
+      aName = "Vertex_";
+    if (theVertex->GetShapeType() == GEOM::COMPOUND)
+      aName = "Compound_";
+    aName += theVertex->GetEntry();
+    SALOMEDS::SObject_ptr theSVertex = geomGen->PublishInStudy(smeshGen->GetCurrentStudy(), NULL, theVertex, aName.c_str());
+    if (!theSVertex->_is_nil())
+      theVertexEntry = theSVertex->GetID();
+  }
+  if (theVertexEntry.empty())
+    THROW_SALOME_CORBA_EXCEPTION( "Geom object is not published in study" ,SALOME::BAD_PARAM );
+  
+  try {
+    bool res = this->GetImpl()->RemoveEnforcedVertex(0,0,0, theVertexEntry.c_str());
+    SMESH::TPythonDump() << "isDone = " << _this() << ".RemoveEnforcedVertexGeom( " << theVertexEntry.c_str() << " )";
+    return res;
   }
   catch (const std::invalid_argument& ex) {
     SALOME::ExceptionStruct ExDescription;
     ExDescription.text = ex.what();
     ExDescription.type = SALOME::BAD_PARAM;
-    ExDescription.sourceFile = "GHS3DPlugin_Hypothesis::RemoveEnforcedVertex(x,y,z)";
-    ExDescription.lineNumber = 0;
+    ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx";
+    ExDescription.lineNumber = 648;
     throw SALOME::SALOME_Exception(ExDescription);
   }
   catch (SALOME_Exception& ex) {
@@ -434,8 +703,251 @@ void GHS3DPlugin_Hypothesis_i::ClearEnforcedVertices()
 {
   ASSERT(myBaseImpl);
   this->GetImpl()->ClearEnforcedVertices();
+  SMESH::TPythonDump () << _this() << ".ClearEnforcedVertices() ";
 }
 
+//=======================================================================
+//function : ClearEnforcedMeshes
+//=======================================================================
+
+void GHS3DPlugin_Hypothesis_i::ClearEnforcedMeshes()
+{
+  ASSERT(myBaseImpl);
+  this->GetImpl()->ClearEnforcedMeshes();
+  SMESH::TPythonDump () << _this() << ".ClearEnforcedMeshes() ";
+}
+
+/*!
+ * \brief Adds enforced elements of type elementType using another mesh/sub-mesh/mesh group theSource. The elements will be grouped in theGroupName.
+ */
+bool GHS3DPlugin_Hypothesis_i::SetEnforcedMeshWithGroup(SMESH::SMESH_IDSource_ptr theSource, SMESH::ElementType theType, const char* theGroupName)
+  throw (SALOME::SALOME_Exception)
+{
+#if GHS3D_VERSION >= 42
+  bool res = _SetEnforcedMesh(theSource, theType, -1.0, theGroupName);
+  SMESH_Mesh_i* theMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( theSource);
+  SMESH_Group_i* theGroup_i = SMESH::DownCast<SMESH_Group_i*>( theSource);
+  SMESH_GroupOnGeom_i* theGroupOnGeom_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( theSource);
+  if (theGroup_i or theGroupOnGeom_i)
+  {
+    SMESH::TPythonDump () << "isDone = " << _this() << ".SetEnforcedMeshWithGroup( " 
+                          << theSource << ", " << theType << ", \"" << theGroupName << "\" )";
+  }
+  else if (theMesh_i)
+  {
+    SMESH::TPythonDump () << "isDone = " << _this() << ".SetEnforcedMeshWithGroup( " 
+                          << theSource << ".GetMesh(), " << theType << ", \"" << theGroupName << "\" )";
+  }
+  return res;
+#else
+  SALOME::ExceptionStruct ExDescription;
+  ExDescription.text = "Bad version of GHS3D. It must >= 4.2.";
+  ExDescription.type = SALOME::BAD_PARAM;
+  ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx";
+  ExDescription.lineNumber = 719;
+  throw SALOME::SALOME_Exception(ExDescription);
+#endif
+}
+
+/*!
+ * \brief Adds enforced elements of type elementType using another mesh/sub-mesh/mesh group theSource.
+ */
+bool GHS3DPlugin_Hypothesis_i::SetEnforcedMesh(SMESH::SMESH_IDSource_ptr theSource, SMESH::ElementType theType)
+  throw (SALOME::SALOME_Exception)
+{
+  MESSAGE("GHS3DPlugin_Hypothesis_i::SetEnforcedMesh");
+#if GHS3D_VERSION >= 42
+  bool res = _SetEnforcedMesh(theSource, theType, -1.0);
+  SMESH_Mesh_i* theMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( theSource);
+  SMESH_Group_i* theGroup_i = SMESH::DownCast<SMESH_Group_i*>( theSource);
+  SMESH_GroupOnGeom_i* theGroupOnGeom_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( theSource);
+  if (theGroup_i or theGroupOnGeom_i)
+  {
+    SMESH::TPythonDump () << "isDone = " << _this() << ".SetEnforcedMesh( " 
+                          << theSource << ", " << theType << " )";
+  }
+  else if (theMesh_i)
+  {
+    SMESH::TPythonDump () << "isDone = " << _this() << ".SetEnforcedMesh( " 
+                          << theSource << ".GetMesh(), " << theType << " )";
+  }
+  return res;
+#else
+  SALOME::ExceptionStruct ExDescription;
+  ExDescription.text = "Bad version of GHS3D. It must >= 4.2.";
+  ExDescription.type = SALOME::BAD_PARAM;
+  ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx";
+  ExDescription.lineNumber = 750;
+  throw SALOME::SALOME_Exception(ExDescription);
+#endif
+}
+
+/*!
+ * \brief Adds enforced elements of type elementType using another mesh/sub-mesh/mesh group theSource and a size. The elements will be grouped in theGroupName.
+ */
+bool GHS3DPlugin_Hypothesis_i::SetEnforcedMeshSizeWithGroup(SMESH::SMESH_IDSource_ptr theSource, SMESH::ElementType theType, double theSize, const char* theGroupName)
+  throw (SALOME::SALOME_Exception)
+{
+  if (theSize <= 0) {
+    SALOME::ExceptionStruct ExDescription;
+    ExDescription.text = "Size cannot be negative";
+    ExDescription.type = SALOME::BAD_PARAM;
+    ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx";
+    ExDescription.lineNumber = 781;
+    throw SALOME::SALOME_Exception(ExDescription);
+  }
+  
+  bool res = _SetEnforcedMesh(theSource, theType, theSize,theGroupName);
+  SMESH_Mesh_i* theMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( theSource);
+  SMESH_Group_i* theGroup_i = SMESH::DownCast<SMESH_Group_i*>( theSource);
+  SMESH_GroupOnGeom_i* theGroupOnGeom_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( theSource);
+  if (theGroup_i or theGroupOnGeom_i)
+  {
+    SMESH::TPythonDump () << "isDone = " << _this() << ".SetEnforcedMeshSizeWithGroup( " 
+                          << theSource << ", " << theType << ", " << theSize << ", \"" << theGroupName << "\" )";
+  }
+  else if (theMesh_i)
+  {
+    SMESH::TPythonDump () << "isDone = " << _this() << ".SetEnforcedMeshSizeWithGroup( " 
+                          << theSource << ".GetMesh(), " << theType << ", " << theSize << ", \"" << theGroupName << "\" )";
+  }
+  return res;
+}
+
+/*!
+ * \brief Adds enforced elements of type elementType using another mesh/sub-mesh/mesh group theSource and a size.
+ */
+bool GHS3DPlugin_Hypothesis_i::SetEnforcedMeshSize(SMESH::SMESH_IDSource_ptr theSource, SMESH::ElementType theType, double theSize)
+  throw (SALOME::SALOME_Exception)
+{
+  if (theSize <= 0) {
+    SALOME::ExceptionStruct ExDescription;
+    ExDescription.text = "Size cannot be negative";
+    ExDescription.type = SALOME::BAD_PARAM;
+    ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx";
+    ExDescription.lineNumber = 812;
+    throw SALOME::SALOME_Exception(ExDescription);
+  }
+  
+  bool res = _SetEnforcedMesh(theSource, theType, theSize);
+  SMESH_Mesh_i* theMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( theSource);
+  SMESH_Group_i* theGroup_i = SMESH::DownCast<SMESH_Group_i*>( theSource);
+  SMESH_GroupOnGeom_i* theGroupOnGeom_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( theSource);
+  if (theGroup_i or theGroupOnGeom_i)
+  {
+    SMESH::TPythonDump () << "isDone = " << _this() << ".SetEnforcedMeshSize( " 
+                          << theSource << ", " << theType << ", " << theSize << " )";
+  }
+  else if (theMesh_i)
+  {
+    SMESH::TPythonDump () << "isDone = " << _this() << ".SetEnforcedMeshSize( " 
+                          << theSource << ".GetMesh(), " << theType << ", " << theSize << " )";
+  }
+  return res;
+}
+
+bool GHS3DPlugin_Hypothesis_i::_SetEnforcedMesh(SMESH::SMESH_IDSource_ptr theSource, SMESH::ElementType theType, double theSize, const char* theGroupName)
+  throw (SALOME::SALOME_Exception)
+{
+  MESSAGE("GHS3DPlugin_Hypothesis_i::_SetEnforcedMesh");
+  ASSERT(myBaseImpl);
+  
+  if (CORBA::is_nil( theSource ))
+  {
+    SALOME::ExceptionStruct ExDescription;
+    ExDescription.text = "The source mesh CORBA object is NULL";
+    ExDescription.type = SALOME::BAD_PARAM;
+    ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx";
+    ExDescription.lineNumber = 840;
+    throw SALOME::SALOME_Exception(ExDescription);
+  }
+  
+  if ((theType != SMESH::NODE) && (theType != SMESH::EDGE) && (theType != SMESH::FACE))
+  {
+    return false;
+//     SALOME::ExceptionStruct ExDescription;
+//     ExDescription.text = "Bad elementType";
+//     ExDescription.type = SALOME::BAD_PARAM;
+//     ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx";
+//     ExDescription.lineNumber = 840;
+//     throw SALOME::SALOME_Exception(ExDescription);
+  }
+  
+  SMESH::array_of_ElementType_var types = theSource->GetTypes();
+  MESSAGE("Required type is "<<theType);
+  MESSAGE("Available types:");
+  for (int i=0;i<types->length();i++){MESSAGE(types[i]);}
+  if ( types->length() >= 1 && types[types->length()-1] <  theType)
+  {
+    return false;
+//     SALOME::ExceptionStruct ExDescription;
+//     ExDescription.text = "The source mesh has bad type";
+//     ExDescription.type = SALOME::BAD_PARAM;
+//     ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx";
+//     ExDescription.lineNumber = 840;
+//     throw SALOME::SALOME_Exception(ExDescription);
+  }
+  
+  SMESH_Mesh_i* theMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( theSource);
+  SMESH_Group_i* theGroup_i = SMESH::DownCast<SMESH_Group_i*>( theSource);
+  SMESH_GroupOnGeom_i* theGroupOnGeom_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( theSource);
+  TIDSortedElemSet theElemSet;
+
+  if (theMesh_i)
+  {
+    try {
+      return this->GetImpl()->SetEnforcedMesh(theMesh_i->GetImpl(), theType, theSize, theGroupName);
+    }
+    catch (const std::invalid_argument& ex) {
+      SALOME::ExceptionStruct ExDescription;
+      ExDescription.text = ex.what();
+      ExDescription.type = SALOME::BAD_PARAM;
+      ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx";
+      ExDescription.lineNumber = 840;
+      throw SALOME::SALOME_Exception(ExDescription);
+    }
+    catch (SALOME_Exception& ex) {
+      THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM );
+    }
+  }
+  else if (theGroup_i && types->length() == 1 && types[0] == theType)
+  {
+    MESSAGE("The source is a group")
+    try {
+      return this->GetImpl()->SetEnforcedGroup(theGroup_i->GetGroupDS()->GetMesh(),theGroup_i->GetListOfID(), theType, theSize, theGroupName);
+    }
+    catch (const std::invalid_argument& ex) {
+      SALOME::ExceptionStruct ExDescription;
+      ExDescription.text = ex.what();
+      ExDescription.type = SALOME::BAD_PARAM;
+      ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx";
+      ExDescription.lineNumber = 840;
+      throw SALOME::SALOME_Exception(ExDescription);
+    }
+    catch (SALOME_Exception& ex) {
+      THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM );
+    }
+  }
+  else if (theGroupOnGeom_i && types->length() == 1 && types[0] == theType)
+  {
+    MESSAGE("The source is a group on geom")
+    try {
+      return this->GetImpl()->SetEnforcedGroup(theGroupOnGeom_i->GetGroupDS()->GetMesh(),theGroupOnGeom_i->GetListOfID(), theType, theSize, theGroupName);
+    }
+    catch (const std::invalid_argument& ex) {
+      SALOME::ExceptionStruct ExDescription;
+      ExDescription.text = ex.what();
+      ExDescription.type = SALOME::BAD_PARAM;
+      ExDescription.sourceFile = "GHS3DPlugin_Hypothesis_i.cxx";
+      ExDescription.lineNumber = 840;
+      throw SALOME::SALOME_Exception(ExDescription);
+    }
+    catch (SALOME_Exception& ex) {
+      THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM );
+    }
+  }
+  return false;
+}
 //=============================================================================
 /*!
  *  Get implementation
index 0cf9a26606649d196b30b49cc5c604008509775f..3e5597a5303e30bc31804fc9247f7f78096ad568 100644 (file)
@@ -1,20 +1,20 @@
-//  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+// Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 //  GHS3DPlugin : C++ implementation
@@ -31,6 +31,7 @@
 #include CORBA_SERVER_HEADER(GHS3DPlugin_Algorithm)
 
 #include "SMESH_Hypothesis_i.hxx"
+#include "SMESH_Mesh_i.hxx"
 #include "GHS3DPlugin_Hypothesis.hxx"
 
 class SMESH_Gen;
@@ -124,17 +125,37 @@ class GHS3DPLUGIN_EXPORT GHS3DPlugin_Hypothesis_i:
   /*!
    * To set an enforced vertex
    */
-  void SetEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z, CORBA::Double size);
+  bool _SetEnforcedVertex(CORBA::Double size, CORBA::Double x = 0, CORBA::Double y = 0, CORBA::Double z = 0,
+                          const char* theVertexName = "", const char* theVertexEntry = "", const char* theGroupName = "")
+      throw (SALOME::SALOME_Exception);
+  bool SetEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z, CORBA::Double size) throw (SALOME::SALOME_Exception);
+  bool SetEnforcedVertexWithGroup(CORBA::Double x, CORBA::Double y, CORBA::Double z, CORBA::Double size, const char* theGroupName) throw (SALOME::SALOME_Exception);
+  bool SetEnforcedVertexGeom(GEOM::GEOM_Object_ptr theVertex, CORBA::Double size) throw (SALOME::SALOME_Exception); // TODO
+  bool SetEnforcedVertexGeomWithGroup(GEOM::GEOM_Object_ptr theVertex, CORBA::Double size, const char* theGroupName) throw (SALOME::SALOME_Exception); // TODO
   CORBA::Double GetEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z) throw (SALOME::SALOME_Exception);
-  void RemoveEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z) throw (SALOME::SALOME_Exception);
+  CORBA::Double GetEnforcedVertexGeom(GEOM::GEOM_Object_ptr theVertex) throw (SALOME::SALOME_Exception); // TODO
+  bool RemoveEnforcedVertex(CORBA::Double x, CORBA::Double y, CORBA::Double z) throw (SALOME::SALOME_Exception);
+  bool RemoveEnforcedVertexGeom(GEOM::GEOM_Object_ptr theVertex) throw (SALOME::SALOME_Exception); // TODO
   GHS3DPlugin::GHS3DEnforcedVertexList* GetEnforcedVertices();
   void ClearEnforcedVertices();
+  /*!
+   * To set an enforced mesh
+   */
+  bool SetEnforcedMesh(SMESH::SMESH_IDSource_ptr theSource, SMESH::ElementType elementType) throw (SALOME::SALOME_Exception);
+  bool SetEnforcedMeshWithGroup(SMESH::SMESH_IDSource_ptr theSource, SMESH::ElementType elementType, const char* theGroupName) throw (SALOME::SALOME_Exception);
+  bool SetEnforcedMeshSize(SMESH::SMESH_IDSource_ptr theSource, SMESH::ElementType elementType, double size) throw (SALOME::SALOME_Exception);
+  bool SetEnforcedMeshSizeWithGroup(SMESH::SMESH_IDSource_ptr theSource, SMESH::ElementType elementType, double size, const char* theGroupName) throw (SALOME::SALOME_Exception);
+  void ClearEnforcedMeshes();
 
   // Get implementation
   ::GHS3DPlugin_Hypothesis* GetImpl();
   
   // Verify whether hypothesis supports given entity type 
   CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+  
+  private:
+  
+  bool _SetEnforcedMesh(SMESH::SMESH_IDSource_ptr theSource, SMESH::ElementType elementType, double size, const char* theGroupName="") throw (SALOME::SALOME_Exception);
 };
 
 #endif
index f1dbdfbbe39d67cb2789b6eb84d05c7663c027c3..47b61158e3f0fc97b810f0d49e7ca6279ef8ca96 100644 (file)
@@ -1,20 +1,20 @@
-//  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+// Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 //  SMESH GHS3DPlugin : implementaion of SMESH idl descriptions
index 28751997741112da0836d41051ec9bceccee53e8..9ecba31e376a20fde1753740dcdb3824366cae8d 100644 (file)
@@ -1,20 +1,20 @@
-#  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+# Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 #
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Lesser General Public
-#  License as published by the Free Software Foundation; either
-#  version 2.1 of the License.
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
 #
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Lesser General Public License for more details.
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
 #
-#  You should have received a copy of the GNU Lesser General Public
-#  License along with this library; if not, write to the Free Software
-#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #
-#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
 # -* Makefile *- 
@@ -27,6 +27,7 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
 # header files 
 salomeinclude_HEADERS = \
+       libmesh5.h \
        GHS3DPlugin_Defs.hxx \
        GHS3DPlugin_GHS3D.hxx \
        GHS3DPlugin_GHS3D_i.hxx \
@@ -37,6 +38,7 @@ salomeinclude_HEADERS = \
 lib_LTLIBRARIES = libGHS3DEngine.la
 
 dist_libGHS3DEngine_la_SOURCES = \
+  libmesh5.c \
   GHS3DPlugin_GHS3D.cxx \
   GHS3DPlugin_GHS3D_i.cxx \
   GHS3DPlugin_i.cxx \
diff --git a/src/GHS3DPlugin/libmesh5.c b/src/GHS3DPlugin/libmesh5.c
new file mode 100644 (file)
index 0000000..4277b97
--- /dev/null
@@ -0,0 +1,1192 @@
+
+
+/*----------------------------------------------------------*/
+/*                                                                                                                     */
+/*                                             LIBMESH V 5.45                                          */
+/*                                                                                                                     */
+/*----------------------------------------------------------*/
+/*                                                                                                                     */
+/*     Description:            handle .meshb file format I/O           */
+/*     Author:                         Loic MARECHAL                                           */
+/*     Creation date:          feb 16 2007                                                     */
+/*     Last modification:      feb 08 2011                                                     */
+/*                                                                                                                     */
+/*----------------------------------------------------------*/
+
+
+/*----------------------------------------------------------*/
+/* Includes                                                                                                    */
+/*----------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+#include <math.h>
+#include <ctype.h>
+#include "libmesh5.h"
+
+
+/*----------------------------------------------------------*/
+/* Defines                                                                                                     */
+/*----------------------------------------------------------*/
+
+#define Asc 1
+#define Bin 2
+#define MshFil 4
+#define SolFil 8
+#define MaxMsh 100
+#define InfKwd 1
+#define RegKwd 2
+#define SolKwd 3
+#define WrdSiz 4
+#define BufSiz 10000
+
+
+/*----------------------------------------------------------*/
+/* Structures                                                                                          */
+/*----------------------------------------------------------*/
+
+typedef struct
+{
+       int typ, SolSiz, NmbWrd, NmbLin, NmbTyp, TypTab[ GmfMaxTyp ];
+       long pos;
+       char fmt[ GmfMaxTyp*9 ];
+}KwdSct;
+
+typedef struct
+{
+       int dim, ver, mod, typ, cod, pos;
+       long NexKwdPos;
+       KwdSct KwdTab[ GmfMaxKwd + 1 ];
+       FILE *hdl;
+       int *IntBuf;
+       float *FltBuf;
+       unsigned char *buf;
+       char FilNam[ GmfStrSiz ];
+       double DblBuf[1000/8];
+       unsigned char blk[ BufSiz + 1000 ];
+}GmfMshSct;
+
+
+/*----------------------------------------------------------*/
+/* Global variables                                                                                    */
+/*----------------------------------------------------------*/
+
+int GmfIniFlg=0;
+GmfMshSct *GmfMshTab[ MaxMsh + 1 ];
+char *GmfKwdFmt[ GmfMaxKwd + 1 ][4] = 
+{      {"Reserved", "", "", ""},
+       {"MeshVersionFormatted", "", "", "i"},
+       {"Reserved", "", "", ""},
+       {"Dimension", "", "", "i"},
+       {"Vertices", "Vertex", "i", "dri"},
+       {"Edges", "Edge", "i", "iii"},
+       {"Triangles", "Triangle", "i", "iiii"},
+       {"Quadrilaterals", "Quadrilateral", "i", "iiiii"},
+       {"Tetrahedra", "Tetrahedron", "i", "iiiii"},
+       {"Prisms", "Prism", "i", "iiiiiii"},
+       {"Hexahedra", "Hexahedron", "i", "iiiiiiiii"},
+       {"IterationsAll", "IterationAll","","i"},
+       {"TimesAll", "TimeAll","","r"},                                 
+       {"Corners", "Corner", "i", "i"},
+       {"Ridges", "Ridge", "i", "i"},
+       {"RequiredVertices", "RequiredVertex", "i", "i"},
+       {"RequiredEdges", "RequiredEdge", "i", "i"},
+       {"RequiredTriangles", "RequiredTriangle", "i", "i"},
+       {"RequiredQuadrilaterals", "RequiredQuadrilateral", "i", "i"},
+       {"TangentAtEdgeVertices", "TangentAtEdgeVertex", "i", "iii"},
+       {"NormalAtVertices", "NormalAtVertex", "i", "ii"},
+       {"NormalAtTriangleVertices", "NormalAtTriangleVertex", "i", "iii"},
+       {"NormalAtQuadrilateralVertices", "NormalAtQuadrilateralVertex", "i", "iiii"},
+       {"AngleOfCornerBound", "", "", "r"},
+       {"TrianglesP2", "TriangleP2", "i", "iiiiiii"},
+       {"EdgesP2", "EdgeP2", "i", "iiii"},
+       {"SolAtPyramids", "SolAtPyramid", "i", "sr"},
+       {"QuadrilateralsQ2", "QuadrilateralQ2", "i", "iiiiiiiiii"},
+       {"ISolAtPyramids", "ISolAtPyramid", "i", "iiiii"},
+       {"Reserved", "", "", ""},
+       {"TetrahedraP2", "TetrahedronP2", "i", "iiiiiiiiiii"},
+       {"Reserved", "", "", ""},
+       {"Reserved", "", "", ""},
+       {"HexahedraQ2", "HexahedronQ2", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiii"},
+       {"Reserved", "", "", ""},
+       {"Reserved", "", "", ""},
+       {"Reserved", "", "", ""},
+       {"Reserved", "", "", ""},
+       {"Reserved", "", "", ""},
+       {"Reserved", "", "", ""},
+       {"Reserved", "", "", ""},
+       {"Reserved", "", "", ""},
+       {"Reserved", "", "", ""},
+       {"Reserved", "", "", ""},
+       {"Reserved", "", "", ""},
+       {"Reserved", "", "", ""},
+       {"Polyhedra", "Polyhedron", "i", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"},
+       {"Polygons", "Polygon", "", "iiiiiiiii"},
+       {"Reserved", "", "", ""},
+       {"Pyramids", "Pyramid", "i", "iiiiii"},
+       {"BoundingBox", "", "", "drdr"},
+       {"Body","i", "drdrdrdr"},
+       {"PrivateTable", "PrivateTable", "i", "i"},
+       {"Reserved", "", "", ""},
+       {"End", "", "", ""},
+       {"Reserved", "", "", ""},
+       {"Reserved", "", "", ""},
+       {"Reserved", "", "", ""},
+       {"Reserved", "", "", ""},
+       {"Tangents", "Tangent", "i", "dr"},
+       {"Normals", "Normal", "i", "dr"},
+       {"TangentAtVertices", "TangentAtVertex", "i", "ii"},
+       {"SolAtVertices", "SolAtVertex", "i", "sr"},
+       {"SolAtEdges", "SolAtEdge", "i", "sr"},
+       {"SolAtTriangles", "SolAtTriangle", "i", "sr"},
+       {"SolAtQuadrilaterals", "SolAtQuadrilateral", "i", "sr"},
+       {"SolAtTetrahedra", "SolAtTetrahedron", "i", "sr"},
+       {"SolAtPrisms", "SolAtPrism", "i", "sr"},
+       {"SolAtHexahedra", "SolAtHexahedron", "i", "sr"},
+       {"DSolAtVertices", "DSolAtVertex", "i", "sr"},
+       {"ISolAtVertices", "ISolAtVertex", "i", "i"},
+       {"ISolAtEdges", "ISolAtEdge", "i", "ii"},
+       {"ISolAtTriangles", "ISolAtTriangle", "i", "iii"},
+       {"ISolAtQuadrilaterals", "ISolAtQuadrilateral", "i", "iiii"},
+       {"ISolAtTetrahedra", "ISolAtTetrahedron", "i", "iiii"},
+       {"ISolAtPrisms", "ISolAtPrism", "i", "iiiiii"},
+       {"ISolAtHexahedra", "ISolAtHexahedron", "i", "iiiiiiii"},
+       {"Iterations", "","","i"},
+       {"Time", "","","r"},
+       {"Reserved", "","",""}
+ };
+
+
+/*----------------------------------------------------------*/
+/* Prototypes of local procedures                                                      */
+/*----------------------------------------------------------*/
+
+static void ScaWrd(GmfMshSct *, unsigned char *);
+static void ScaDblWrd(GmfMshSct *, unsigned char *);
+static void ScaBlk(GmfMshSct *, unsigned char *, int);
+static long GetPos(GmfMshSct *);
+static void RecWrd(GmfMshSct *, unsigned char *);
+static void RecDblWrd(GmfMshSct *, unsigned char *);
+static void RecBlk(GmfMshSct *, unsigned char *, int);
+static void SetPos(GmfMshSct *, long);
+static int ScaKwdTab(GmfMshSct *);
+static void ExpFmt(GmfMshSct *, int);
+static void ScaKwdHdr(GmfMshSct *, int);
+
+
+/*----------------------------------------------------------*/
+/* Open a mesh file in read or write mod                                       */
+/*----------------------------------------------------------*/
+
+int GmfOpenMesh(const char *FilNam, int mod, ...)
+{
+       int i, KwdCod, res, *PtrVer, *PtrDim, MshIdx=0;
+       char str[ GmfStrSiz ];
+       va_list VarArg;
+       GmfMshSct *msh;
+
+       if(!GmfIniFlg)
+       {
+               for(i=0;i<=MaxMsh;i++)
+                       GmfMshTab[i] = NULL;
+
+               GmfIniFlg = 1;
+       }
+
+       /*---------------------*/
+       /* MESH STRUCTURE INIT */
+       /*---------------------*/
+
+       for(i=1;i<=MaxMsh;i++)
+               if(!GmfMshTab[i])
+               {
+                       MshIdx = i;
+                       break;
+               }
+
+       if( !MshIdx || !(msh = calloc(1, sizeof(GmfMshSct))) )
+               return(0);
+
+       /* Copy the FilNam into the structure */
+
+       if(strlen(FilNam) + 7 >= GmfStrSiz)
+               return(0);
+
+       strcpy(msh->FilNam, FilNam);
+
+       /* Store the opening mod (read or write) and guess the filetype (binary or ascii) depending on the extension */
+
+       msh->mod = mod;
+       msh->buf = (void *)msh->DblBuf;
+       msh->FltBuf = (void *)msh->DblBuf;
+       msh->IntBuf = (void *)msh->DblBuf;
+
+       if(strstr(msh->FilNam, ".meshb"))
+               msh->typ |= (Bin | MshFil);
+       else if(strstr(msh->FilNam, ".mesh"))
+               msh->typ |= (Asc | MshFil);
+       else if(strstr(msh->FilNam, ".solb"))
+               msh->typ |= (Bin | SolFil);
+       else if(strstr(msh->FilNam, ".sol"))
+               msh->typ |= (Asc | SolFil);
+       else
+               return(0);
+
+       /* Open the file in the required mod and initialyse the mesh structure */
+
+       if(msh->mod == GmfRead)
+       {
+
+               /*-----------------------*/
+               /* OPEN FILE FOR READING */
+               /*-----------------------*/
+
+               va_start(VarArg, mod);
+               PtrVer = va_arg(VarArg, int *);
+               PtrDim = va_arg(VarArg, int *);
+               va_end(VarArg);
+
+               /* Create the name string and open the file */
+
+               if(!(msh->hdl = fopen(msh->FilNam, "rb")))
+                       return(0);
+
+               /* Read the endian coding tag, the mesh version and the mesh dimension (mandatory kwd) */
+
+               if(msh->typ & Bin)
+               {
+                       fread((unsigned char *)&msh->cod, WrdSiz, 1, msh->hdl);
+
+                       if( (msh->cod != 1) && (msh->cod != 16777216) )
+                               return(0);
+
+                       ScaWrd(msh, (unsigned char *)&msh->ver);
+
+                       if( (msh->ver < 1) || (msh->ver > 3) )
+                               return(0);
+
+                       if( (msh->ver == 3) && (sizeof(long) == 4) )
+                               return(0);
+
+                       ScaWrd(msh, (unsigned char *)&KwdCod);
+
+                       if(KwdCod != GmfDimension)
+                               return(0);
+
+                       GetPos(msh);
+                       ScaWrd(msh, (unsigned char *)&msh->dim);
+               }
+               else
+               {
+                       do
+                       {
+                               res = fscanf(msh->hdl, "%s", str);
+                       }while( (res != EOF) && strcmp(str, "MeshVersionFormatted") );
+
+                       if(res == EOF)
+                               return(0);
+
+                       fscanf(msh->hdl, "%d", &msh->ver);
+
+                       if( (msh->ver < 1) || (msh->ver > 3) )
+                               return(0);
+
+                       do
+                       {
+                               res = fscanf(msh->hdl, "%s", str);
+                       }while( (res != EOF) && strcmp(str, "Dimension") );
+
+                       if(res == EOF)
+                               return(0);
+
+                       fscanf(msh->hdl, "%d", &msh->dim);
+               }
+
+               if( (msh->dim != 2) && (msh->dim != 3) )
+                       return(0);
+
+               (*PtrVer) = msh->ver;
+               (*PtrDim) = msh->dim;
+
+               /*------------*/
+               /* KW READING */
+               /*------------*/
+
+               /* Read the list of kw present in the file */
+
+               if(!ScaKwdTab(msh))
+                       return(0);
+
+               GmfMshTab[ MshIdx ] = msh;
+
+               return(MshIdx);
+       }
+       else if(msh->mod == GmfWrite)
+       {
+
+               /*-----------------------*/
+               /* OPEN FILE FOR WRITING */
+               /*-----------------------*/
+
+               msh->cod = 1;
+
+               /* Check if the user provided a valid version number and dimension */
+
+               va_start(VarArg, mod);
+               msh->ver = va_arg(VarArg, int);
+               msh->dim = va_arg(VarArg, int);
+               va_end(VarArg);
+
+               if( (msh->ver < 1) || (msh->ver > 3) )
+                       return(0);
+
+               if( (msh->ver == 3) && (sizeof(long) == 4) )
+                       return(0);
+
+               if( (msh->dim != 2) && (msh->dim != 3) )
+                       return(0);
+
+               /* Create the mesh file */
+
+               if(!(msh->hdl = fopen(msh->FilNam, "wb")))
+                       return(0);
+
+               GmfMshTab[ MshIdx ] = msh;
+
+
+               /*------------*/
+               /* KW WRITING */
+               /*------------*/
+
+               /* Write the mesh version and dimension */
+
+               if(msh->typ & Asc)
+               {
+                       fprintf(msh->hdl, "%s %d\n\n", GmfKwdFmt[ GmfVersionFormatted ][0], msh->ver);
+                       fprintf(msh->hdl, "%s %d\n", GmfKwdFmt[ GmfDimension ][0], msh->dim);
+               }
+               else
+               {
+                       RecWrd(msh, (unsigned char *)&msh->cod);
+                       RecWrd(msh, (unsigned char *)&msh->ver);
+                       GmfSetKwd(MshIdx, GmfDimension, 0);
+                       RecWrd(msh, (unsigned char *)&msh->dim);
+               }
+
+               return(MshIdx);
+       }
+       else
+               return(0);
+}
+
+
+/*----------------------------------------------------------*/
+/* Close a meshfile in the right way                                           */
+/*----------------------------------------------------------*/
+
+int GmfCloseMesh(int MshIdx)
+{
+       int res = 1;
+       GmfMshSct *msh;
+
+       if( (MshIdx < 1) || (MshIdx > MaxMsh) )
+               return(0);
+
+       msh = GmfMshTab[ MshIdx ];
+       RecBlk(msh, msh->buf, 0);
+
+       /* In write down the "End" kw in write mode */
+
+  if(msh->mod == GmfWrite) {
+               if(msh->typ & Asc)
+                       fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ GmfEnd ][0]);
+               else
+                       GmfSetKwd(MshIdx, GmfEnd, 0);
+  }
+
+       /* Close the file and free the mesh structure */
+
+       if(fclose(msh->hdl))
+               res = 0;
+
+       free(msh);
+       GmfMshTab[ MshIdx ] = NULL;
+
+       return(res);
+}
+
+
+/*----------------------------------------------------------*/
+/* Read the number of lines and set the position to this kwd*/
+/*----------------------------------------------------------*/
+
+int GmfStatKwd(int MshIdx, int KwdCod, ...)
+{
+       int i, *PtrNmbTyp, *PtrSolSiz, *TypTab;
+       GmfMshSct *msh;
+       KwdSct *kwd;
+       va_list VarArg;
+
+       if( (MshIdx < 1) || (MshIdx > MaxMsh) )
+               return(0);
+
+       msh = GmfMshTab[ MshIdx ];
+
+       if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
+               return(0);
+
+       kwd = &msh->KwdTab[ KwdCod ];
+
+       if(!kwd->NmbLin)
+               return(0);
+
+       /* Read further arguments if this kw is a sol */
+
+       if(kwd->typ == SolKwd)
+       {
+               va_start(VarArg, KwdCod);
+
+               PtrNmbTyp = va_arg(VarArg, int *);
+               *PtrNmbTyp = kwd->NmbTyp;
+
+               PtrSolSiz = va_arg(VarArg, int *);
+               *PtrSolSiz = kwd->SolSiz;
+
+               TypTab = va_arg(VarArg, int *);
+
+               for(i=0;i<kwd->NmbTyp;i++)
+                       TypTab[i] = kwd->TypTab[i];
+
+               va_end(VarArg);
+       }
+
+       return(kwd->NmbLin);
+}
+
+
+/*----------------------------------------------------------*/
+/* Set the current file position to a given kwd                                */
+/*----------------------------------------------------------*/
+
+int GmfGotoKwd(int MshIdx, int KwdCod)
+{
+       GmfMshSct *msh;
+       KwdSct *kwd;
+
+       if( (MshIdx < 1) || (MshIdx > MaxMsh) )
+               return(0);
+
+       msh = GmfMshTab[ MshIdx ];
+
+       if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
+               return(0);
+
+       kwd = &msh->KwdTab[ KwdCod ];
+
+       if(!kwd->NmbLin)
+               return(0);
+
+       return(fseek(msh->hdl, kwd->pos, SEEK_SET));
+}
+
+
+/*----------------------------------------------------------*/
+/* Write the kwd and set the number of lines                           */
+/*----------------------------------------------------------*/
+
+int GmfSetKwd(int MshIdx, int KwdCod, ...)
+{
+       int i, NmbLin=0, *TypTab;
+       long CurPos;
+       va_list VarArg;
+       GmfMshSct *msh;
+       KwdSct *kwd;
+
+       if( (MshIdx < 1) || (MshIdx > MaxMsh) )
+               return(0);
+
+       msh = GmfMshTab[ MshIdx ];
+       RecBlk(msh, msh->buf, 0);
+
+       if( (KwdCod < 1) || (KwdCod > GmfMaxKwd) )
+               return(0);
+
+       kwd = &msh->KwdTab[ KwdCod ];
+
+       /* Read further arguments if this kw has a header */
+
+       if(strlen(GmfKwdFmt[ KwdCod ][2]))
+       {
+               va_start(VarArg, KwdCod);
+               NmbLin = va_arg(VarArg, int);
+
+               if(!strcmp(GmfKwdFmt[ KwdCod ][3], "sr"))
+               {
+                       kwd->NmbTyp = va_arg(VarArg, int);
+                       TypTab = va_arg(VarArg, int *);
+
+                       for(i=0;i<kwd->NmbTyp;i++)
+                               kwd->TypTab[i] = TypTab[i];
+               }
+
+               va_end(VarArg);
+       }
+
+       /* Setup the kwd info */
+
+       ExpFmt(msh, KwdCod);
+
+       if(!kwd->typ)
+               return(0);
+       else if(kwd->typ == InfKwd)
+               kwd->NmbLin = 1;
+       else
+               kwd->NmbLin = NmbLin;
+
+       /* Store the next kwd position in binary file */
+
+       if( (msh->typ & Bin) && msh->NexKwdPos )
+       {
+               CurPos = ftell(msh->hdl);
+               fseek(msh->hdl, msh->NexKwdPos, SEEK_SET);
+               SetPos(msh, CurPos);
+               fseek(msh->hdl, CurPos, SEEK_SET);
+       }
+
+       /* Write the header */
+
+       if(msh->typ & Asc)
+       {
+               fprintf(msh->hdl, "\n%s\n", GmfKwdFmt[ KwdCod ][0]);
+
+               if(kwd->typ != InfKwd)
+                       fprintf(msh->hdl, "%d\n", kwd->NmbLin);
+
+               /* In case of solution field, write the extended header */
+
+               if(kwd->typ == SolKwd)
+               {
+                       fprintf(msh->hdl, "%d ", kwd->NmbTyp);
+
+                       for(i=0;i<kwd->NmbTyp;i++)
+                               fprintf(msh->hdl, "%d ", kwd->TypTab[i]);
+
+                       fprintf(msh->hdl, "\n\n");
+               }
+       }
+       else
+       {
+               RecWrd(msh, (unsigned char *)&KwdCod);
+               msh->NexKwdPos = ftell(msh->hdl);
+               SetPos(msh, 0);
+
+               if(kwd->typ != InfKwd)
+                       RecWrd(msh, (unsigned char *)&kwd->NmbLin);
+
+               /* In case of solution field, write the extended header at once */
+
+               if(kwd->typ == SolKwd)
+               {
+                       RecWrd(msh, (unsigned char *)&kwd->NmbTyp);
+
+                       for(i=0;i<kwd->NmbTyp;i++)
+                               RecWrd(msh, (unsigned char *)&kwd->TypTab[i]);
+               }
+       }
+       msh->pos = 0;
+       return(kwd->NmbLin);
+}
+
+
+/*----------------------------------------------------------*/
+/* Read a full line from the current kwd                                       */
+/*----------------------------------------------------------*/
+
+void GmfGetLin(int MshIdx, int KwdCod, ...)
+{
+       int i, j;
+       float *FltSolTab;
+       double *DblSolTab;
+       va_list VarArg;
+       GmfMshSct *msh = GmfMshTab[ MshIdx ];
+       KwdSct *kwd = &msh->KwdTab[ KwdCod ];
+
+       /* Start decoding the arguments */
+
+       va_start(VarArg, KwdCod);
+
+       if(kwd->typ != SolKwd)
+       {
+               if(msh->ver == 1)
+               {
+                       if(msh->typ & Asc)
+                       {
+                               for(i=0;i<kwd->SolSiz;i++)
+                                       if(kwd->fmt[i] == 'r')
+                                               fscanf(msh->hdl, "%f", va_arg(VarArg, float *));
+                                       else
+                                               fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
+                       }
+                       else
+                       {
+                               ScaBlk(msh, msh->buf, kwd->SolSiz);
+
+                               for(i=0;i<kwd->SolSiz;i++)
+                                       if(kwd->fmt[i] == 'r')
+                                               *(va_arg(VarArg, float *)) = msh->FltBuf[i];
+                                       else
+                                               *(va_arg(VarArg, int *)) = msh->IntBuf[i];
+                       }
+               }
+               else
+               {
+                       if(msh->typ & Asc)
+                       {
+                               for(i=0;i<kwd->SolSiz;i++)
+                                       if(kwd->fmt[i] == 'r')
+                                               fscanf(msh->hdl, "%lf", va_arg(VarArg, double *));
+                                       else
+                                               fscanf(msh->hdl, "%d", va_arg(VarArg, int *));
+                       }
+                       else
+                               for(i=0;i<kwd->SolSiz;i++)
+                                       if(kwd->fmt[i] == 'r')
+                                               ScaDblWrd(msh, (unsigned char *)va_arg(VarArg, double *));
+                                       else
+                                               ScaWrd(msh, (unsigned char *)va_arg(VarArg, int *));
+               }
+       }
+       else
+       {
+               if(msh->ver == 1)
+               {
+                       FltSolTab = va_arg(VarArg, float *);
+
+                       if(msh->typ & Asc)
+                               for(j=0;j<kwd->SolSiz;j++)
+                                       fscanf(msh->hdl, "%f", &FltSolTab[j]);
+                       else
+                               ScaBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
+               }
+               else
+               {
+                       DblSolTab = va_arg(VarArg, double *);
+
+                       if(msh->typ & Asc)
+                               for(j=0;j<kwd->SolSiz;j++)
+                                       fscanf(msh->hdl, "%lf", &DblSolTab[j]);
+                       else
+                               for(j=0;j<kwd->SolSiz;j++)
+                                       ScaDblWrd(msh, (unsigned char *)&DblSolTab[j]);
+               }
+       }
+
+       va_end(VarArg);
+}
+
+
+/*----------------------------------------------------------*/
+/* Write a full line from the current kwd                                      */
+/*----------------------------------------------------------*/
+
+void GmfSetLin(int MshIdx, int KwdCod, ...)
+{
+       int i, j, pos, *IntBuf;
+       float *FltSolTab;
+       double *DblSolTab, *DblBuf;
+       va_list VarArg;
+       GmfMshSct *msh = GmfMshTab[ MshIdx ];
+       KwdSct *kwd = &msh->KwdTab[ KwdCod ];
+
+       /* Start decoding the arguments */
+
+       va_start(VarArg, KwdCod);
+
+       if(kwd->typ != SolKwd)
+       {
+               if(msh->ver == 1)
+               {
+                       if(msh->typ & Asc)
+                       {
+                               for(i=0;i<kwd->SolSiz;i++)
+                                       if(kwd->fmt[i] == 'r')
+                                               fprintf(msh->hdl, "%g ", (float)va_arg(VarArg, double));
+                                       else
+                                               fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
+                       }
+                       else
+                       {
+                               for(i=0;i<kwd->SolSiz;i++)
+                                       if(kwd->fmt[i] == 'r')
+                                               msh->FltBuf[i] = va_arg(VarArg, double);
+                                       else
+                                               msh->IntBuf[i] = va_arg(VarArg, int);
+
+                               RecBlk(msh, msh->buf, kwd->SolSiz);
+                       }
+               }
+               else
+               {
+                       if(msh->typ & Asc)
+                       {
+                               for(i=0;i<kwd->SolSiz;i++)
+                                       if(kwd->fmt[i] == 'r')
+                                               fprintf(msh->hdl, "%.15lg ", va_arg(VarArg, double));
+                                       else
+                                               fprintf(msh->hdl, "%d ", va_arg(VarArg, int));
+                       }
+                       else
+                       {
+                               pos = 0;
+
+                               for(i=0;i<kwd->SolSiz;i++)
+                                       if(kwd->fmt[i] == 'r')
+                                       {
+                                               DblBuf = (void *)&msh->buf[ pos ];
+                                               *DblBuf = va_arg(VarArg, double);
+                                               pos += 8;
+                                       }
+                                       else
+                                       {
+                                               IntBuf = (void *)&msh->buf[ pos ];
+                                               *IntBuf = va_arg(VarArg, int);
+                                               pos += 4;
+                                       }
+                               RecBlk(msh, msh->buf, kwd->NmbWrd);
+                       }
+               }
+       }
+       else
+       {
+               if(msh->ver == 1)
+               {
+                       FltSolTab = va_arg(VarArg, float *);
+
+                       if(msh->typ & Asc)
+                               for(j=0;j<kwd->SolSiz;j++)
+                                       fprintf(msh->hdl, "%g ", FltSolTab[j]);
+                       else
+                               RecBlk(msh, (unsigned char *)FltSolTab, kwd->NmbWrd);
+               }
+               else
+               {
+                       DblSolTab = va_arg(VarArg, double *);
+
+                       if(msh->typ & Asc)
+                               for(j=0;j<kwd->SolSiz;j++)
+                                       fprintf(msh->hdl, "%.15lg ", DblSolTab[j]);
+                       else
+                               RecBlk(msh, (unsigned char *)DblSolTab, kwd->NmbWrd);
+               }
+       }
+
+       va_end(VarArg);
+
+       if(msh->typ & Asc)
+               fprintf(msh->hdl, "\n");
+}
+
+
+/*----------------------------------------------------------*/
+/* Private procedure for transmesh : copy a whole line         */
+/*----------------------------------------------------------*/
+
+void GmfCpyLin(int InpIdx, int OutIdx, int KwdCod)
+{
+       double d;
+       float f;
+       int i, a;
+       GmfMshSct *InpMsh = GmfMshTab[ InpIdx ], *OutMsh = GmfMshTab[ OutIdx ];
+       KwdSct *kwd = &InpMsh->KwdTab[ KwdCod ];
+
+       for(i=0;i<kwd->SolSiz;i++)
+       {
+               if(kwd->fmt[i] == 'r')
+               {
+                       if(InpMsh->ver == 1)
+                       {
+                               if(InpMsh->typ & Asc)
+                                       fscanf(InpMsh->hdl, "%f", &f);
+                               else
+                                       ScaWrd(InpMsh, (unsigned char *)&f);
+
+                               d = f;
+                       }
+                       else
+                       {
+                               if(InpMsh->typ & Asc)
+                                       fscanf(InpMsh->hdl, "%lf", &d);
+                               else
+                                       ScaDblWrd(InpMsh, (unsigned char *)&d);
+
+                               f = (float)d;
+                       }
+
+                       if(OutMsh->ver == 1)
+                               if(OutMsh->typ & Asc)
+                                       fprintf(OutMsh->hdl, "%g ", f);
+                               else
+                                       RecWrd(OutMsh, (unsigned char *)&f);
+                       else
+                               if(OutMsh->typ & Asc)
+                                       fprintf(OutMsh->hdl, "%.15g ", d);
+                               else
+                                       RecDblWrd(OutMsh, (unsigned char *)&d);
+               }
+               else
+               {
+                       if(InpMsh->typ & Asc)
+                               fscanf(InpMsh->hdl, "%d", &a);
+                       else
+                               ScaWrd(InpMsh, (unsigned char *)&a);
+
+                       if(OutMsh->typ & Asc)
+                               fprintf(OutMsh->hdl, "%d ", a);
+                       else
+                               RecWrd(OutMsh, (unsigned char *)&a);
+               }
+       }
+
+       if(OutMsh->typ & Asc)
+               fprintf(OutMsh->hdl, "\n");
+}
+
+
+/*----------------------------------------------------------*/
+/* Find every kw present in a meshfile                                         */
+/*----------------------------------------------------------*/
+
+static int ScaKwdTab(GmfMshSct *msh)
+{
+       int KwdCod;
+       long  NexPos, CurPos, EndPos;
+       char str[ GmfStrSiz ];
+
+       if(msh->typ & Asc)
+       {
+               /* Scan each string in the file until the end */
+
+               while(fscanf(msh->hdl, "%s", str) != EOF)
+               {
+                       /* Fast test in order to reject quickly the numeric values */
+
+                       if(isalpha(str[0]))
+                       {
+                               /* Search which kwd code this string is associated with, 
+                                       then get its header and save the curent position in file (just before the data) */
+
+                               for(KwdCod=1; KwdCod<= GmfMaxKwd; KwdCod++)
+                                       if(!strcmp(str, GmfKwdFmt[ KwdCod ][0]))
+                                       {
+                                               ScaKwdHdr(msh, KwdCod);
+                                               break;
+                                       }
+                       }
+                       else if(str[0] == '#')
+                               while(fgetc(msh->hdl) != '\n');
+               }
+       }
+       else
+       {
+               /* Get file size */
+
+               CurPos = ftell(msh->hdl);
+               fseek(msh->hdl, 0, SEEK_END);
+               EndPos = ftell(msh->hdl);
+               fseek(msh->hdl, CurPos, SEEK_SET);
+
+               /* Jump through kwd positions in the file */
+
+               do
+               {
+                       /* Get the kwd code and the next kwd position */
+
+                       ScaWrd(msh, (unsigned char *)&KwdCod);
+                       NexPos = GetPos(msh);
+
+                       if(NexPos > EndPos)
+                               return(0);
+
+                       /* Check if this kwd belongs to this mesh version */
+
+                       if( (KwdCod >= 1) && (KwdCod <= GmfMaxKwd) )
+                               ScaKwdHdr(msh, KwdCod);
+
+                       /* Go to the next kwd */
+
+                       if(NexPos)
+                               fseek(msh->hdl, NexPos, SEEK_SET);
+               }while(NexPos && (KwdCod != GmfEnd));
+       }
+
+       return(1);
+}
+
+
+/*----------------------------------------------------------*/
+/* Read and setup the keyword's header                                         */
+/*----------------------------------------------------------*/
+
+static void ScaKwdHdr(GmfMshSct *msh, int KwdCod)
+{
+       int i;
+       KwdSct *kwd = &msh->KwdTab[ KwdCod ];
+
+       if(!strcmp("i", GmfKwdFmt[ KwdCod ][2]))
+       {
+               if(msh->typ & Asc)
+                       fscanf(msh->hdl, "%d", &kwd->NmbLin);
+               else
+                       ScaWrd(msh, (unsigned char *)&kwd->NmbLin);
+       }
+       else
+               kwd->NmbLin = 1;
+
+       if(!strcmp("sr", GmfKwdFmt[ KwdCod ][3]))
+       {
+               if(msh->typ & Asc)
+               {
+                       fscanf(msh->hdl, "%d", &kwd->NmbTyp);
+
+                       for(i=0;i<kwd->NmbTyp;i++)
+                               fscanf(msh->hdl, "%d", &kwd->TypTab[i]);
+               }
+               else
+               {
+                       ScaWrd(msh, (unsigned char *)&kwd->NmbTyp);
+
+                       for(i=0;i<kwd->NmbTyp;i++)
+                               ScaWrd(msh, (unsigned char *)&kwd->TypTab[i]);
+               }
+       }
+
+       ExpFmt(msh, KwdCod);
+       kwd->pos = ftell(msh->hdl);
+}
+
+
+/*----------------------------------------------------------*/
+/* Expand the compacted format and compute the line size       */
+/*----------------------------------------------------------*/
+
+static void ExpFmt(GmfMshSct *msh, int KwdCod)
+{
+       int i, j, TmpSiz=0;
+       char chr, *InpFmt = GmfKwdFmt[ KwdCod ][3];
+       KwdSct *kwd = &msh->KwdTab[ KwdCod ];
+
+       /* Set the kwd's type */
+
+       if(!strlen(GmfKwdFmt[ KwdCod ][2]))
+               kwd->typ = InfKwd;
+       else if(!strcmp(InpFmt, "sr"))
+               kwd->typ = SolKwd;
+       else
+               kwd->typ = RegKwd;
+
+       /* Get the solution-field's size */
+
+       if(kwd->typ == SolKwd)
+               for(i=0;i<kwd->NmbTyp;i++)
+                       switch(kwd->TypTab[i])
+                       {
+                               case GmfSca    : TmpSiz += 1; break;
+                               case GmfVec    : TmpSiz += msh->dim; break;
+                               case GmfSymMat : TmpSiz += (msh->dim * (msh->dim+1)) / 2; break;
+                               case GmfMat    : TmpSiz += msh->dim * msh->dim; break;
+                       }
+
+       /* Scan each character from the format string */
+
+       i = kwd->SolSiz = kwd->NmbWrd = 0;
+
+       while(i < strlen(InpFmt))
+       {
+               chr = InpFmt[ i++ ];
+
+               if(chr == 'd')
+               {
+                       chr = InpFmt[i++];
+
+                       for(j=0;j<msh->dim;j++)
+                               kwd->fmt[ kwd->SolSiz++ ] = chr;
+               }
+               else if(chr == 's')
+               {
+                       chr = InpFmt[i++];
+
+                       for(j=0;j<TmpSiz;j++)
+                               kwd->fmt[ kwd->SolSiz++ ] = chr;
+               }
+               else
+                       kwd->fmt[ kwd->SolSiz++ ] = chr;
+       }
+
+       for(i=0;i<kwd->SolSiz;i++)
+               if(kwd->fmt[i] == 'i')
+                       kwd->NmbWrd++;
+               else if(msh->ver >= 2)
+                       kwd->NmbWrd += 2;
+               else
+                       kwd->NmbWrd++;
+}
+
+
+/*----------------------------------------------------------*/
+/* Read a four bytes word from a mesh file                                     */
+/*----------------------------------------------------------*/
+
+static void ScaWrd(GmfMshSct *msh, unsigned char *wrd)
+{
+       unsigned char swp;
+
+       fread(wrd, WrdSiz, 1, msh->hdl);
+
+       if(msh->cod == 1)
+               return;
+
+       swp = wrd[3];
+       wrd[3] = wrd[0];
+       wrd[0] = swp;
+
+       swp = wrd[2];
+       wrd[2] = wrd[1];
+       wrd[1] = swp;
+}
+
+
+/*----------------------------------------------------------*/
+/* Read an eight bytes word from a mesh file                           */
+/*----------------------------------------------------------*/
+
+static void ScaDblWrd(GmfMshSct *msh, unsigned char *wrd)
+{
+       int i;
+       unsigned char swp;
+
+       fread(wrd, WrdSiz, 2, msh->hdl);
+
+       if(msh->cod == 1)
+               return;
+
+       for(i=0;i<4;i++)
+       {
+               swp = wrd[7-i];
+               wrd[7-i] = wrd[i];
+               wrd[i] = swp;
+       }
+}
+
+
+/*----------------------------------------------------------*/
+/* Read ablock of four bytes word from a mesh file                     */
+/*----------------------------------------------------------*/
+
+static void ScaBlk(GmfMshSct *msh, unsigned char *blk, int siz)
+{
+       int i, j;
+       unsigned char swp, *wrd;
+
+       fread(blk, WrdSiz, siz, msh->hdl);
+
+       if(msh->cod == 1)
+               return;
+
+       for(i=0;i<siz;i++)
+       {
+               wrd = &blk[ i * 4 ];
+
+               for(j=0;j<2;j++)
+               {
+                       swp = wrd[ 3-j ];
+                       wrd[ 3-j ] = wrd[j];
+                       wrd[j] = swp;
+               }
+       }
+}
+
+
+/*----------------------------------------------------------*/
+/* Read a 4 or 8 bytes position in mesh file                           */
+/*----------------------------------------------------------*/
+
+static long GetPos(GmfMshSct *msh)
+{
+       int IntVal;
+       long pos;
+
+       if(msh->ver >= 3)
+               ScaDblWrd(msh, (unsigned char*)&pos);
+       else
+       {
+               ScaWrd(msh, (unsigned char*)&IntVal);
+               pos = IntVal;
+       }
+
+       return(pos);
+}
+
+
+/*----------------------------------------------------------*/
+/* Write a four bytes word to a mesh file                                      */
+/*----------------------------------------------------------*/
+
+static void RecWrd(GmfMshSct *msh, unsigned char *wrd)
+{
+       fwrite(wrd, WrdSiz, 1, msh->hdl);
+}
+
+
+/*----------------------------------------------------------*/
+/* Write an eight bytes word to a mesh file                                    */
+/*----------------------------------------------------------*/
+
+static void RecDblWrd(GmfMshSct *msh, unsigned char *wrd)
+{
+       fwrite(wrd, WrdSiz, 2, msh->hdl);
+}
+
+
+/*----------------------------------------------------------*/
+/* Write a block of four bytes word to a mesh file                     */
+/*----------------------------------------------------------*/
+
+static void RecBlk(GmfMshSct *msh, unsigned char *blk, int siz)
+{
+       /* Copy this line-block into the main mesh buffer */
+
+       if(siz)
+       {
+               memcpy(&msh->blk[ msh->pos ], blk, siz * WrdSiz);
+               msh->pos += siz * WrdSiz;
+       }
+
+       /* When the buffer is full or this procedure is called with a 0 size, flush the cache on disk */
+
+       if( (msh->pos > BufSiz) || (!siz && msh->pos) )
+       {
+               fwrite(msh->blk, 1, msh->pos, msh->hdl);
+               msh->pos = 0;
+       }
+}
+
+
+/*----------------------------------------------------------*/
+/* Read a 4 or 8 bytes position in mesh file                           */
+/*----------------------------------------------------------*/
+
+static void SetPos(GmfMshSct *msh, long pos)
+{
+       int IntVal;
+
+       if(msh->ver >= 3)
+               RecDblWrd(msh, (unsigned char*)&pos);
+       else
+       {
+               IntVal = pos;
+               RecWrd(msh, (unsigned char*)&IntVal);
+       }
+}
diff --git a/src/GHS3DPlugin/libmesh5.h b/src/GHS3DPlugin/libmesh5.h
new file mode 100755 (executable)
index 0000000..cfaf9fb
--- /dev/null
@@ -0,0 +1,152 @@
+
+
+/*----------------------------------------------------------*/
+/*                                                                                                                     */
+/*                                             LIBMESH V 5.45                                          */
+/*                                                                                                                     */
+/*----------------------------------------------------------*/
+/*                                                                                                                     */
+/*     Description:            handle .meshb file format I/O           */
+/*     Author:                         Loic MARECHAL                                           */
+/*     Creation date:          feb 16 2007                                                     */
+/*     Last modification:      sep 27 2010                                                     */
+/*                                                                                                                     */
+/*----------------------------------------------------------*/
+
+
+/*----------------------------------------------------------*/
+/* Defines                                                                                                     */
+/*----------------------------------------------------------*/
+
+#define GmfStrSiz 1024
+#define GmfMaxTyp 1000
+#define GmfMaxKwd 79
+#define GmfMshVer 1
+#define GmfRead 1
+#define GmfWrite 2
+#define GmfSca 1
+#define GmfVec 2
+#define GmfSymMat 3
+#define GmfMat 4
+#define GmfFloat 1
+#define GmfDouble 2
+
+enum GmfKwdCod
+{
+       GmfReserved1, \
+       GmfVersionFormatted, \
+       GmfReserved2, \
+       GmfDimension, \
+       GmfVertices, \
+       GmfEdges, \
+       GmfTriangles, \
+       GmfQuadrilaterals, \
+       GmfTetrahedra, \
+       GmfPrisms, \
+       GmfHexahedra, \
+       GmfIterationsAll, \
+       GmfTimesAll, \
+       GmfCorners, \
+       GmfRidges, \
+       GmfRequiredVertices, \
+       GmfRequiredEdges, \
+       GmfRequiredTriangles, \
+       GmfRequiredQuadrilaterals, \
+       GmfTangentAtEdgeVertices, \
+       GmfNormalAtVertices, \
+       GmfNormalAtTriangleVertices, \
+       GmfNormalAtQuadrilateralVertices, \
+       GmfAngleOfCornerBound, \
+       GmfTrianglesP2, \
+       GmfEdgesP2, \
+       GmfSolAtPyramids, \
+       GmfQuadrilateralsQ2, \
+       GmfISolAtPyramids, \
+       GmfReserved6, \
+       GmfTetrahedraP2, \
+       GmfReserved7, \
+       GmfReserved8, \
+       GmfHexahedraQ2, \
+       GmfReserved9, \
+       GmfReserved10, \
+       GmfReserved17, \
+       GmfReserved18, \
+       GmfReserved19, \
+       GmfReserved20, \
+       GmfReserved21, \
+       GmfReserved22, \
+       GmfReserved23, \
+       GmfReserved24, \
+       GmfReserved25, \
+       GmfReserved26, \
+       GmfPolyhedra, \
+       GmfPolygons, \
+       GmfReserved29, \
+       GmfPyramids, \
+       GmfBoundingBox, \
+       GmfBody, \
+       GmfPrivateTable, \
+       GmfReserved33, \
+       GmfEnd, \
+       GmfReserved34, \
+       GmfReserved35, \
+       GmfReserved36, \
+       GmfReserved37, \
+       GmfTangents, \
+       GmfNormals, \
+       GmfTangentAtVertices, \
+       GmfSolAtVertices, \
+       GmfSolAtEdges, \
+       GmfSolAtTriangles, \
+       GmfSolAtQuadrilaterals, \
+       GmfSolAtTetrahedra, \
+       GmfSolAtPrisms, \
+       GmfSolAtHexahedra, \
+       GmfDSolAtVertices, \
+       GmfISolAtVertices, \
+       GmfISolAtEdges, \
+       GmfISolAtTriangles, \
+       GmfISolAtQuadrilaterals, \
+       GmfISolAtTetrahedra, \
+       GmfISolAtPrisms, \
+       GmfISolAtHexahedra, \
+       GmfIterations, \
+       GmfTime, \
+       GmfReserved38
+};
+
+
+/*----------------------------------------------------------*/
+/* External procedures                                                                         */
+/*----------------------------------------------------------*/
+
+extern int GmfOpenMesh(const char *, int, ...);
+extern int GmfCloseMesh(int);
+extern int GmfStatKwd(int, int, ...);
+extern int GmfGotoKwd(int, int);
+extern int GmfSetKwd(int, int, ...);
+extern void GmfGetLin(int, int, ...);
+extern void GmfSetLin(int, int, ...);
+
+
+/*----------------------------------------------------------*/
+/* Fortran 77 API                                                                                      */
+/*----------------------------------------------------------*/
+
+#if defined(F77_NO_UNDER_SCORE)
+#define call(x) x
+#else
+#define call(x) x ## _
+#endif
+
+
+/*----------------------------------------------------------*/
+/* Transmesh private API                                                                       */
+/*----------------------------------------------------------*/
+
+#ifdef TRANSMESH
+
+extern char *GmfKwdFmt[ GmfMaxKwd + 1 ][4];
+extern int GmfCpyLin(int, int, int);
+
+#endif
index e716b43b0b03b703c9bfb6dfa526e4c287d881e0..4d4a278d091b05a3013b349048e911e9a7900d67 100644 (file)
@@ -1,20 +1,20 @@
-//  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+// Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 //  GHS3DPlugin GUI: GUI for plugged-in mesher GHS3DPlugin
@@ -505,32 +505,35 @@ void GHS3DPluginGUI_HypothesisCreator::retrieveParams() const
   myFEMCorrectionCheck             ->setChecked    ( data.myFEMCorrection );
   myTextOption                     ->setText       ( data.myTextOption );
 
-  TEnforcedVertexValues::const_iterator it;
+  TEnfVertexList::const_iterator it;
   int row = 0;
   for(it = data.myEnforcedVertices.begin() ; it != data.myEnforcedVertices.end(); it++ )
   {
-    double x = it->at(0);
-    double y = it->at(1);
-    double z = it->at(2);
-    double size = it->at(3);
-    // ENF_VER_X_COLUMN
-    mySmpModel->setData(mySmpModel->index(row, ENF_VER_X_COLUMN),x);
-    mySmpModel->setItem( row, ENF_VER_X_COLUMN, new QStandardItem(QString::number(x)) );
-    mySmpModel->item( row, ENF_VER_X_COLUMN )->setFlags( Qt::ItemIsSelectable );
-    // ENF_VER_Y_COLUMN
-    mySmpModel->setData(mySmpModel->index(row, ENF_VER_Y_COLUMN),y);
-    mySmpModel->setItem( row, ENF_VER_Y_COLUMN, new QStandardItem(QString::number(y)) );
-    mySmpModel->item( row, ENF_VER_Y_COLUMN )->setFlags( Qt::ItemIsSelectable );
-    // ENF_VER_Z_COLUMN
-    mySmpModel->setData(mySmpModel->index(row, ENF_VER_Z_COLUMN),z);
-    mySmpModel->setItem( row, ENF_VER_Z_COLUMN, new QStandardItem(QString::number(z)) );
-    mySmpModel->item( row, ENF_VER_Z_COLUMN )->setFlags( Qt::ItemIsSelectable );
-    // ENF_VER_SIZE_COLUMN
-    mySmpModel->setData(mySmpModel->index(row, ENF_VER_SIZE_COLUMN),size);
-    mySmpModel->setItem( row, ENF_VER_SIZE_COLUMN, new QStandardItem(QString::number(size)) );
-
-    MESSAGE("Row " << row << ": (" << x << ","<< y << ","<< z << ") ="<< size);
-    row++;
+    TEnfVertex* enfVertex = (*it);
+    if (enfVertex->coords.size()) {
+      double x = enfVertex->coords.at(0);
+      double y = enfVertex->coords.at(1);
+      double z = enfVertex->coords.at(2);
+      double size = enfVertex->size;
+      // ENF_VER_X_COLUMN
+      mySmpModel->setData(mySmpModel->index(row, ENF_VER_X_COLUMN),x);
+      mySmpModel->setItem( row, ENF_VER_X_COLUMN, new QStandardItem(QString::number(x)) );
+      mySmpModel->item( row, ENF_VER_X_COLUMN )->setFlags( Qt::ItemIsSelectable );
+      // ENF_VER_Y_COLUMN
+      mySmpModel->setData(mySmpModel->index(row, ENF_VER_Y_COLUMN),y);
+      mySmpModel->setItem( row, ENF_VER_Y_COLUMN, new QStandardItem(QString::number(y)) );
+      mySmpModel->item( row, ENF_VER_Y_COLUMN )->setFlags( Qt::ItemIsSelectable );
+      // ENF_VER_Z_COLUMN
+      mySmpModel->setData(mySmpModel->index(row, ENF_VER_Z_COLUMN),z);
+      mySmpModel->setItem( row, ENF_VER_Z_COLUMN, new QStandardItem(QString::number(z)) );
+      mySmpModel->item( row, ENF_VER_Z_COLUMN )->setFlags( Qt::ItemIsSelectable );
+      // ENF_VER_SIZE_COLUMN
+      mySmpModel->setData(mySmpModel->index(row, ENF_VER_SIZE_COLUMN),size);
+      mySmpModel->setItem( row, ENF_VER_SIZE_COLUMN, new QStandardItem(QString::number(size)) );
+
+      MESSAGE("Row " << row << ": (" << x << ","<< y << ","<< z << ") ="<< size);
+      row++;
+    }
   }
   
   GHS3DPluginGUI_HypothesisCreator* that = (GHS3DPluginGUI_HypothesisCreator*)this;
@@ -630,13 +633,17 @@ bool GHS3DPluginGUI_HypothesisCreator::readParamsFromHypo( GHS3DHypothesisData&
   MESSAGE("vertices->length(): " << vertices->length());
   h_data.myEnforcedVertices.clear();
   for (int i=0 ; i<vertices->length() ; i++) {
-    GHS3DEnforcedVertex myVertex;
-    myVertex.push_back(vertices[i].x);
-    myVertex.push_back(vertices[i].y);
-    myVertex.push_back(vertices[i].z);
-    myVertex.push_back(vertices[i].size);
-    MESSAGE("Add enforced vertex ("<< myVertex[0] << ","<< myVertex[1] << ","<< myVertex[2] << ") ="<< myVertex[3]);
-    h_data.myEnforcedVertices.push_back(myVertex);
+    TEnfVertex* myVertex = new TEnfVertex();
+    myVertex->name = CORBA::string_dup(vertices[i].name.in());
+    myVertex->geomEntry = CORBA::string_dup(vertices[i].geomEntry.in());
+    myVertex->groupName = CORBA::string_dup(vertices[i].groupName.in());
+    myVertex->size = vertices[i].size;
+    if (vertices[i].coords.length()) {
+      for (int c = 0; c < vertices[i].coords.length() ; c++)
+        myVertex->coords.push_back(vertices[i].coords[c]);
+      MESSAGE("Add enforced vertex ("<< myVertex->coords.at(0) << ","<< myVertex->coords.at(1) << ","<< myVertex->coords.at(2) << ") ="<< myVertex->size);
+    }
+    h_data.myEnforcedVertices.insert(myVertex);
   }
   return true;
 }
@@ -694,39 +701,44 @@ bool GHS3DPluginGUI_HypothesisCreator::storeParamsToHypo( const GHS3DHypothesisD
 //        else {
             // iterate over vertices of hypo
             for(int i = 0 ; i <nbVertexHyp ; i++) {
-                double x = vertexHyp[i].x;
-                double y = vertexHyp[i].y;
-                double z = vertexHyp[i].z;
+              if (vertexHyp[i].coords.length()) {
+                double x = vertexHyp[i].coords[0];
+                double y = vertexHyp[i].coords[1];
+                double z = vertexHyp[i].coords[2];
                 // vertex is removed
                 if (!smpVertexExists(x,y,z))
                     h->RemoveEnforcedVertex(x,y,z);
+              }
             }
 //        }
     }
     
-    TEnforcedVertexValues::const_iterator it;
+    TEnfVertexList::const_iterator it;
     for(it = h_data.myEnforcedVertices.begin() ; it != h_data.myEnforcedVertices.end(); it++ ) {
-      double x = it->at(0);
-      double y = it->at(1);
-      double z = it->at(2);
-      double size = it->at(3);
-      MESSAGE("(" << x   << ", "
-                       << y   << ", "
-                       << z   << ") = "
-                       << size  );
-      double mySize;
-      try {
-        mySize = h->GetEnforcedVertex(x,y,z);
-        MESSAGE("Old size: " << mySize);
-        if (mySize != size) {
+      TEnfVertex* enfVertex = (*it);
+      if (enfVertex->coords.size()) {
+        double x = enfVertex->coords.at(0);
+        double y = enfVertex->coords.at(1);
+        double z = enfVertex->coords.at(2);
+        double size = enfVertex->size;
+        MESSAGE("(" << x   << ", "
+                        << y   << ", "
+                        << z   << ") = "
+                        << size  );
+        double mySize;
+        try {
+          mySize = h->GetEnforcedVertex(x,y,z);
+          MESSAGE("Old size: " << mySize);
+          if (mySize != size) {
+            MESSAGE("Setting new size: " << size);
+            h->SetEnforcedVertex(x,y,z,size);
+          }
+        }
+        catch (...) {
           MESSAGE("Setting new size: " << size);
-          h->SetEnforcedVertex(x,y,z,size);
+          h->SetEnforcedVertex( x, y, z, size);
         }
       }
-      catch (...) {
-        MESSAGE("Setting new size: " << size);
-        h->SetEnforcedVertex(x,y,z,size);
-      }
     }
   }
   catch ( const SALOME::SALOME_Exception& ex )
@@ -756,16 +768,19 @@ bool GHS3DPluginGUI_HypothesisCreator::readParamsFromWidgets( GHS3DHypothesisDat
   h_data.myEnforcedVertices.clear();
 
   for (int i=0 ; i<mySmpModel->rowCount() ; i++) {
-    GHS3DEnforcedVertex myVertex;
-    myVertex.push_back(mySmpModel->data(mySmpModel->index(i,ENF_VER_X_COLUMN)).toDouble());
-    myVertex.push_back(mySmpModel->data(mySmpModel->index(i,ENF_VER_Y_COLUMN)).toDouble());
-    myVertex.push_back(mySmpModel->data(mySmpModel->index(i,ENF_VER_Z_COLUMN)).toDouble());
-    myVertex.push_back(mySmpModel->data(mySmpModel->index(i,ENF_VER_SIZE_COLUMN)).toDouble());
-    MESSAGE("Add new enforced vertex (" << myVertex[0] << ", "
-                                             << myVertex[1] << ", "
-                                             << myVertex[2] << ") = "
-                                             << myVertex[3]);
-    h_data.myEnforcedVertices.push_back(myVertex);
+    TEnfVertex *myVertex = new TEnfVertex();
+    myVertex->name = "";
+    myVertex->geomEntry = "";
+    myVertex->groupName = "";
+    myVertex->coords.push_back(mySmpModel->data(mySmpModel->index(i,ENF_VER_X_COLUMN)).toDouble());
+    myVertex->coords.push_back(mySmpModel->data(mySmpModel->index(i,ENF_VER_Y_COLUMN)).toDouble());
+    myVertex->coords.push_back(mySmpModel->data(mySmpModel->index(i,ENF_VER_Z_COLUMN)).toDouble());
+    myVertex->size = mySmpModel->data(mySmpModel->index(i,ENF_VER_SIZE_COLUMN)).toDouble();
+    MESSAGE("Add new enforced vertex (" << myVertex->coords.at(0) << ", "
+                                             << myVertex->coords.at(1) << ", "
+                                             << myVertex->coords.at(2) << ") = "
+                                             << myVertex->size);
+    h_data.myEnforcedVertices.insert(myVertex);
   }
 
   return true;
index de0359d86065a52f5448872599e4766d8824dcda..3e883b28960bddd6e8764fc15404e19340c37cc6 100644 (file)
@@ -1,20 +1,20 @@
-//  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+// Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
 //  GHS3DPlugin GUI: GUI for plugged-in mesher GHS3DPlugin
@@ -41,6 +41,7 @@
 #include <QItemDelegate>
 #include <map>
 #include <vector>
+#include <set>
 #include CORBA_SERVER_HEADER(GHS3DPlugin_Algorithm)
 
 class QWidget;
@@ -55,8 +56,32 @@ class QDoubleSpinBox;
 
 class LightApp_SelectionMgr;
 
-typedef std::vector<double> GHS3DEnforcedVertex;
-typedef std::vector<GHS3DEnforcedVertex> TEnforcedVertexValues;
+// Enforced vertex
+struct TEnfVertex{
+  std::string name;
+  std::string geomEntry;
+  std::vector<double> coords;
+  std::string groupName;
+  double size;
+};
+
+struct CompareEnfVertices
+{
+  bool operator () (const TEnfVertex* e1, const TEnfVertex* e2) const {
+    if (e1 && e2) {
+      if (e1->coords.size() && e2->coords.size())
+        return (e1->coords < e2->coords);
+      else
+        return (e1->geomEntry < e2->geomEntry);
+    }
+    return false;
+  }
+};
+
+// List of enforced vertices
+typedef std::set< TEnfVertex*, CompareEnfVertices > TEnfVertexList;
+
+// typedef std::vector<GHS3DEnforcedVertex> TEnforcedVertexCoordsValues;
 
 typedef struct
 {
@@ -64,7 +89,7 @@ typedef struct
   int     myMaximumMemory,myInitialMemory,myOptimizationLevel;
   QString myName,myWorkingDir,myTextOption;
   short   myVerboseLevel;
-  TEnforcedVertexValues myEnforcedVertices;
+  TEnfVertexList myEnforcedVertices;
 } GHS3DHypothesisData;
 
 /*!
index 78ff47e73815079d7df5e9b6f6bc8c1303b6f95d..7f59dfee8759ad323e538c652fa486f0da71e036 100644 (file)
@@ -1,25 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE TS>
-<!--
-  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
-  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-
--->
-<TS version="1.1" >
+<TS version="2.0" language="en_US">
     <context>
         <name>@default</name>
         <message>
index 9d83ca7ee93fd71685f125fce2403da31b2ef820..e5b3c4c79f1cecd7646391fb5d40021f0130886e 100644 (file)
@@ -1,20 +1,20 @@
-#  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+# Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 #
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Lesser General Public
-#  License as published by the Free Software Foundation; either
-#  version 2.1 of the License.
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
 #
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Lesser General Public License for more details.
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
 #
-#  You should have received a copy of the GNU Lesser General Public
-#  License along with this library; if not, write to the Free Software
-#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #
-#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
 # -* Makefile *- 
index a6d0a7a604a35e92c1f439ee4200b370965c8a65..a2b317d29955d3ac6219978d62c4b2abcd3bc015 100644 (file)
@@ -1,20 +1,20 @@
-#  Copyright (C) 2004-2010  CEA/DEN, EDF R&D
+# Copyright (C) 2004-2011  CEA/DEN, EDF R&D
 #
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Lesser General Public
-#  License as published by the Free Software Foundation; either
-#  version 2.1 of the License.
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
 #
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Lesser General Public License for more details.
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
 #
-#  You should have received a copy of the GNU Lesser General Public
-#  License along with this library; if not, write to the Free Software
-#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 #
-#  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
 # -* Makefile *-