Salome HOME
Module MULTIPR MULTIPR_1
authorcs <cs>
Fri, 9 Mar 2007 14:29:06 +0000 (14:29 +0000)
committercs <cs>
Fri, 9 Mar 2007 14:29:06 +0000 (14:29 +0000)
66 files changed:
INSTALL [new file with mode: 0644]
MULTIPR_version.h.in [new file with mode: 0644]
Makefile.in [new file with mode: 0644]
README [new file with mode: 0755]
adm_local/Makefile.in [new file with mode: 0644]
adm_local/unix/config_files/check_MULTIPR.m4 [new file with mode: 0755]
adm_local/unix/make_commence.in [new file with mode: 0644]
adm_local/unix/make_omniorb.in [new file with mode: 0644]
bin/VERSION.in [new file with mode: 0755]
bin/myrunSalome.py [new file with mode: 0755]
bin/runAppli.in [new file with mode: 0755]
build_configure [new file with mode: 0755]
configure.in.base [new file with mode: 0644]
doc/CSSI_DRV_EDF-IOLS-MULTIPR_spec-conception_1_1.odt [new file with mode: 0755]
doc/CSSI_DRV_EDF-IOLS-MULTIPR_spec-conception_1_1.pdf [new file with mode: 0755]
idl/MULTIPR.idl [new file with mode: 0644]
idl/Makefile.in [new file with mode: 0644]
resources/ExecMULTIPR.png [new file with mode: 0644]
resources/MULTIPR.png [new file with mode: 0644]
resources/MULTIPRCatalog.xml.in [new file with mode: 0644]
resources/MULTIPR_import_med.png [new file with mode: 0644]
resources/MULTIPR_save_med.png [new file with mode: 0644]
resources/SalomeApp.xml [new file with mode: 0644]
src/MULTIPR/MULTIPR_API.cxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_API.hxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_DecimationAccel.cxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_DecimationAccel.hxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_DecimationFilter.cxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_DecimationFilter.hxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_Elements.cxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_Elements.hxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_Exceptions.hxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_Family.cxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_Family.hxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_Field.cxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_Field.hxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_GaussLoc.cxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_GaussLoc.hxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_Globals.hxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_Mesh.cxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_Mesh.hxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_MeshDis.cxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_MeshDis.hxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_Nodes.cxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_Nodes.hxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_Obj.cxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_Obj.hxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_PointOfField.hxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_Profil.cxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_Profil.hxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_ProgressCallback.hxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_Utils.cxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_Utils.hxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_i.cxx [new file with mode: 0644]
src/MULTIPR/MULTIPR_i.hxx [new file with mode: 0644]
src/MULTIPR/Makefile.in [new file with mode: 0644]
src/MULTIPR/multipr.cxx [new file with mode: 0644]
src/MULTIPRGUI/MULTIPR_GUI.cxx [new file with mode: 0644]
src/MULTIPRGUI/MULTIPR_GUI.h [new file with mode: 0644]
src/MULTIPRGUI/MULTIPR_GUI_Dlg.cxx [new file with mode: 0644]
src/MULTIPRGUI/MULTIPR_GUI_Dlg.h [new file with mode: 0644]
src/MULTIPRGUI/MULTIPR_icons.po [new file with mode: 0644]
src/MULTIPRGUI/MULTIPR_msg_en.po [new file with mode: 0644]
src/MULTIPRGUI/MULTIPR_msg_fr.po [new file with mode: 0644]
src/MULTIPRGUI/Makefile.in [new file with mode: 0644]
src/Makefile.in [new file with mode: 0644]

diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..adabbd3
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1 @@
+SALOME2 : MULTIPR module
diff --git a/MULTIPR_version.h.in b/MULTIPR_version.h.in
new file mode 100644 (file)
index 0000000..69335a1
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library is distributed in the hope that it will be useful 
+// but WITHOUT ANY WARRANTY; without even the implied warranty of 
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/
+//
+//  File   : MULTIPR_version.h
+//  Author : Vadim SANDLER
+//  Module : SALOME
+
+#if !defined(__MULTIPR_VERSION_H__)
+#define __MULTIPR_VERSION_H__
+
+/*
+  MULTIPR_VERSION is (major << 16) + (minor << 8) + patch.
+*/
+
+#define MULTIPR_VERSION_STR "@VERSION@"
+#define MULTIPR_VERSION     @XVERSION@
+
+#endif // __MULTIPR_VERSION_H__
diff --git a/Makefile.in b/Makefile.in
new file mode 100644 (file)
index 0000000..1eeeb2f
--- /dev/null
@@ -0,0 +1,121 @@
+#  Copyright (C) 2005  CEA/DEN, EDF R&D
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# -* Makefile *- 
+#
+# Author : C. Caremoli
+# Date : 10/10/2003
+# $Header$
+#
+
+# source path
+top_srcdir=@top_srcdir@
+top_builddir=.
+srcdir=@srcdir@
+VPATH=.:@srcdir@:@top_srcdir@/bin:./bin/salome:./resources:@top_srcdir@/resources:./bin:@top_srcdir@/idl
+
+
+@COMMENCE@
+
+SUBDIRS = idl src adm_local
+
+RESOURCES_FILES = MULTIPRCatalog.xml MULTIPR.png ExecMULTIPR.png MULTIPR_import_med.png MULTIPR_save_med.png SalomeApp.xml
+
+BIN_SCRIPT= VERSION runAppli myrunSalome.py
+
+# copy header files in common directory
+
+include_list = include/salome/SALOMEconfig.h \
+               include/salome/MULTIPR_version.h
+
+ifneq ($(HAVE_SSTREAM),yes)
+       include_list += include/salome/sstream
+endif
+
+inc: idl $(include_list)
+
+bin: bin/salome/VERSION
+
+bin/salome/VERSION : bin/VERSION
+       -$(RM) $@
+       $(LN_S) ../../$< $@
+
+include/salome/SALOMEconfig.h: salome_adm/unix/SALOMEconfig.ref
+       -$(RM) $@
+       $(LN_S) ../../$< $@
+
+# test if SALOMEconfig.h has changed (contents)
+salome_adm/unix/SALOMEconfig.ref: salome_adm/unix/SALOMEconfig.h
+       @if ! [ -a $@ ]; then \
+         cp -p $< $@;        \
+       fi;                   \
+       if ! cmp $< $@; then  \
+         cp -p $< $@;        \
+       fi;                   \
+
+include/salome/sstream: salome_adm/unix/sstream
+       -$(RM) $@
+       $(LN_S) ../../$< $@
+
+include/salome/MULTIPR_version.h: MULTIPR_version.h
+       -$(RM) $@
+       $(LN_S) ../../$< $@
+
+depend: depend_idl
+
+depend_idl:
+       (cd idl ; $(MAKE) $@) || exit 1
+
+# doc is already build : if you want to had documents, go manually to doc and run 'make doc'
+#doc:
+#      (cd doc && $(MAKE) $@) || exit 1
+
+install-end:
+# finish libtool install
+#      @$(LT) --mode=finish $(libdir)
+
+install-include: $(include_list)
+       $(INSTALL) -d  $(includedir)
+       @for f in X $(include_list); do                         \
+          if test $$f != X; then                               \
+            ($(INSTALL_DATA) $$f $(includedir)/. || exit 1);   \
+          fi;                                                  \
+       done
+
+# install script in $(bindir) :
+install-bin: $(BIN_SCRIPT)
+       $(INSTALL) -d  $(bindir)
+       $(INSTALL_PROGRAM) $^ $(bindir)
+
+uninstall: uninstall-idl
+
+uninstall-idl:
+       $(RM) $(idldir)/*.idl
+
+distclean: distclean-other
+
+distclean-other:
+       -$(RM) salome_adm/unix/*~ salome_adm/unix/*% salome_adm/unix/*.bak salome_adm/unix/*.new salome_adm/unix/*.old
+       -$(RM) salome_adm/unix/make_* 
+       -$(RM) salome_adm/unix/depend salome_adm/unix/SALOMEconfig.h 
+       -$(RM) config.cache config.log config.status 
+
+@MODULE@
+
+install: install-bin install-include install-end
+
diff --git a/README b/README
new file mode 100755 (executable)
index 0000000..2e4ce3c
--- /dev/null
+++ b/README
@@ -0,0 +1,228 @@
+MODULE SALOME MULTIPR
+=====================
+Par EDF/CS, 02/2007
+
+
+Description
+-----------
+MULTIPR est un module pour la plateforme SALOME (v3.2).
+Le module sert au partitionnement et a la decimation de maillages tetraedriques (TETRA10),
+dans le but de pouvoir visualiser d'importants volumes de donnees.
+
+
+Contenu de ce fichier
+---------------------
+I.    INSTALLATION/COMPILATION
+II.   L'APPLICATION AUTONOME EN LIGNE DE COMMANDE multipr
+III   LE MODULE SALOME MULTIPR
+
+
+*******************************************************************************
+*
+* I. INSTALLATION/COMPILATION
+*
+*******************************************************************************
+
+A. Information generales
+------------------------
+MULTIPR a besoin des prerequis suivants:
+    1. Salome V3.2
+    2. MESPLITTER (branche CVS WP1_2_3_17-01-2007_Data_format_at_entry_of_visualization_pipeline)
+    3. MED fichier v2.3
+    4. METIS v4.0.1 (version NON modifiee par EDF)
+    5. SCOTCH v4
+
+A propos de MEDSPLITTER :
+MEDSPLITTER est un partitionneur de fichiers MED qui repose sur le format MED v2.3
+et les outils METIS et SCOTCH. L'outil a ete developpe par Vincent Bergeaud du CEA.
+Dans le cadre du module MULTIPR, MEDSPLITTER est utilise pour partitionner des grains
+(scenario a 2 echelles).
+    
+
+
+B. Installation/compilation
+---------------------------
+
+
+   B.1. Se procurer le module MED/MEDSPLITTER compatible avec MULTIPR
+   ------------------------------------------------------------------
+   
+1. Charger la branche CVS WP1_2_3_17-01-2007_Data_format_at_entry_of_visualization_pipeline dans le repertoire MED sur le server d'OpenCascade
+   > cvs -d ":pserver:salome2anonymous@www.opencascade.com:/home/server/cvs/MED" login
+   rntlrntl   (<--- mot de passe)
+   > cvs -d ":pserver:salome2anonymous@www.opencascade.com:/home/server/cvs/MED" checkout -kk -RP -r WP1_2_3_17-01-2007_Data_format_at_entry_of_visualization_pipeline MED_SRC
+   > cvs -d ":pserver:salome2anonymous@www.opencascade.com:/home/server/cvs/MED" logout
+   (note : MEDPLITTER peut également être compilé à partir de la branche CVS BR_SPLITTER_improved)
+   
+2. Modifier le code pour utiliser MED fichier v2.3 :
+   A. Supprimer les 6 fichiers suivants :
+      MED_SRC/src/medmem/MEDMEM_MEDMEMchampLire.hxx/cxx
+      MED_SRC/src/medmem/MEDMEM_MEDMEMgaussEcr.hxx/cxx
+      MED_SRC/src/medmem/MEDMEM_MEDMEMprofilEcr.hxx/cxx
+   B. Mettre a jour le fichier medmem/Makefile.in en supprimant les 6 lignes correspondantes
+   C. Mettre a jour le fichier MEDMEM_MedFieldDriver22.hxx
+      1. Dans la section "includes, supprimer les 3 lignes #include "MEDMEM_MEDMEMchampLire.hxx" ...
+      2. Remplacer ces lignes par l'inclusion de l'API MED :
+         namespace med_2_2 
+         {
+             extern "C" 
+            { 
+                 #include <med.h>
+                 #include <med_proto.h>
+             }
+         }
+      3. Effectuer les changements suivants (utiliser l'API MED fichier v2.3) :
+         MEDMEMchampLire -> MEDchampLire
+         MEDMEMgaussEcr  -> MEDgaussEcr
+         MEDMEMprofilEcr -> MEDprofilEcr
+         => En tout, il y a 4 lignes a changer
+      
+
+   B.2. Prerequis a la compilation du module MED/MEDSPLITTER
+   ---------------------------------------------------------
+   
+3. Verifier que la variable d'environnement LD_LIBRARY_PATH ne pointe pas vers un repertoire MED
+4. Verifier que la variable d'environnement MED_ROOT_DIR n'est pas definie
+5. Installer METIS v4.0.1 (soit <METIS_DIR> le repertoire d'installation)
+   A. Charger le source sur http://glaros.dtc.umn.edu/gkhome/metis/metis/download
+   B. Decompresser l'archive : tar -zxvz metis-4.0.tar.gz
+   C. Puis make dans le repertoire
+   D. Verifier que tout est OK : depuis \Graph, lancer ./mtest 4elt.graph
+6. Verifier que la bibliotheque boost v1.32 ou + est installee
+   A. Bien verifier que le paquet libboost_program_option est inclu (ce paquet est utilise par MEDSPLITTER)
+   B. Ajouter la variable d'environnement export BOOSTDIR=/usr, si nécessaire
+   C. Si necessaire, dans /usr/lib, ajouter le lien 
+      ln -s libboost_program_options.so libboost_program_options-gcc-mt.so
+      (droits administrateur necessaires)
+      
+
+   B.3. Compilation du module MED/MEDSPLITTER
+   ------------------------------------------
+   
+7. Pour compiler la branche MED WP1_2_3_17-01-2007_Data_format_at_entry_of_visualization_pipeline avec SALOME V3.2.2 (Debian Sarge)
+   Dans le repertoire SALOME v3.2.2 :
+   A. Sourcer prerequis-Sarge-slash-usr.sh et envSalome-V3_2_2.sh
+   B. Verifier que la variable d'environnement MED2HOME pointe bien vers
+      MED fichier v2.3
+8. Pour compiler avec METIS v4.0.1 precedemment charge : 
+   Renommer la fonction log2 en log2_ dans metis\lib\proto.h  
+   (sinon, un conflit se produit)
+   
+Depuis le repertoire contenant WP1_2_3_17-01-2007_Data_format_at_entry_of_visualization_pipeline :
+9. Creer un repertoire Build et un repertoire MED au cote de MED_SRC
+10. Dans le repertoire MED_SRC, faire ./build_configure
+11. Depuis le repertoire Build, faire (en remplacant les <...> par les bons répertoires) 
+    ../MED_SRC/configure --prefix=<PATH>/MED --enable-splitter=yes --with-metis=<METIS_DIR> --with-scotch=<SCOTCH_DIR>
+    --enable-production=yes --disable-debug  
+12. Puis : make
+13. Puis : make install
+
+
+   B.4. Tester l'installation du module MED/MEDSPLITTER
+   ----------------------------------------------------
+   
+14. Definir la variable d'environnement MED_ROOT_DIR (=<PATH>/MED)
+15. Eventuellement, mettre a jour les variables d'environnement LD_LIBRARY_PATH et PYTHONPATH
+16. Pour verifier que MEDMEM est bien installe :
+    Depuis le repertoire <PATH>/MED : python bin/salome/testMedMemGeneral.py
+17. Pour verifier que MEDSPLITTER est bien installe :
+    A. Dans <PATH>/MED/bin/salome, creer le repertoire tests : mkdir tests
+    B. Puis : 
+       ./test_SPLITTER_indivisible
+       ./test_SPLITTER_square
+       ./medsplitter --input-file=<PATH>/MED/share/salome/resources/med/pointe_import22.med --output-file=toto --ndomains=2 --meshname=maa1
+
+
+   B.5. Compiler le module MULTIPR
+   -------------------------------
+   
+18. Creer un repertoire Build et un repertoire MULTIPR au cote de MULTIPR_SRC
+19. Dans le repertoire MULTIPR_SRC, faire ./build_configure
+20. Depuis le repertoire Build, faire (en remplacant les <...> par les bons répertoires) 
+    ../MULTIPR_SRC/configure --prefix=<PATH>/MULTIPR --enable-production=yes --disable-debug  
+21. Puis : make
+22. Puis : make install
+    
+
+*******************************************************************************
+*
+* II. L'APPLICATION AUTONOME EN LIGNE DE COMMANDE multipr
+*
+*******************************************************************************
+
+Tests de l'application autonome en ligne de commande multipr
+------------------------------------------------------------
+L'application "multipr" se trouve dans .../bin/salome
+
+1. Affichage de la page d'aide
+   
+   $ ./multipr 
+   
+2. Autotest complet de l'application
+
+   $ ./multipr --auto /data
+   (ou /data designe le repertoire dans lequel se trouve le fichier agregat100grains_12pas.med)
+   
+3. Affichage de la liste des maillages et des champs d'un fichier MED sequentiel :
+  
+   $ ./multipr --info agregat100grains_12pas.med
+   
+4. Affichage de toutes les informations concernant un maillage :
+   
+   $ ./multipr --info agregat100grains_12pas.med MAIL
+   
+5. Partitionnement (1 echelle) : 
+   Extraction des grains du maillage MAIL dans le fichier agregat100grains_12pas.med
+   
+   $ ./multipr --part1 agregat100grains_12pas.med MAIL
+   
+6. Partitionnement (2 echelles) :
+   Decoupage du grain numero 98 en 3 parties :
+   
+   $ ./multipr --part2 agregat100grains_12pas_grains_maitre.med MAIL_98 3
+   
+7. Decimation :
+   Creation de 3 resolutions du grain numero 99 en prenant :
+   comme reference le 12e pas de temps du champ SIG_____SIEF_ELGA_______________
+   comme seuil pour la resolution MEDIUM : 10
+   comme seuil pour la resolution BASSE : 25
+   comme rayon pour le calcul du voisinage : 0.3
+   
+   $ ./multipr --decim agregat100grains_12pas_grains_maitre.med MAIL_99 SIG_____SIEF_ELGA_______________ 12 Filtre_GradientMoyen 10 25 0.3 
+
+8. Messages d'erreur :
+   Les exemples suivants sont des commandes erronees :
+   
+   $ ./multipr --part1 agregat100grains_12pas.m MAIL
+   ... MULTIPR: FileNotFoundException (MULTIPR_Mesh.cxx, line 663): MED file not found
+   
+   $ ./multipr --part1 agregat100grains_12pas.med MAILLAGE
+   ... MULTIPR: IllegalStateException (MULTIPR_Mesh.cxx, line 747): mesh not found in the given MED file
+   
+   $ ./multipr --part2 agregat100grains_12pas.med MAIL 2
+   ... MULTIPR: IOException (MULTIPR_API.cxx, line 106): waiting for a distributed MED file (not a sequential one)
+   
+   $ ./multipr --part2 agregat100grains_12pas_grains_maitre.med MAIL_95 0
+   ... MULTIPR: IllegalArgumentException (MULTIPR_API.cxx, line 97): pNbParts should be >= 2
+
+   $ ./multipr --decim agregat100grains_12pas_grains_maitre.med MAIL_99 SIG_____SIEF_ELGA_______________ 14 Filtre_GradientMoyen 10 25 0.3 
+   ... MULTIPR: IllegalArgumentException (MULTIPR_DecimationFilter.cxx, line 100): invalid field iteration (14)
+   
+   $ ./multipr --decim agregat100grains_12pas_grains_maitre.med MAIL_99 SIG_____SIEF_ELGA___________TEST 12 Filtre_GradientMoyen 10 25 0.3 
+   MULTIPR: IllegalArgumentException (MULTIPR_DecimationFilter.cxx, line 99): field not found
+
+   etc.
+   
+
+*******************************************************************************
+*
+* III. LE MODULE SALOME MULTIPR
+*
+*******************************************************************************   
+   
+Lancer le module salome seul : ./bin/salome/runAppli depuis le repertoire MULTIPR
+
+
+
+
+
diff --git a/adm_local/Makefile.in b/adm_local/Makefile.in
new file mode 100644 (file)
index 0000000..cfbe6f4
--- /dev/null
@@ -0,0 +1,59 @@
+#  Copyright (C) 2005  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
+#
+# source path
+top_srcdir=@top_srcdir@
+top_builddir=..
+srcdir=@srcdir@
+VPATH=.:$(srcdir)/adm_local
+
+
+all: resources
+
+install:
+       cp -rf @top_srcdir@/adm_local @prefix@
+
+bin:
+
+resources :
+       cp -rf @top_srcdir@/adm_local $(top_builddir)
+
+inc:
+
+lib:
+
+depend:
+
+depend_idl:
+
+install-end:
+
+install-include:
+
+install-bin:
+
+uninstall:
+
+uninstall-idl:
+
+distclean:
+
+clean:
+
+distclean-other:
+
diff --git a/adm_local/unix/config_files/check_MULTIPR.m4 b/adm_local/unix/config_files/check_MULTIPR.m4
new file mode 100755 (executable)
index 0000000..91816f8
--- /dev/null
@@ -0,0 +1,53 @@
+#  Check availability of MULTIPR module binary distribution
+#
+#  Author : Olivier LE ROUX (CS, 2006)
+#------------------------------------------------------------
+
+AC_DEFUN([CHECK_MULTIPR],[
+
+AC_CHECKING(for Multipr)
+
+Multipr_ok=no
+
+AC_ARG_WITH(multipr,
+           --with-multipr=DIR root directory path of MULTIPR installation,
+           MULTIPR_DIR="$withval",MULTIPR_DIR="")
+
+if test "x$MULTIPR_DIR" = "x" ; then
+
+# no --with-gui-dir option used
+
+  if test "x$MULTIPR_ROOT_DIR" != "x" ; then
+
+    # MULTIPR_ROOT_DIR environment variable defined
+    MULTIPR_DIR=$MULTIPR_ROOT_DIR
+
+  else
+
+    # search multipr binaries in PATH variable
+    AC_PATH_PROG(TEMP, libMULTIPR.so)
+    if test "x$TEMP" != "x" ; then
+      MULTIPR_BIN_DIR=`dirname $TEMP`
+      MULTIPR_DIR=`dirname $MULTIPR_BIN_DIR`
+    fi
+
+  fi
+#
+fi
+
+if test -f ${MULTIPR_DIR}/lib/salome/libMULTIPR.so  ; then
+  Multipr_ok=yes
+  AC_MSG_RESULT(Using MULTIPR distribution in ${MULTIPR_DIR})
+
+  if test "x$MULTIPR_ROOT_DIR" == "x" ; then
+    MULTIPR_ROOT_DIR=${MULTIPR_DIR}
+  fi
+  AC_SUBST(MULTIPR_ROOT_DIR)
+else
+  AC_MSG_WARN("Cannot find compiled MULTIPR distribution")
+fi
+  
+AC_MSG_RESULT(for MULTIPR: $Multipr_ok)
+])dnl
diff --git a/adm_local/unix/make_commence.in b/adm_local/unix/make_commence.in
new file mode 100644 (file)
index 0000000..4d769e4
--- /dev/null
@@ -0,0 +1,278 @@
+# common directories to put headerfiles
+inc_builddir=$(top_builddir)/include/salome
+
+MODULE_NAME=@MODULE_NAME@
+
+@SET_MAKE@
+SHELL=/bin/sh
+
+# header missing
+
+HAVE_SSTREAM=@HAVE_SSTREAM@
+
+
+LIBS=@LIBS@ 
+LDFLAGS=@LDFLAGS@ -L$(top_builddir)/lib@LIB_LOCATION_SUFFIX@/salome -Xlinker -rpath-link -Xlinker $(top_builddir)/lib@LIB_LOCATION_SUFFIX@/salome
+# add libstdc++ to link c++ library with libtool !
+LDFLAGS+= -lstdc++
+
+CP=@CP@
+
+# CPP
+
+CPP=@CPP@
+CXXCPP=@CXXCPP@
+CPPFLAGS=@CPPFLAGS@ -I$(inc_builddir) -I$(srcdir) -I.
+
+# C
+
+CC = @CC@
+CFLAGS = @CFLAGS@
+C_DEPEND_FLAG = @C_DEPEND_FLAG@
+
+# C++
+
+CXX = @CXX@
+CXXFLAGS = @CXXFLAGS@ 
+CXX_DEPEND_FLAG = @CXX_DEPEND_FLAG@
+
+# BOOST Library
+
+BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
+
+# JAVA
+
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_LIBS = @JAVA_LIBS@
+JAVA_LDPATH = @JAVA_LDPATH@
+
+# PYTHON
+
+PYTHON = @PYTHON@
+PYTHONHOME = @PYTHONHOME@
+PYTHON_INCLUDES = @PYTHON_INCLUDES@
+PYTHON_LIBS = @PYTHON_LIBS@
+PYTHON_VERSION = @PYTHON_VERSION@
+PYTHON_SITE = $(prefix)/lib@LIB_LOCATION_SUFFIX@/python$(PYTHON_VERSION)/site-packages
+PYTHON_SITE_INSTALL = $(prefix)/lib@LIB_LOCATION_SUFFIX@/python$(PYTHON_VERSION)/site-packages/salome
+
+# QT
+
+QT_ROOT = @QT_ROOT@
+QT_INCLUDES = @QT_INCLUDES@
+QT_MT_INCLUDES = @QT_INCLUDES@ -DQT_THREAD_SUPPORT
+QT_LIBS = @QT_LIBS@
+QT_MT_LIBS = @QT_MT_LIBS@
+
+MOC = @MOC@
+UIC = @UIC@
+
+# msg2qm
+
+MSG2QM = @MSG2QM@
+
+#QWT
+
+QWT_INCLUDES=@QWT_INCLUDES@
+QWT_LIBS=@QWT_LIBS@
+
+# SIP
+SIP = @SIP@
+SIP_INCLUDES = @SIP_INCLUDES@
+SIP_LIBS = @SIP_LIBS@
+
+# PYQT
+PYQT_SIPS = @PYQT_SIPS@
+PYQT_LIBS = @PYQT_LIBS@
+
+# openGL
+OGL_INCLUDES=@OGL_INCLUDES@
+OGL_LIBS=@OGL_LIBS@
+
+# VTK
+VTK_INCLUDES=@VTK_INCLUDES@
+VTK_LIBS=@VTK_LIBS@
+
+# HDF5
+
+HDF5_INCLUDES=@HDF5_INCLUDES@
+HDF5_LIBS=@HDF5_LIBS@
+HDF5_MT_LIBS=@HDF5_MT_LIBS@
+
+# MED2
+
+MED2_INCLUDES=@MED2_INCLUDES@
+MED2_LIBS=@MED2_LIBS@
+MED2_MT_LIBS=@MED2_MT_LIBS@
+
+# OpenCasCade
+
+OCC_INCLUDES=@CAS_CPPFLAGS@
+OCC_CXXFLAGS=@CAS_CXXFLAGS@
+
+OCC_KERNEL_LIBS=@CAS_KERNEL@
+OCC_OCAF_LIBS=@CAS_OCAF@
+OCC_VIEWER_LIBS=@CAS_VIEWER@
+OCC_MODELER_LIBS=@CAS_MODELER@
+OCC_DATAEXCHANGE_LIBS=@CAS_DATAEXCHANGE@
+OCC_LIBS=@CAS_LDFLAGS@
+
+# MPICH
+
+MPICH_INCLUDES=@MPICH_INCLUDES@
+MPICH_LIBS=@MPICH_LIBS@
+
+# Swig C++ Python
+
+SWIG       = @SWIG@
+SWIG_FLAGS = @SWIG_FLAGS@ -I$(inc_builddir) -I$(srcdir) -I.
+
+# OMNIORB
+
+OMNIORB_ROOT        = @OMNIORB_ROOT@
+OMNIORB_INCLUDES    = @OMNIORB_INCLUDES@
+OMNIORB_LIBS        = @OMNIORB_LIBS@
+OMNIORB_CXXFLAGS    = @OMNIORB_CXXFLAGS@
+
+OMNIORB_IDL         = @OMNIORB_IDL@
+OMNIORB_IDLCXXFLAGS = @OMNIORB_IDLCXXFLAGS@
+OMNIORB_IDLPYFLAGS  = @OMNIORB_IDLPYFLAGS@ -I$(top_srcdir)/idl -I$(top_builddir)/idl -I$(KERNEL_ROOT_DIR)/idl/salome
+
+OMNIORB_IDL_CLN_H   = @OMNIORB_IDL_CLN_H@
+OMNIORB_IDL_CLN_CXX = @OMNIORB_IDL_CLN_CXX@
+OMNIORB_IDL_CLN_OBJ = @OMNIORB_IDL_CLN_OBJ@
+
+OMNIORB_IDL_SRV_H   = @OMNIORB_IDL_SRV_H@
+OMNIORB_IDL_SRV_CXX = @OMNIORB_IDL_SRV_CXX@
+OMNIORB_IDL_SRV_OBJ = @OMNIORB_IDL_SRV_OBJ@
+
+# Default ORB
+
+CORBA_ROOT        = @CORBA_ROOT@
+CORBA_INCLUDES    = @CORBA_INCLUDES@
+CORBA_LIBS        = @CORBA_LIBS@
+CORBA_CXXFLAGS    = @CORBA_CXXFLAGS@
+
+IDLCXXFLAGS = -bcxx @IDLCXXFLAGS@ -I$(top_srcdir)/idl -I$(top_builddir)/idl -I$(KERNEL_ROOT_DIR)/idl/salome
+IDLPYFLAGS  = @IDLPYFLAGS@
+
+IDL = @IDL@
+
+IDL_CLN_H   = @IDL_CLN_H@
+IDL_CLN_CXX = @IDL_CLN_CXX@
+IDL_CLN_OBJ = @IDL_CLN_OBJ@
+
+IDL_SRV_H   = @IDL_SRV_H@
+IDL_SRV_CXX = @IDL_SRV_CXX@
+IDL_SRV_OBJ = @IDL_SRV_OBJ@
+
+CPPFLAGS+= $(CORBA_INCLUDES) 
+CXXFLAGS+= $(CORBA_CXXFLAGS)
+
+# add corba libs when link salome application ! 
+#LDFLAGS+= $(CORBA_LIBS)
+LIBS+=$(CORBA_LIBS)
+
+## Shared libraries
+LT_STATIC_EXEC=@LT_STATIC_EXEC@
+DYNAMIC_DIRS=@DYNAMIC_DIRS@
+LT_LIB=libtool
+LT=$(top_builddir)/libtool
+LT_COMPILE=$(LT) --mode=compile $(CC)
+LT_LINK_LIB=$(LT_LIB) --mode=link $(CC) -rpath $(libdir)
+LT_LINK_EXE=$(LT) --mode=link $(CC) $(LT_STATIC_EXEC) -dlopen self -rpath $(bindir) $(DYNAMIC_DIRS)
+LT_RUN=$(LT) --mode=execute
+LT_INSTALL_PROG=$(LT) --mode=install $(INSTALL_PROGRAM)
+LT_INSTALL_LIB=$(LT) --mode=install $(INSTALL_DATA)
+LT_UNINSTALL=$(LT) --mode=uninstall $(RM)
+
+INSTALL=@INSTALL@
+INSTALL_PROGRAM=@INSTALL_PROGRAM@
+INSTALL_DATA=@INSTALL_DATA@
+
+# create a symbolic link (or a copie ?)
+LN_S=@LN_S@
+
+KERNEL_ROOT_DIR=@KERNEL_ROOT_DIR@
+KERNEL_SITE_DIR=@KERNEL_SITE_DIR@
+KERNEL_LDFLAGS=@KERNEL_LDFLAGS@
+KERNEL_CXXFLAGS=@KERNEL_CXXFLAGS@
+
+GUI_ROOT_DIR=@GUI_ROOT_DIR@
+GUI_LDFLAGS=@GUI_LDFLAGS@
+GUI_CXXFLAGS=@GUI_CXXFLAGS@
+
+## Installation points
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+bindir=@bindir@/salome
+libdir=@exec_prefix@/lib@LIB_LOCATION_SUFFIX@/salome
+# warning : if user give this path in configure we could have salome/salome :-(
+includedir=@includedir@/salome
+datadir=@datadir@/salome
+idldir=$(prefix)/idl/salome
+sharedpydir=@exec_prefix@/lib@LIB_LOCATION_SUFFIX@/python$(PYTHON_VERSION)/site-packages/salome/shared_modules
+
+docdir=$(datadir)/doc
+
+#
+# begin of package rules
+#
+
+.PHONY: all lib bin inc resources tests install uninstall dep depend depend_idl cleandep mostlyclean clean distclean
+
+.SUFFIXES: .cxx .cc .c .f .o .lo .idl .py .i .ui .po .qm
+
+all:
+       $(MAKE) inc
+       $(MAKE) depend_idl
+       $(MAKE) depend
+       $(MAKE) lib
+       $(MAKE) bin
+       $(MAKE) resources
+
+#
+# add target to build administrative files
+#
+
+Makefile: $(top_builddir)/config.status $(srcdir)/Makefile.in
+       cd $(top_builddir) ; ./config.status
+
+LOCAL_MAKE = make_commence make_omniorb
+
+KERNEL_MAKE = make_module make_conclude depend SALOMEconfig.h F77config.h sstream envScript
+
+$(top_builddir)/config.status: $(top_srcdir)/configure \
+                              $(LOCAL_MAKE:%=$(top_srcdir)/adm_local/unix/%.in) \
+                              $(KERNEL_MAKE:%=$(KERNEL_ROOT_DIR)/salome_adm/unix/%.in)
+       cd $(top_builddir) ; ./config.status --recheck
+
+# VPATH contain $(srcdir), so make configure is good in top_srcdir and we must add target configure otherwise :-)
+ifneq ($(top_srcdir),$(srcdir))
+configure: $(top_srcdir)/configure
+endif
+
+$(top_srcdir)/configure: $(top_srcdir)/configure.in $(top_srcdir)/aclocal.m4
+       cd $(top_srcdir) ; autoconf
+
+$(top_srcdir)/configure.in: $(top_srcdir)/configure.in.base
+       cd $(top_srcdir) && ./build_configure
+
+
+ACLOCAL_KERNEL = \
+ac_cxx_bool.m4                    check_corba.m4                       \
+ac_cxx_depend_flag.m4             check_hdf5.m4      enable_pthreads.m4        \
+ac_cxx_mutable.m4                 check_mico.m4      libtool.m4                \
+ac_cxx_namespaces.m4              check_omniorb.m4   pyembed.m4                \
+ac_cxx_partial_specialization.m4  python.m4                            \
+ac_cxx_typename.m4                check_pthreads.m4  check_cas.m4      \
+ac_cc_warnings.m4                 check_swig.m4 
+
+ACLOCAL_GUI = \
+check_vtk.m4                      check_opengl.m4        check_qt.m4   \
+check_GUI.m4                      check_corba_in_GUI.m4
+
+$(top_srcdir)/aclocal.m4: $(ACLOCAL_KERNEL:%=@KERNEL_ROOT_DIR@/salome_adm/unix/config_files/%) \
+                          $(ACLOCAL_GUI:%=@GUI_ROOT_DIR@/adm_local/unix/config_files/%)
+       cd $(top_srcdir) ; aclocal -I adm_local/unix/config_files -I @KERNEL_ROOT_DIR@/salome_adm/unix/config_files \
+                                                                      -I @GUI_ROOT_DIR@/adm_local/unix/config_files
diff --git a/adm_local/unix/make_omniorb.in b/adm_local/unix/make_omniorb.in
new file mode 100644 (file)
index 0000000..c91ccbf
--- /dev/null
@@ -0,0 +1,52 @@
+#=======================================================================
+# Begin specific part to omniorb 
+# (include from file adm/unix/make_omniorb generated by 
+# adm/unix/make_omniorb.in)
+#=======================================================================
+# -* Makefile *- 
+#
+# Author : Patrick GOLDBRONN (CEA)
+# Date : 29/06/2001
+#
+
+# Client and server object are the same with omniorb
+# There are one header file and one source file generate
+
+#IDLOBJ=$(IDLSRC:%.idl=%$(IDL_CLN_OBJ))
+
+# dependancies between idl and it's generated files
+%$(OMNIORB_IDL_CLN_CXX) %$(OMNIORB_IDL_CLN_H): ${KERNEL_ROOT_DIR}/idl/salome/%.idl
+       $(OMNIORB_IDL) $(IDLCXXFLAGS) $(OMNIORB_IDLCXXFLAGS) $<
+
+%$(OMNIORB_IDL_CLN_CXX) %$(OMNIORB_IDL_CLN_H): ${top_srcdir}/idl/%.idl
+       $(OMNIORB_IDL) $(IDLCXXFLAGS) $(OMNIORB_IDLCXXFLAGS) $<
+
+# dependncies between idl files
+depend_idl: .depidl
+
+# we use cpp to generate dependencies between idl files.
+# we change cpp output to keep only idl file and transform it to get a suitable rule
+.depidl: $(IDL_FILES)
+       @touch $@
+       @for dep in $? dummy; do \
+         if [ $$dep != "dummy" ]; then \
+           echo Building dependencies for $$dep; \
+           basedep=`basename $$dep .idl`; \
+           header="$$basedep"$(IDL_CLN_H); \
+           sed '\%^'"$$header"':%,\%[^\\]$$%d' <$@ >$@- && mv $@- $@; \
+           $(CPP) $(C_DEPEND_FLAG) -I$(srcdir) $$dep 2>/dev/null | \
+           sed `echo "s%$$basedep\\.idl%$$header:%g"` | \
+           sed 's% $(srcdir)/% %g' | \
+           sed 's% $(top_srcdir)/% %g' | \
+           sed 's% $(top_builddir)/% %g' | \
+           sed 's%^.*:\.o: *%%' | sed 's%^ *\\ *%%'| sed 's%^ *\(.*\):%\1:%' | \
+           sed 's/\.idl/$(IDL_CLN_H)/' >>$@; \
+           echo ''  >>$@; \
+         fi; \
+       done ;
+
+-include .depidl
+
+#=======================================================================
+# End specific part to omniorb 
+#=======================================================================
diff --git a/bin/VERSION.in b/bin/VERSION.in
new file mode 100755 (executable)
index 0000000..8395447
--- /dev/null
@@ -0,0 +1 @@
+SALOME 2 MODULE C++ : MULTIPR : @VERSION@
diff --git a/bin/myrunSalome.py b/bin/myrunSalome.py
new file mode 100755 (executable)
index 0000000..e9d52c4
--- /dev/null
@@ -0,0 +1,162 @@
+#  Copyright (C) 2005  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
+#
+#!/usr/bin/env python
+
+def test(clt):
+   """
+        Test function that creates an instance of MULTIPR component
+        usage : multipr=test(clt)
+   """
+   # create an LifeCycleCORBA instance
+   import LifeCycleCORBA
+   lcc = LifeCycleCORBA.LifeCycleCORBA(clt.orb)
+   import MULTIPR_ORB
+   multipr = lcc.FindOrLoadComponent("FactoryServer", "MULTIPR")
+   return multipr
+
+   
+def multipr_test1(clt,path):
+   import LifeCycleCORBA
+   lcc = LifeCycleCORBA.LifeCycleCORBA(clt.orb)
+   import MULTIPR_ORB
+   engine = lcc.FindOrLoadComponent("FactoryServer", "MULTIPR")
+   m = engine.getObject(path+'/agregat100grains_12pas.med')
+   liste_champs = m.getFields()
+   for i in liste_champs:
+      m.getTimeStamps(i)
+   liste_maillages = m.getMeshes()
+   m.setMesh(liste_maillages[0])
+   m.partitionneDomaine()
+   m.getParts()
+   m.save()
+   m.decimePartition('MAIL_99', 'SIG_____SIEF_ELGA_______________', 12, 'Filtre_GradientMoyen', 10, 25, 0.3)
+   liste_grains = m.getParts()
+   m.save()
+   m.partitionneGrain('MAIL_98', 3, 0)
+   m.save()
+   m.getParts()
+   m.getMeshes()
+   m.getFields()
+
+
+def multipr_test2(clt,path):
+   import LifeCycleCORBA
+   lcc = LifeCycleCORBA.LifeCycleCORBA(clt.orb)
+   import MULTIPR_ORB
+   engine = lcc.FindOrLoadComponent("FactoryServer", "MULTIPR")
+   m = engine.getObject(path+'/agregat100grains_12pas.med')
+   m.getMeshes()
+   m.setMesh('MAIL')
+   m.partitionneDomaine()
+   m.getParts()
+   liste_champs = m.getFields()
+   m.getTimeStamps(liste_champs[3])
+   m.decimePartition('MAIL_99', 'SIG_____SIEF_ELGA_______________', 12, 'Filtre_GradientMoyen', 10, 25, 0.3)
+   m.save()
+   m.getMeshes()
+   m.getParts()
+   m.getFields()
+   
+      
+def multipr_test3(clt,path):
+   import LifeCycleCORBA
+   lcc = LifeCycleCORBA.LifeCycleCORBA(clt.orb)
+   import MULTIPR_ORB
+   engine = lcc.FindOrLoadComponent("FactoryServer", "MULTIPR")
+   m = engine.getObject(path+'/agregat100grains_12pas.med')
+   m.setMesh('MAIL')
+   m.partitionneDomaine()
+   m.getParts()
+   liste_champs = m.getFields()
+   m.getTimeStamps(liste_champs[3])
+   m.decimePartition('MAIL_99', 'SIG_____SIEF_ELGA_______________', 12, 'Filtre_GradientMoyen', 10, 25, 0.3)
+   m.partitionneGrain('MAIL_1', 3, 0)
+   m.getParts()
+   #m.partitionneGrain('MAIL_2', 4, 1)
+   m.getMeshes()
+   m.getParts()
+   m.getFields()
+   m.save() 
+   
+      
+def multipr_test4(clt,path):
+   import LifeCycleCORBA
+   lcc = LifeCycleCORBA.LifeCycleCORBA(clt.orb)
+   import MULTIPR_ORB
+   engine = lcc.FindOrLoadComponent("FactoryServer", "MULTIPR")
+   m = engine.getObject(path+'/agregat100grains_12pas_grains_maitre.med')
+   m.getFields()
+   m.getParts()
+   for i in m.getParts():
+      m.partitionneGrain(i, 3, 0);
+
+
+def multipr_test5(clt,path):
+   import LifeCycleCORBA
+   lcc = LifeCycleCORBA.LifeCycleCORBA(clt.orb)
+   import MULTIPR_ORB
+   engine = lcc.FindOrLoadComponent("FactoryServer", "MULTIPR")
+   m = engine.getObject(path+'/agregat100grains_12pas.med')
+   liste_champs = m.getFields()
+   liste_maillages = m.getMeshes()
+   m.setMesh(liste_maillages[0])
+   liste_grains = m.partitionneDomaine()
+   for grain in liste_grains[0:4]:
+      m.decimePartition(grain, liste_champs[1], 12, 'Filtre_GradientMoyen', 10, 25, 0.3)
+   m.getParts()
+   m.save()
+   
+
+def multipr_test6(clt,path):
+   import LifeCycleCORBA
+   lcc = LifeCycleCORBA.LifeCycleCORBA(clt.orb)
+   import MULTIPR_ORB
+   engine = lcc.FindOrLoadComponent("FactoryServer", "MULTIPR")
+   m = engine.getObject(path+'/agregat100grains_12pas.med')
+   liste_champs = m.getFields()
+   liste_maillages = m.getMeshes()
+   m.setMesh(liste_maillages[0])
+   liste_grains = m.partitionneDomaine()
+   liste_pgrain = m.partitionneGrain(liste_grains[4], 16, 0)
+   m.setBoxing(10)
+   for grain in liste_pgrain[0:11]:
+      m.decimePartition(grain, liste_champs[1], 12, 'Filtre_GradientMoyen', 10, 25, 0.5)
+   m.getParts()
+   m.save()
+   n = engine.getObject(path+'/agregat100grains_12pas_grains_maitre.med')
+   n.getParts()
+   
+       
+if __name__ == "__main__":
+   import user
+   from runSalome import *
+   clt,args = main()
+   
+   #
+   #  Impression arborescence Naming Service
+   #
+   
+   if clt != None:
+     print
+     print " --- registered objects tree in Naming Service ---"
+     clt.showNS()
+     session=clt.waitNS("/Kernel/Session")
+     catalog=clt.waitNS("/Kernel/ModulCatalog")
+     import socket
+     container =  clt.waitNS("/Containers/" + socket.gethostname().split('.')[0] + "/FactoryServer")
diff --git a/bin/runAppli.in b/bin/runAppli.in
new file mode 100755 (executable)
index 0000000..99af375
--- /dev/null
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+if [ -z "${KERNEL_ROOT_DIR}" ] ; then 
+export KERNEL_ROOT_DIR=@KERNEL_ROOT_DIR@
+fi
+if [ -z "${MULTIPR_ROOT_DIR}" ] ; then 
+export MULTIPR_ROOT_DIR=@prefix@
+fi
+
+searchFreePort() {
+    echo -n "Searching for a free port for naming service: "
+    export NSPORT=2810
+    local limit=$NSPORT
+    let limit=limit+100
+    while [ 1 ]
+    do
+        aRes=`netstat -ltn | grep -E :${NSPORT}`
+        if [ -z "$aRes" ]; then
+            echo ${NSPORT} - Ok
+            local myhost=`hostname`
+            export OMNIORB_CONFIG=${HOME}/.omniORB_${myhost}_${NSPORT}.cfg
+            local initref="NameService=corbaname::"`hostname`":$NSPORT"
+            if [[ `python -c "import CORBA; print CORBA.ORB_ID"` = "omniORB4" ]]; then
+                echo "InitRef = $initref" > $OMNIORB_CONFIG
+            else
+                echo "ORBInitRef $initref" > $OMNIORB_CONFIG
+            fi
+            break
+        fi
+        echo -n "${NSPORT} "
+        if [[ $NSPORT -eq $limit ]] ; then
+            echo
+            echo "Can't find a free port to launch omniNames"
+            echo "Try to kill the running servers and then launch SALOME again."
+            exit
+        fi
+        let NSPORT=NSPORT+1
+    done
+}
+
+searchFreePort
+
+
+${KERNEL_ROOT_DIR}/bin/salome/envSalome.py python -i $MULTIPR_ROOT_DIR/bin/salome/myrunSalome.py --modules=MULTIPR --containers=cpp,python --killall
diff --git a/build_configure b/build_configure
new file mode 100755 (executable)
index 0000000..9aa3637
--- /dev/null
@@ -0,0 +1,242 @@
+#!/bin/bash
+
+#
+# Tool for updating list of .in file for the SALOME project 
+# and regenerating configure script
+#
+# Author : Marc Tajchman - CEA
+# Date : 10/10/2002
+# $Header $
+#
+
+ORIG_DIR=`pwd`
+CONF_DIR=`echo $0 | sed -e "s,[^/]*$,,;s,/$,,;s,^$,.,"`
+
+########################################################################
+# Test if the KERNEL_ROOT_DIR is set correctly
+
+if test ! -d "${KERNEL_ROOT_DIR}"; then
+    echo "failed : KERNEL_ROOT_DIR variable is not correct !"
+    exit
+fi
+
+########################################################################
+# Test if the GUI_ROOT_DIR is set correctly
+
+if test ! -d "${GUI_ROOT_DIR}"; then
+    echo "failed : GUI_ROOT_DIR variable is not correct !"
+    exit
+fi
+
+########################################################################
+# Test if the MED_ROOT_DIR is set correctly
+
+if test ! -d "${MED_ROOT_DIR}"; then
+    echo "failed : MED_ROOT_DIR variable is not correct !"
+    exit
+fi
+
+########################################################################
+# Test if the MED2HOME is set correctly
+
+if test ! -d "${MED2HOME}"; then
+    echo "failed : MED2HOME variable is not correct !"
+    exit
+fi
+
+########################################################################
+# Test if the HDF5HOME is set correctly
+
+if test ! -d "${HDF5HOME}"; then
+    echo "failed : HDF5HOME variable is not correct !"
+    exit
+fi
+
+########################################################################
+# find_in - utility function
+#
+# usage :  
+#    find_in directory filename 
+#
+# Finds files following the *.in pattern, recursively in the
+# directory (first argument).
+# Results are appended into the file (second argument)
+#
+# Difference from the standard unix find is that files are tested
+# before directories
+# 
+
+find_in()
+{
+  local i
+  local f=$2
+
+# if the first argument is not a directory, returns
+
+  if [ ! -d "$1" ] ; then 
+     return 
+  fi
+
+# dont look in the CVS directories
+
+  case $1 in
+    */CVS) return ;;
+    */adm_local/*) return ;;
+    *) ;;
+  esac
+
+# for each regular file contained in the directory
+# test if it's a .in file
+
+  for i in "$1"/*
+  do
+     if [ -f "$i" ] ; then
+       case $i in 
+         *.in) echo $i" \\" >> $f;;
+         *) ;;
+        esac
+     fi
+  done
+
+# for each subdirectory of the first argument, proceeds recursively
+
+  for i in "$1"/*
+  do
+     if [ -d "$i" ] ; then
+        find_in "$i" "$f"
+     fi
+  done
+}
+
+
+#######################################################################
+# Generate list of .in files (Makefile.in, config.h.in, etc)
+# appending it in file configure.in
+
+cd ${CONF_DIR}
+ABS_CONF_DIR=`pwd`
+
+#
+# Common part of the configure.in file
+#
+chmod u+w configure.in.base
+if ! \cp -f configure.in.base configure.in_tmp1 
+then
+       echo
+       echo "error : can't create files in" ${CONF_DIR}
+       echo "aborting ..."
+        chmod u-w configure.in.base 
+       exit
+fi
+chmod u-w configure.in.base 
+
+if [ -e "${CONF_DIR}/salome_adm" ] ; then
+    \rm -f ${CONF_DIR}/salome_adm
+fi
+
+# make a link allowing AC_OUTPUT to find the salome_adm/.../*.in  files
+echo "" >> configure.in_tmp1
+echo 'ln -fs ${KERNEL_ROOT_DIR}/salome_adm ${ROOT_SRCDIR}' >> configure.in_tmp1
+
+echo  "" >> configure.in_tmp1
+echo "AC_OUTPUT([ \\" >> configure.in_tmp1
+
+#
+# List of .in files in the adm/unix directory
+# These files MUST be on top of AC_OUTPUT list so we
+# put them "manually"
+#
+
+echo "./salome_adm/unix/SALOMEconfig.h \\" >> configure.in_tmp1
+echo "./salome_adm/unix/F77config.h \\" >> configure.in_tmp1
+echo "./salome_adm/unix/sstream \\" >> configure.in_tmp1
+echo "./salome_adm/unix/depend \\" >> configure.in_tmp1
+echo "./adm_local/unix/make_omniorb:${ABS_CONF_DIR}/adm_local/unix/make_omniorb.in \\" >> configure.in_tmp1
+echo "./salome_adm/unix/envScript \\" >> configure.in_tmp1
+echo "./adm_local/unix/make_commence:${ABS_CONF_DIR}/adm_local/unix/make_commence.in \\" >> configure.in_tmp1
+echo "./salome_adm/unix/make_conclude \\" >> configure.in_tmp1
+echo "./salome_adm/unix/make_module \\" >> configure.in_tmp1
+
+\rm -f configure.in_tmp2
+touch configure.in_tmp2
+find_in . configure.in_tmp2
+
+sed -e '/^...salome_adm/d'    \
+    -e '/configure.in/d'      \
+    -e '/^...adm_local/d'     \
+    -e 's/.in / /'            \
+    configure.in_tmp2  >>  configure.in_tmp1
+
+echo  "])" >> configure.in_tmp1
+
+# delete the link created for AC_OUTPUT
+echo "" >> configure.in_tmp1
+\mv configure.in_tmp1 configure.in_new
+\rm  -f configure.in_tmp2 
+
+
+########################################################################
+# Create new (or replace old) configure.in file
+# Print a message if the file is write protected
+#
+
+echo
+if test ! -f configure.in
+then
+       echo -n "Creating new file 'configure.in' ... "
+       if \mv configure.in_new configure.in >& /dev/null
+       then
+               echo "done"
+       else
+               echo "error, check your file permissions"
+       fi
+else
+       echo -n "Updating 'configure.in' file ... "
+       if ! \cp configure.in configure.in_old >& /dev/null
+       then
+               echo
+               echo
+               echo "Can't backup previous configure.in"
+               echo -n "Continue (you will not be able to revert) - (Y/N) ? "
+               read R
+                case "x$R" in
+                   xn*) exit;;
+                   xN*) exit;;
+               esac
+               echo
+               echo -n "                                 "
+       fi
+       if \cp configure.in_new configure.in >& /dev/null
+       then
+                \rm  -f configure.in_new
+               echo "done"
+       else
+               echo
+               echo "error, can't update previous configure.in"
+       fi
+fi
+
+########################################################################
+# Use autoconf to rebuild the configure script
+#
+
+if test -f configure
+then
+       echo -n "Updating 'configure' script ...  "
+else
+       echo -n "Creating 'configure' script ...  "
+fi
+
+aclocal -I adm_local/unix/config_files -I ${KERNEL_ROOT_DIR}/salome_adm/unix/config_files \
+                                       -I ${GUI_ROOT_DIR}/adm_local/unix/config_files \
+                                      -I ${MED_ROOT_DIR}/adm_local/unix/config_files
+if autoconf
+then
+       echo "done"
+else
+       echo "failed (check file permissions and/or user quotas ...)"
+fi
+
+cd ${ORIG_DIR}
+
+echo
diff --git a/configure.in.base b/configure.in.base
new file mode 100644 (file)
index 0000000..bfad732
--- /dev/null
@@ -0,0 +1,337 @@
+#
+#  PLEASE DO NOT MODIFY configure.in FILE
+#
+#  ALL CHANGES WILL BE DISCARDED BY THE NEXT
+#  build_configure COMMAND
+#
+#  CHANGES MUST BE MADE IN configure.in.base FILE
+#
+#
+# Author : Marc Tajchman (CEA)
+# Date : 28/06/2001
+# Modified by : Patrick GOLDBRONN (CEA)
+# Modified by : Marc Tajchman (CEA)
+#
+# Created from configure.in.base
+#
+
+AC_INIT(src)
+AC_CONFIG_AUX_DIR(${KERNEL_ROOT_DIR}/salome_adm/unix/config_files)
+AC_CANONICAL_HOST
+
+PACKAGE=salome
+AC_SUBST(PACKAGE)
+
+VERSION=3.2.2
+XVERSION=0x030202
+AC_SUBST(VERSION)
+AC_SUBST(XVERSION)
+
+# set up MODULE_NAME variable for dynamic construction of directories (resources, etc.)
+MODULE_NAME=multipr
+AC_SUBST(MODULE_NAME)
+
+dnl
+dnl Initialize source and build root directories
+dnl
+
+ROOT_BUILDDIR=`pwd`
+ROOT_SRCDIR=`echo $0 | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"`
+cd $ROOT_SRCDIR
+ROOT_SRCDIR=`pwd`
+cd $ROOT_BUILDDIR
+
+AC_SUBST(ROOT_SRCDIR)
+AC_SUBST(ROOT_BUILDDIR)
+
+echo
+echo Source root directory : $ROOT_SRCDIR
+echo Build  root directory : $ROOT_BUILDDIR
+echo
+echo
+
+if test -z "$AR"; then
+   AC_CHECK_PROGS(AR,ar xar,:,$PATH)
+fi
+AC_SUBST(AR)
+
+dnl Export the AR macro so that it will be placed in the libtool file
+dnl correctly.
+export AR
+
+echo
+echo ---------------------------------------------
+echo testing make
+echo ---------------------------------------------
+echo
+
+AC_PROG_MAKE_SET
+AC_PROG_INSTALL
+dnl 
+dnl libtool macro check for CC, LD, NM, LN_S, RANLIB, STRIP + for shared libraries
+
+AC_ENABLE_DEBUG(yes)
+AC_DISABLE_PRODUCTION
+
+echo ---------------------------------------------
+echo testing libtool
+echo ---------------------------------------------
+
+dnl first, we set static to no!
+dnl if we want it, use --enable-static
+AC_ENABLE_STATIC(no)
+
+AC_LIBTOOL_DLOPEN
+AC_PROG_LIBTOOL
+
+dnl Fix up the INSTALL macro if it s a relative path. We want the
+dnl full-path to the binary instead.
+case "$INSTALL" in
+   *install-sh*)
+      INSTALL='\${KERNEL_ROOT_DIR}'/salome_adm/unix/config_files/install-sh
+      ;;
+esac
+
+echo
+echo ---------------------------------------------
+echo testing C/C++
+echo ---------------------------------------------
+echo
+
+cc_ok=no
+dnl inutil car libtool
+dnl AC_PROG_CC
+AC_PROG_CXX
+AC_CXX_WARNINGS
+AC_CXX_TEMPLATE_OPTIONS
+AC_DEPEND_FLAG
+# AC_CC_WARNINGS([ansi])
+cc_ok=yes
+
+dnl Library libdl :
+AC_CHECK_LIB(dl,dlopen)
+
+dnl Library librt : for alpha/osf
+AC_CHECK_LIB(rt,nanosleep)
+
+dnl add library libm :
+AC_CHECK_LIB(m,ceil)
+
+AC_CXX_USE_STD_IOSTREAM
+AC_CXX_HAVE_SSTREAM
+
+dnl
+dnl ---------------------------------------------
+dnl testing linker
+dnl ---------------------------------------------
+dnl
+
+AC_LINKER_OPTIONS
+
+echo
+echo ---------------------------------------------
+echo testing threads
+echo ---------------------------------------------
+echo
+
+ENABLE_PTHREADS
+
+echo
+echo ---------------------------------------------
+echo testing python
+echo ---------------------------------------------
+echo
+
+CHECK_PYTHON
+
+echo
+echo ---------------------------------------------
+echo testing QT
+echo ---------------------------------------------
+echo
+
+CHECK_QT
+
+echo
+echo ---------------------------------------------
+echo testing msg2qm
+echo ---------------------------------------------
+echo
+
+CHECK_MSG2QM
+
+echo
+echo ---------------------------------------------
+echo BOOST Library
+echo ---------------------------------------------
+echo
+
+CHECK_BOOST
+
+echo
+echo ---------------------------------------------
+echo Testing OpenCascade
+echo ---------------------------------------------
+echo
+
+CHECK_CAS
+
+echo
+echo ---------------------------------------------
+echo testing omniORB
+echo ---------------------------------------------
+echo
+
+CHECK_OMNIORB
+
+echo
+echo ---------------------------------------------
+echo default ORB : omniORB
+echo ---------------------------------------------
+echo
+
+DEFAULT_ORB=omniORB
+CHECK_CORBA
+
+AC_SUBST_FILE(CORBA)
+corba=make_$ORB
+CORBA=adm_local/unix/$corba
+
+echo
+echo ---------------------------------------------
+echo Testing GUI
+echo ---------------------------------------------
+echo
+
+CHECK_SALOME_GUI
+
+echo
+echo ---------------------------------------------
+echo Testing full GUI
+echo ---------------------------------------------
+echo
+
+CHECK_CORBA_IN_GUI
+if test "x${CORBA_IN_GUI}" != "xyes"; then
+  echo "failed : For configure MULTIPR module necessary full GUI !"
+  exit
+fi
+
+echo
+echo ---------------------------------------------
+echo Testing Kernel
+echo ---------------------------------------------
+echo
+
+CHECK_KERNEL
+
+echo
+echo ---------------------------------------------
+echo Testing Med
+echo ---------------------------------------------
+echo
+
+CHECK_MED
+
+echo
+echo ---------------------------------------------
+echo testing HDF5
+echo ---------------------------------------------
+echo
+
+CHECK_HDF5
+
+echo
+echo ---------------------------------------------
+echo testing MED2
+echo ---------------------------------------------
+echo
+
+CHECK_MED2
+
+echo
+echo ---------------------------------------------
+echo Testing GUI
+echo ---------------------------------------------
+echo
+
+CHECK_SALOME_GUI
+
+echo
+echo ---------------------------------------------
+echo Summary
+echo ---------------------------------------------
+echo
+
+echo Configure
+variables="cc_ok threads_ok boost_ok python_ok omniORB_ok qt_ok msg2qm_ok Kernel_ok Med_ok hdf5_ok med2_ok SalomeGUI_ok"
+
+for var in $variables
+do
+   printf "   %10s : " `echo \$var | sed -e "s,_ok,,"`
+   eval echo \$$var
+done
+
+echo
+echo "Default ORB   : $DEFAULT_ORB"
+echo
+
+dnl generals files which could be included in every makefile
+
+AC_SUBST_FILE(COMMENCE) COMMENCE=adm_local/unix/make_commence
+AC_SUBST_FILE(CONCLUDE) CONCLUDE=salome_adm/unix/make_conclude
+AC_SUBST_FILE(MODULE) MODULE=salome_adm/unix/make_module
+
+dnl les dependences
+AC_SUBST_FILE(DEPEND) DEPEND=salome_adm/unix/depend
+
+dnl We don t need to say when we re entering directories if we re using
+dnl GNU make becuase make does it for us.
+if test "X$GMAKE" = "Xyes"; then
+   AC_SUBST(SETX) SETX=":"
+else
+   AC_SUBST(SETX) SETX="set -x"
+fi
+
+# make other build directories
+for rep in salome_adm adm_local doc bin/salome include/salome lib${LIB_LOCATION_SUFFIX}/salome share/salome/resources/${MODULE_NAME} share/salome/doc idl
+do
+    $INSTALL -d $rep
+done
+
+echo 
+echo ---------------------------------------------
+echo copying resource files, shell scripts, and 
+echo xml files
+echo ---------------------------------------------
+echo
+
+dnl copy shells and utilities contained in the bin directory
+dnl excluding .in files (treated in AC-OUTPUT below) and CVS 
+dnl directory
+
+cd bin
+for i in $ROOT_SRCDIR/bin/*
+do
+  local_bin=`echo $i | sed -e "s,$ROOT_SRCDIR,.,"`
+  case "$local_bin" in
+        *.in | *~)                    ;;
+        ./bin/CVS)                    ;;
+        *) ln -fs $i; echo $local_bin ;;
+  esac
+done
+cd $ROOT_BUILDDIR
+
+AC_SUBST_FILE(ENVSCRIPT) ENVSCRIPT=salome_adm/unix/envScript
+
+echo
+echo ---------------------------------------------
+echo generating Makefiles and configure files
+echo ---------------------------------------------
+echo
+
+AC_OUTPUT_COMMANDS([ \
+       chmod +x ./bin/* \
+])
+
+## do not delete this line
diff --git a/doc/CSSI_DRV_EDF-IOLS-MULTIPR_spec-conception_1_1.odt b/doc/CSSI_DRV_EDF-IOLS-MULTIPR_spec-conception_1_1.odt
new file mode 100755 (executable)
index 0000000..80f8063
Binary files /dev/null and b/doc/CSSI_DRV_EDF-IOLS-MULTIPR_spec-conception_1_1.odt differ
diff --git a/doc/CSSI_DRV_EDF-IOLS-MULTIPR_spec-conception_1_1.pdf b/doc/CSSI_DRV_EDF-IOLS-MULTIPR_spec-conception_1_1.pdf
new file mode 100755 (executable)
index 0000000..1584def
Binary files /dev/null and b/doc/CSSI_DRV_EDF-IOLS-MULTIPR_spec-conception_1_1.pdf differ
diff --git a/idl/MULTIPR.idl b/idl/MULTIPR.idl
new file mode 100644 (file)
index 0000000..19510b7
--- /dev/null
@@ -0,0 +1,230 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+// 
+// MULTIPR.idl
+// 
+// Interface CORBA for the MULTIPR module
+//
+// Author: Olivier LE ROUX - CS, Virtual Reality Dpt
+//
+// Date: 01/2007
+//
+
+#ifndef __MULTIPR_INTERFACE_CORBA__
+#define __MULTIPR_INTERFACE_CORBA__
+
+#include "SALOME_Exception.idl"
+#include "SALOME_Component.idl"
+#include "SALOME_GenericObj.idl"
+#include "SALOMEDS.idl" // to access study
+
+
+/*!  \ingroup MULTIPR
+ *
+ * This package contains the interface MULTIPR_ORB used for %MULTIPR component.
+ */
+module MULTIPR_ORB
+{
+
+
+typedef sequence<string> string_array;
+
+
+//*************************************************************************
+// Interface of the %MULTIPR component used to manage partition/decimation
+//*************************************************************************
+
+interface MULTIPR_Obj
+{
+
+       //---------------------------------------------------------------------
+       // Basic accessors/mutators
+       //--------------------------------------------------------------------
+       
+       /*!
+        * Return true iff this obj represents a valid sequential MED file.
+        */
+       boolean isValidSequentialMEDFile();
+       
+       /*!
+        * Return true iff this obj represents a valid distributed MED file.
+        */
+       boolean isValidDistributedMEDFile();
+       
+       /*!
+        * Set the mesh to be partitionned/decimated. 
+        * Assume sequential MED file.
+        */
+       void setMesh(in string meshName)
+               raises (SALOME::SALOME_Exception);
+
+       /*!
+        * Set the boxing parameter used for decimation (100 by default).
+        */
+       void setBoxing(in long boxing)
+               raises (SALOME::SALOME_Exception);
+       
+       /*!
+        * Return the list of meshes contained in the associated MED file.
+        */
+       string_array getMeshes()
+               raises (SALOME::SALOME_Exception);
+               
+       /*!
+        * Return the list of fields contained in the current mesh of the associated MED file.
+        */
+       string_array getFields()
+               raises (SALOME::SALOME_Exception);
+       
+       /*!
+        * Return the number of iterations for a given field.
+        */
+       long getTimeStamps(in string fieldName)
+               raises (SALOME::SALOME_Exception);
+
+       /*!
+        * Return the name of all partitions.
+        * Assume this object encapsulates a distributed MED file.
+        */
+       string_array getParts()
+               raises (SALOME::SALOME_Exception);
+
+       /*!
+        * Return all information abour a part.
+        * Assume this object encapsulates a distributed MED file.
+        */
+       string getPartInfo(in string partName)
+               raises (SALOME::SALOME_Exception);
+       
+       //---------------------------------------------------------------------
+       // Algorithms
+       //--------------------------------------------------------------------
+       
+       /*!
+        * Create a distributed MED file (v2.3) by extracting all the groups from the current mesh of the current MED sequential MED file.
+        * Assume:
+        * - the file is in MED format and can be read using MED file v2.3.
+        * - the file is sequential (not a distributed MED).
+        * - the file only contains TETRA10 elements (dimension of space and mesh is 3).
+        * - the file have no profil.
+        * \return the name of each part.
+        */
+       string_array partitionneDomaine()
+               raises (SALOME::SALOME_Exception);
+       
+       /*! 
+        * Create a distributed MED file (V2.3) by splitting a group of a MED file previously created by partitionneDomaine.
+        * Assume:
+        * - the file is a distributed MED file, previously created by partitionneDomaine()
+        *   (=> each part only contain 1 mesh, TETRA10 elements only)
+        * - nbPart > 1
+        * - partitionner METIS=0 or SCOTCH=1
+        * \return the name of each part.
+        */
+       string_array partitionneGrain(
+               in string partName, 
+               in long   nbParts, 
+               in long   partitionner)
+               raises (SALOME::SALOME_Exception);
+       
+       /*!
+        * Create 3 resolutions of the given part of a distributed MED file (V2.3).
+        * Assume:
+        * - the file is a distributed MED file, previously created by partitionneDomaine() or partitionneGrain()
+        *   (=> each part only contain 1 mesh, TETRA10 elements only)
+        */
+       string_array decimePartition(
+               in string partName,
+               in string fieldName,
+               in long   fieldIt,
+               in string filterName,
+               in double tmed,
+               in double tlow,
+               in double radius)
+               raises (SALOME::SALOME_Exception);
+       
+       //---------------------------------------------------------------------
+       // i/o
+       //--------------------------------------------------------------------
+       
+       /*!
+        * Save the current distributed MED file to disk.
+        */
+       void save()
+               raises (SALOME::SALOME_Exception);
+
+}; // interface MULTIPR_Obj
+
+
+//*************************************************************************
+// Interface of the %MULTIPR component; used to create MULTIPR_Obj object 
+// and to define high level API.
+//*************************************************************************
+interface MULTIPR_Gen : Engines::Component
+{
+       /*!
+        * Return the version of the MULTIPR library.
+        */
+       string getVersion()
+               raises (SALOME::SALOME_Exception);
+       
+       //------------------------------------------------------------------------
+       // High level API
+       // Directly apply one of the 3 main operations of the MULTIPR module on a MED file
+       //------------------------------------------------------------------------      
+
+       /*!         
+        * Create a distributed MED file (v2.3) by extracting all the groups from the mesh of a sequential MED file.
+        * High level function.
+        */
+       void partitionneDomaine(
+               in string medFilename, 
+               in string meshName)
+               raises (SALOME::SALOME_Exception);
+
+       /*!         
+        * Create a distributed MED file (V2.3) by splitting a group of a MED file previously created by partitionneDomaine().
+        * High level function.
+        */
+       void partitionneGrain(
+               in string medFilename, 
+               in string partName, 
+               in long   nbParts, 
+               in long   partitionner) // 0=METIS 1=SCOTCH
+               raises (SALOME::SALOME_Exception);
+
+       /*!         
+        * Creates 3 resolutions of the given part of a distributed MED file (V2.3).
+        * High level function.
+        */
+       void decimePartition(
+               in string medFilename, 
+               in string partName, 
+               in string fieldName,
+               in long   fieldIt,
+               in string filterName,
+               in double tmed,
+               in double tlow,
+               in double radius,
+               in long   boxing)
+               raises (SALOME::SALOME_Exception);
+
+       //------------------------------------------------------------------------
+       // Low level API
+       // Create an object to encapsulate a MED file.
+       //------------------------------------------------------------------------
+       
+       /*!
+        * Create a MULTIPR_Obj object which encapsulate a MED file.
+        */
+       MULTIPR_Obj getObject(in string medFilename)
+               raises (SALOME::SALOME_Exception);
+
+}; // interface MULTIPR_Gen
+  
+}; // module MULTIPR_ORB
+
+#endif // __MULTIPR_INTERFACE_CORBA__
+
diff --git a/idl/Makefile.in b/idl/Makefile.in
new file mode 100644 (file)
index 0000000..57b0c2f
--- /dev/null
@@ -0,0 +1,86 @@
+# Copyright (C) 2005  OPEN CASCADE, CEA, EDF R&D, LEG
+#           PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either 
+# version 2.1 of the License.
+# 
+# This library is distributed in the hope that it will be useful 
+# but WITHOUT ANY WARRANTY; without even the implied warranty of 
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+# Lesser General Public License for more details.
+# 
+# You should have received a copy of the GNU Lesser General Public  
+# License along with this library; if not, write to the Free Software 
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+# 
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+# 
+#
+# generate dependencies for idl file :
+#
+
+# source path
+top_srcdir=@top_srcdir@
+top_builddir=..
+srcdir=@srcdir@
+VPATH=.:${KERNEL_ROOT_DIR}/idl/salome
+
+@COMMENCE@
+
+IDL_FILES = \
+  MULTIPR.idl
+
+PY_CLIENT_IDL = $(IDL_FILES)
+
+# we copy all idl file in $(top_builddir)/idl
+inc: $(top_builddir)/idl/salome $(IDL_FILES:%=$(top_builddir)/idl/salome/%)
+
+$(top_builddir)/idl/salome:
+       mkdir $@
+
+$(IDL_FILES:%=$(top_builddir)/idl/salome/%):$(IDL_FILES:%=$(top_srcdir)/idl/%)
+#      $(CP) $< $@
+       cp -f $^ $(top_builddir)/idl/salome
+
+
+lib: pyidl
+
+PYTHON_BUILD_SITE=$(top_builddir)/lib@LIB_LOCATION_SUFFIX@/python$(PYTHON_VERSION)/site-packages/@PACKAGE@
+
+pyidl: $(PYTHON_BUILD_SITE) $(IDL_FILES:%.idl=$(PYTHON_BUILD_SITE)/%_idl.py)
+
+$(PYTHON_BUILD_SITE):
+       $(INSTALL) -d  $@
+
+$(PYTHON_BUILD_SITE)/%_idl.py: $(top_builddir)/idl/salome/%.idl
+       $(OMNIORB_IDL) $(OMNIORB_IDLPYFLAGS) -C$(PYTHON_BUILD_SITE) $<
+
+
+# install python client (generated from idl file
+install: install-pyidl install-idl
+
+# create directory $(idldir) and copy idl files into it
+install-idl: $(IDL_FILES:%=$(top_builddir)/idl/salome/%)
+       $(INSTALL) -d  $(idldir)
+       $(INSTALL_DATA) $^ $(idldir)
+
+
+install-pyidl: $(IDL_FILES:%=$(top_builddir)/idl/salome/%)
+       $(INSTALL) -d  $(PYTHON_SITE_INSTALL)
+       @for file in $^ dummy; do \
+         if [ $$file != "dummy" ]; then \
+           $(OMNIORB_IDL) $(OMNIORB_IDLPYFLAGS) -C$(PYTHON_SITE_INSTALL) $$file ; \
+         fi ; \
+       done ;
+
+#@ CONCLUDE @
+
+cleandep:
+       -$(RM) .dep*
+
+distclean:
+       -$(RM) *.py
+       -$(RM) $(IDL_FILES:%=$(top_builddir)/idl/salome/%)
+       -$(RM) Makefile
+
diff --git a/resources/ExecMULTIPR.png b/resources/ExecMULTIPR.png
new file mode 100644 (file)
index 0000000..436af1d
Binary files /dev/null and b/resources/ExecMULTIPR.png differ
diff --git a/resources/MULTIPR.png b/resources/MULTIPR.png
new file mode 100644 (file)
index 0000000..436af1d
Binary files /dev/null and b/resources/MULTIPR.png differ
diff --git a/resources/MULTIPRCatalog.xml.in b/resources/MULTIPRCatalog.xml.in
new file mode 100644 (file)
index 0000000..5ee10c9
--- /dev/null
@@ -0,0 +1,59 @@
+<?xml version='1.0' encoding='us-ascii' ?>
+<!-- XML component catalog -->
+<begin-catalog>
+
+<!-- Path prefix information -->
+
+<path-prefix-list>
+</path-prefix-list>
+
+<!-- Component list -->
+<component-list>
+       <component>
+               <!-- Component identification -->
+               <component-name>MULTIPR</component-name>
+               <component-username>MULTIPR GUI</component-username>
+               <component-type>Data</component-type>
+               <component-author>O. Le Roux</component-author>
+               <component-version>@VERSION@</component-version>
+               <component-comment>CS/EDF-RD</component-comment>
+               <component-multistudy>1</component-multistudy>
+               <component-icone>MULTIPR.png</component-icone>
+               <constraint>'linux' ~ OS</constraint>
+               
+               <!-- component interface list -->
+               <component-interface-list>
+                       <!-- component interface identification -->
+                       <component-interface-name>MULTIPR</component-interface-name>
+                       <component-interface-comment>No comment</component-interface-comment>
+
+                       <!-- Component service list-->
+                       <component-service-list>
+                           <component-service>
+                                       <service-name>getObject</service-name>
+                                       <service-author>O. Le Roux</service-author>
+                                       <service-version>1.0.0</service-version>
+                                       <service-comment></service-comment>
+                                       <inParameter-list>
+                                               <inParameter>
+                                                       <inParameter-name>MEDfilename</inParameter-name>
+                                                       <inParameter-type>string</inParameter-type>
+                                                       <inParameter-comment>Name of the MED file to be processed</inParameter-comment>
+                                               </inParameter>
+                                       </inParameter-list>
+                                       <outParameter-list>
+                                               <outParameter>
+                                               <outParameter-name>return</outParameter-name>
+                                               <outParameter-type>MULTIPR_Obj</outParameter-type>
+                                               <outParameter-comment></outParameter-comment>
+                                               </outParameter>
+                                       </outParameter-list>
+                           </component-service>    
+                       </component-service-list>
+                       
+               </component-interface-list>
+               
+       </component>
+</component-list>
+</begin-catalog>
diff --git a/resources/MULTIPR_import_med.png b/resources/MULTIPR_import_med.png
new file mode 100644 (file)
index 0000000..d9953b6
Binary files /dev/null and b/resources/MULTIPR_import_med.png differ
diff --git a/resources/MULTIPR_save_med.png b/resources/MULTIPR_save_med.png
new file mode 100644 (file)
index 0000000..330493f
Binary files /dev/null and b/resources/MULTIPR_save_med.png differ
diff --git a/resources/SalomeApp.xml b/resources/SalomeApp.xml
new file mode 100644 (file)
index 0000000..3e52145
--- /dev/null
@@ -0,0 +1,11 @@
+<document>
+  <section name="MULTIPR">
+    <!-- Major module parameters -->
+    <parameter name="name" value="Multipr"/>
+    <parameter name="icon" value="MULTIPR.png"/>
+  </section>
+  <section name="resources">
+    <!-- Module resources -->
+    <parameter name="MULTIPR" value="${MULTIPR_ROOT_DIR}/share/salome/resources/multipr"/>
+  </section>
+</document>
diff --git a/src/MULTIPR/MULTIPR_API.cxx b/src/MULTIPR/MULTIPR_API.cxx
new file mode 100644 (file)
index 0000000..5c5fda5
--- /dev/null
@@ -0,0 +1,193 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_API.cxx
+ *
+ * \brief   see MULTIPR_API.hxx
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+#include "MULTIPR_API.hxx"
+#include "MULTIPR_Globals.hxx"
+#include "MULTIPR_Mesh.hxx"
+#include "MULTIPR_MeshDis.hxx"
+#include "MULTIPR_Utils.hxx"
+#include "MULTIPR_Exceptions.hxx"
+
+extern "C"
+{
+       #include "med.h"
+}
+
+#include "MEDSPLITTER_API.hxx"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+using namespace std;
+
+
+//*****************************************************************************
+// Implementation
+//*****************************************************************************
+
+const char* multipr::getVersion()
+{
+       return "1.0";
+}
+
+
+void multipr::partitionneDomaine(const char* pMEDfilename, const char* pMeshName)
+{      
+       if (pMEDfilename == NULL) throw NullArgumentException("pMEDfilename should not be NULL", __FILE__, __LINE__);
+       if (pMeshName == NULL)    throw NullArgumentException("pMeshName should not be NULL", __FILE__, __LINE__);
+       
+       //---------------------------------------------------------------------
+       // Read the sequential mesh
+       //---------------------------------------------------------------------
+       cout << "Read sequential MED file: " << pMEDfilename << ": please wait... " << endl;
+       
+       multipr::Mesh mesh;
+       mesh.readSequentialMED(pMEDfilename, pMeshName);
+       cout << mesh << endl;
+       
+       //---------------------------------------------------------------------
+       // Build distributed mesh from groups
+       //---------------------------------------------------------------------
+       cout << "Build distributed mesh: please wait... " << endl;
+       multipr::MeshDis* meshDis = NULL;
+       try
+       {
+               meshDis = mesh.splitGroupsOfElements();
+       
+               //-------------------------------------------------------------
+               // Write distributed mesh
+               //-------------------------------------------------------------
+               cout << "Write distributed mesh: please wait... " << endl;
+               string strPrefix = removeExtension(pMEDfilename, ".med");       
+               meshDis->writeDistributedMED(strPrefix.c_str());
+               
+               delete meshDis;
+       }
+       catch (RuntimeException& e)
+       {
+               delete meshDis;
+               throw e;
+       }
+}
+
+
+void multipr::partitionneGrain(
+       const char* pMEDfilename, 
+       const char* pGroupName, 
+       int         pNbParts, 
+       int         pPartitionner)
+{
+       if (pMEDfilename == NULL) throw NullArgumentException("pMEDfilename should not be NULL", __FILE__, __LINE__);
+       if (pGroupName == NULL)   throw NullArgumentException("pGroupName should not be NULL", __FILE__, __LINE__);
+       if (pNbParts < 2)         throw IllegalArgumentException("pNbParts should be >= 2", __FILE__, __LINE__);
+       if ((pPartitionner != MULTIPR_METIS) && (pPartitionner != MULTIPR_SCOTCH)) throw NullArgumentException("pPartitionner should be METIS (0) or SCOTCH (1)", __FILE__, __LINE__);
+       
+       //---------------------------------------------------------------------
+       // Read the distributed mesh
+       //---------------------------------------------------------------------
+       MULTIPR_LOG("Read distributed MED file: " << pMEDfilename << ": please wait... " << endl);
+       
+       int ret = MEDformatConforme(pMEDfilename);
+       if (ret == 0) throw IOException("waiting for a distributed MED file (not a sequential one)", __FILE__, __LINE__);
+
+       multipr::MeshDis meshDis;
+       meshDis.readDistributedMED(pMEDfilename);
+       cout << meshDis << endl;
+       
+       //---------------------------------------------------------------------
+       // Split the given part (pGroupName)
+       //---------------------------------------------------------------------
+       if (pPartitionner == MULTIPR_METIS)
+       {
+               cout << "Use METIS" << endl;
+       }
+       else if (pPartitionner == MULTIPR_SCOTCH)
+       {
+               cout << "Use SCOTCH" << endl;
+       }
+       
+       meshDis.splitPart(pGroupName, pNbParts, pPartitionner);
+       cout << meshDis << endl;
+       
+       //---------------------------------------------------------------------
+       // Write new distributed mesh
+       //---------------------------------------------------------------------
+       string strPrefix = multipr::removeExtension(pMEDfilename, ".med");
+       meshDis.writeDistributedMED(strPrefix.c_str());
+}
+
+
+void multipr::decimePartition(
+       const char* pMEDfilename,
+       const char* pPartName,
+       const char* pFieldName,
+       int         pFieldIt,
+       const char* pFilterName,
+       double      pTMed,
+       double      pTLow,
+       double      pRadius,
+       int         pBoxing)
+{
+       //---------------------------------------------------------------------
+       // Check arguments
+       //---------------------------------------------------------------------
+       if (pMEDfilename == NULL) throw NullArgumentException("pMEDfilename should not be NULL", __FILE__, __LINE__);
+       if (pPartName == NULL) throw NullArgumentException("pPartName should not be NULL", __FILE__, __LINE__);
+       if (pFieldName == NULL) throw NullArgumentException("pFieldName should not be NULL", __FILE__, __LINE__);
+       if (pFieldIt < 1) throw IllegalArgumentException("pFieldIt: invalid field iteration; should be >= 1", __FILE__, __LINE__);
+       if (pTMed < 0.0) throw IllegalArgumentException("med res.: threshold must be > 0", __FILE__, __LINE__);
+       if (pTMed >= pTLow) throw IllegalArgumentException("threshold for med res. must be < threshold for low res.", __FILE__, __LINE__);
+       if (pRadius <= 0.0) throw IllegalArgumentException("radius should be > 0", __FILE__, __LINE__);
+       if ((pBoxing < 1) || (pBoxing > 200)) throw IllegalArgumentException("boxing should be in [1..200]", __FILE__, __LINE__);
+       
+       cout << "--decim file=" << pMEDfilename << " part=" << pPartName << " filter=" << pFilterName << " tmed=" << pTMed << " tlow=" << pTLow << " radius=" << pRadius << endl;
+       
+       //---------------------------------------------------------------------
+       // Read the distributed mesh
+       //---------------------------------------------------------------------
+       MULTIPR_LOG("Read distributed MED file: " << pMEDfilename << ": please wait... " << endl);
+
+       int ret = MEDformatConforme(pMEDfilename);
+       if (ret == 0) throw IOException("waiting for a distributed MED file (not a sequential one)", __FILE__, __LINE__);
+       
+       multipr::MeshDis meshDis;
+       meshDis.readDistributedMED(pMEDfilename);
+       cout << meshDis << endl;
+       
+       //---------------------------------------------------------------------
+       // Create 3 resolutions of the given part
+       //---------------------------------------------------------------------
+       meshDis.decimatePart(
+               pPartName, 
+               pFieldName,
+               pFieldIt,
+               pFilterName,
+               pTMed,
+               pTLow,
+               pRadius,
+               pBoxing);
+       cout << meshDis << endl;
+       
+       //---------------------------------------------------------------------
+       // Write new distributed mesh
+       //---------------------------------------------------------------------
+       string strPrefix = removeExtension(pMEDfilename, ".med"); // get prefix from the original MED filename  
+       meshDis.writeDistributedMED(strPrefix.c_str());
+}
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_API.hxx b/src/MULTIPR/MULTIPR_API.hxx
new file mode 100644 (file)
index 0000000..8c42885
--- /dev/null
@@ -0,0 +1,108 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_API.hxx
+ *
+ * \brief   Main header of the high level MULTIPR API.
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#ifndef MULTIPR_API_HXX
+#define MULTIPR_API_HXX
+
+
+namespace multipr
+{
+
+
+enum Partitionner
+{
+       MULTIPR_METIS   = 0,
+       MULTIPR_SCOTCH  = 1
+       
+}; // enum Partitionner
+
+
+/**
+ * \fn     const char* getVersion()
+ * \brief  returns the current version of the MULTIPR API.
+ * \return the current version of the MULTIPR API. 
+ */
+const char* getVersion();
+
+
+/**
+ * \fn     int partitionneDomaine(const char* medFilename, const char* meshName)
+ * \brief  creates a distributed MED file (v2.3) by extracting all the groups from the mesh of a sequential MED file.
+ *         Assumes:
+ *         - the file is in MED format and can be read using MED file v2.3.
+ *         - the file is sequential (not a distributed MED).
+ *         - the file only contains TETRA10 elements (dimension of space and mesh is 3).
+ *         - the file have no profil.
+ * \param  medFilename filename of any valid sequential MED file with TETRA10 elements only.
+ * \param  meshName    name of the mesh to be distributed.
+ * \throw  RuntimeException if any error occurs.
+ */
+void partitionneDomaine(
+       const char* medFilename, 
+       const char* meshName);
+
+
+/**
+ * \fn     int partitionneGrain(const char* medFilename, const char* groupName, int nbParts, int partitionner)
+ * \brief  creates a distributed MED file (V2.3) by splitting a group of a MED file previously created by partitionneDomaine.
+ *         Assumes:
+ *         - the file is a distributed MED file, previously created by partitionneDomaine()
+ *           (=> each part only contain 1 mesh, TETRA10 elements only)
+ *         - nbPart > 1
+ * \param  medFilename  filename of any valid distributed MED file previously created by partitionneDomaine(). 
+ * \param  partName     name of the part to be splitted.
+ * \param  nbParts      number of parts; must be > 1.
+ * \param  partitionner use value MULTIPR_METIS for Metis or MULTIPR_SCOTCH for Scotch.
+ * \throw  RuntimeException if any error occurs.
+ */
+ void partitionneGrain(
+       const char* medFilename, 
+       const char* partName, 
+       int         nbParts, 
+       int         partitionner=MULTIPR_METIS);
+
+/**
+ * \fn     int decimePartition(const char* medFilename, const char* partName, const char* fieldName, int fieldIt, const char* filterName, double tmed, double tlow, double radius);
+ * \brief  creates 3 resolutions of the given part of a distributed MED file (V2.3).
+ *         Assumes:
+ *         - the file is a distributed MED file, previously created by partitionneDomaine() or partitionneGrain()
+ *           (=> each part only contain 1 mesh, TETRA10 elements only)
+ * \param  medFilename filename of any valid distributed MED file previously created by partitionneDomaine or partitionneGrain.
+ * \param  partName    name of the part to be decimated.
+ * \param  fieldName   name of the field used for decimation.
+ * \param  fieldIt     iteration (time step) of the field.
+ * \param  filterName  name of the filter to be used.
+ * \param  tmed        threshold used for medium resolution.
+ * \param  tlow        threshold used for low resolution; tmed must be less than tlow
+ * \param  radius      radius used to determine the neighbourhood.
+ * \param  boxing      number of cells along each axis; must be >= 1; e.g. if 100 then acceleration grid will have 100*100*100 = 10**6 cells.
+ * \throw  RuntimeException if any error occurs.
+ */
+void decimePartition(
+       const char* medFilename,
+       const char* partName,
+       const char* fieldName,
+       int         fieldIt,
+       const char* filterName,
+       double      tmed,
+       double      tlow,
+       double      radius,
+       int         boxing);
+
+} // namespace MULTIPR
+
+
+#endif // MULTIPR_API_HXX
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_DecimationAccel.cxx b/src/MULTIPR/MULTIPR_DecimationAccel.cxx
new file mode 100644 (file)
index 0000000..080613a
--- /dev/null
@@ -0,0 +1,325 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_DecimationAccel.cxx
+ *
+ * \brief   see MULTIPR_DecimationAccel.hxx
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+#include "MULTIPR_DecimationAccel.hxx"
+#include "MULTIPR_PointOfField.hxx"
+#include "MULTIPR_Exceptions.hxx"
+
+#include <iostream>
+
+using namespace std;
+
+
+namespace multipr
+{
+
+
+//*****************************************************************************
+// Class DecimationAccel implementation
+//*****************************************************************************
+
+
+ostream& operator<<(ostream& pOs, DecimationAccel& pA)
+{
+       pOs << "DecimationAccel:" << endl;
+       return pOs;
+}
+
+
+//*****************************************************************************
+// Class DecimationAccelGrid
+//*****************************************************************************
+
+DecimationAccelGrid::DecimationAccelGrid() 
+{
+       mGrid = NULL;
+       
+       reset();
+}
+
+
+DecimationAccelGrid::~DecimationAccelGrid()  
+{ 
+       reset();
+}
+
+
+void DecimationAccelGrid::reset()
+{
+       mNum = 0;
+       
+       mMin[0] = numeric_limits<med_float>::quiet_NaN();
+       mMin[1] = numeric_limits<med_float>::quiet_NaN();
+       mMin[2] = numeric_limits<med_float>::quiet_NaN();
+       
+       mMax[0] = numeric_limits<med_float>::quiet_NaN();
+       mMax[1] = numeric_limits<med_float>::quiet_NaN();
+       mMax[2] = numeric_limits<med_float>::quiet_NaN();
+       
+       mInvLen[0] = numeric_limits<med_float>::quiet_NaN();
+       mInvLen[1] = numeric_limits<med_float>::quiet_NaN();
+       mInvLen[2] = numeric_limits<med_float>::quiet_NaN();
+       
+       mSize[0] = 0;
+       mSize[1] = 0;
+       mSize[2] = 0;
+       
+       if (mGrid != NULL)
+       {
+               delete[] mGrid;
+               mGrid = NULL;
+       }
+       
+       mFlagPrintAll = false;
+}
+
+
+void DecimationAccelGrid::create(const std::vector<PointOfField>& pPts)
+{
+       // check if grid have been initialized
+       if (mSize[0] == 0) throw IllegalStateException("call setSize() before", __FILE__, __LINE__);
+       
+       // compute bbox of the grid
+       computeBBox(pPts);
+       
+       // allocate the grid
+       int size = mSize[0] * mSize[1] * mSize[2];
+       mGrid = new vector<PointOfField>[size];
+       
+       // fill the grid
+       mNum = pPts.size();
+       for (int i = 0 ; i < mNum ; i++)
+       {
+               vector<PointOfField>& cell = getCell(pPts[i]);
+               cell.push_back(pPts[i]);
+       }
+}
+
+
+void DecimationAccelGrid::configure(const char* pArgv)
+{
+       // check arguments
+       if (pArgv == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       
+       int sizeX = 0;
+       int sizeY = 0;
+       int sizeZ = 0;
+       
+       int ret = sscanf(pArgv, "%d %d %d", &sizeX, &sizeY, &sizeZ);
+       
+       if (ret != 3) throw IllegalArgumentException("expected 3 parameters", __FILE__, __LINE__);
+       if (sizeX <= 0) throw IllegalArgumentException("number of cells along X-axis must be > 0", __FILE__, __LINE__);
+       if (sizeY <= 0) throw IllegalArgumentException("number of cells along Y-axis must be > 0", __FILE__, __LINE__);
+       if (sizeZ <= 0) throw IllegalArgumentException("number of cells along Z-axis must be > 0", __FILE__, __LINE__);
+       
+       reset();
+       
+       mSize[0] = sizeX;
+       mSize[1] = sizeY;
+       mSize[2] = sizeZ;
+}
+
+
+void DecimationAccelGrid::getCellCoord(
+               med_float pX, med_float pY, med_float pZ,
+               int* pIx, int* pIy, int* pIz) const
+{
+       med_float cx = (pX - mMin[0]) * mInvLen[0];
+       med_float cy = (pY - mMin[1]) * mInvLen[1];
+       med_float cz = (pZ - mMin[2]) * mInvLen[2];
+       
+       *pIx = med_int(cx);
+       if (*pIx >= mSize[0]) *pIx = mSize[0] - 1;
+       else if (*pIx < 0) *pIx = 0;
+       
+       *pIy = med_int(cy);
+       if (*pIy >= mSize[1]) *pIy = mSize[1] - 1;
+       else if (*pIy < 0) *pIy = 0;
+       
+       *pIz = med_int(cz);
+       if (*pIz >= mSize[2]) *pIz = mSize[2] - 1;
+       else if (*pIz < 0) *pIz = 0;
+}
+
+
+int DecimationAccelGrid::getCellIndex(int pI, int pJ, int pK) const
+{      
+       int index = pK * (mSize[0] * mSize[1]) + pJ * mSize[0] + pI;
+       
+       return index;
+}
+
+
+vector<PointOfField>& DecimationAccelGrid::getCell(const PointOfField& pPt)
+{
+       int ix, iy, iz;
+       
+       getCellCoord(
+               pPt.mXYZ[0], pPt.mXYZ[1], pPt.mXYZ[2],
+               &ix, &iy, &iz);
+       
+       int index = getCellIndex(ix, iy, iz);
+       
+       return mGrid[index];
+}
+
+
+vector<PointOfField> DecimationAccelGrid::findNeighbours(
+       med_float pCenterX,
+       med_float pCenterY,
+       med_float pCenterZ,
+       med_float pRadius) const
+{      
+       //---------------------------------------------------------------------
+       // Determine the axis aligned bounding box of the sphere ((x, y, z), r)
+       //---------------------------------------------------------------------
+       med_float sphereBBoxMin[3];
+       med_float sphereBBoxMax[3];
+       
+       sphereBBoxMin[0] = pCenterX - pRadius;
+       sphereBBoxMin[1] = pCenterY - pRadius;
+       sphereBBoxMin[2] = pCenterZ - pRadius;
+
+       sphereBBoxMax[0] = pCenterX + pRadius;
+       sphereBBoxMax[1] = pCenterY + pRadius;
+       sphereBBoxMax[2] = pCenterZ + pRadius;
+
+       //---------------------------------------------------------------------
+       // Determine the cells of the grid intersected by the sphere ((x, y, z), r)
+       // => range of cells are [iMinCell[0], iMaxCell[0]] x [iMinCell[1], iMaxCell[1]] x [iMinCell[2], iMaxCell[2]]
+       //---------------------------------------------------------------------
+       int iMinCell[3];
+       int iMaxCell[3];
+
+       getCellCoord(sphereBBoxMin[0], sphereBBoxMin[1], sphereBBoxMin[2], 
+               &iMinCell[0], &iMinCell[1], &iMinCell[2]);
+
+       getCellCoord(sphereBBoxMax[0], sphereBBoxMax[1], sphereBBoxMax[2], 
+               &iMaxCell[0], &iMaxCell[1], &iMaxCell[2]);
+
+       //---------------------------------------------------------------------
+       // Collect points of the field which are in the sphere
+       //---------------------------------------------------------------------
+       vector<PointOfField> res;
+       
+/*
+// debug
+cout << "Center = " << pCenterX << " " << pCenterY << " " << pCenterZ << endl;
+cout << "Radius = " << pRadius << endl;
+cout << "Visited cells : [" << iMinCell[0] << " ; " << iMaxCell[0] << "] x ["<< iMinCell[1] << " ; " << iMaxCell[1] << "] x [" << iMinCell[2] << " ; " << iMaxCell[2] << "]" << endl;
+*/
+       
+       // for all the cells in the grid intersected by the sphere ((x, y, z), r)
+       for (int i = iMinCell[0] ; i <= iMaxCell[0] ; i++)
+       {
+               for (int j = iMinCell[1] ; j <= iMaxCell[1] ; j++)
+               {
+                       for (int k = iMinCell[2] ; k <= iMaxCell[2] ; k++)
+                       {
+                               int idCell = getCellIndex(i, j, k);
+
+//printf("DEBUG: visited cell(%d %d %d) -> %d\n", i, j, k, idCell);
+
+                               vector<PointOfField>& cell = mGrid[idCell];
+                       
+                               // for all the points in the current cell
+                               for (vector<PointOfField>::const_iterator itPoint = cell.begin() ; itPoint != cell.end() ; itPoint++)
+                               {
+                                       const PointOfField& currentPt = *itPoint;
+                                       
+                                       // test if currentPt is in the sphere ((x, y, z), r)
+                                       med_float vecX = currentPt.mXYZ[0] - pCenterX;
+                                       med_float vecY = currentPt.mXYZ[1] - pCenterY;
+                                       med_float vecZ = currentPt.mXYZ[2] - pCenterZ;
+                                       
+                                       med_float norm = med_float( sqrt( vecX*vecX + vecY*vecY + vecZ*vecZ ) );
+                                       if (norm < pRadius)
+                                       {
+                                               // only add the point if it is different from (x, y, z)
+                                               if ((currentPt.mXYZ[0] != pCenterX) ||
+                                                   (currentPt.mXYZ[1] != pCenterY) ||
+                                                   (currentPt.mXYZ[2] != pCenterZ))
+                                               {
+                                                       res.push_back(currentPt);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return res;
+}
+
+
+void DecimationAccelGrid::computeBBox(const std::vector<PointOfField>& pPts)
+{
+       for (int itDim = 0 ; itDim < 3 ; itDim++) 
+       { 
+               mMin[itDim] = numeric_limits<med_float>::max();
+               mMax[itDim] = -mMin[itDim];
+       }
+       
+       for (unsigned i = 0 ; i < pPts.size() ; i++)
+       {
+               for (int itDim = 0 ; itDim < 3 ; itDim++)
+               {
+                       med_float coord = pPts[i].mXYZ[itDim];
+                       if (coord < mMin[itDim]) mMin[itDim] = coord;
+                       if (coord > mMax[itDim]) mMax[itDim] = coord;
+               }
+       }
+
+       mInvLen[0] = med_float(mSize[0]) / (mMax[0] - mMin[0]);
+       mInvLen[1] = med_float(mSize[1]) / (mMax[1] - mMin[1]);
+       mInvLen[2] = med_float(mSize[2]) / (mMax[2] - mMin[2]);
+}
+
+
+ostream& operator<<(ostream& pOs, DecimationAccelGrid& pG)
+{
+       pOs << "DecimationAccelGrid:" << endl;
+       pOs << "    Num=" << pG.mNum << endl;
+       pOs << "    Size=" << pG.mSize[0] << " x " << pG.mSize[1] << " x " << pG.mSize[2] << endl;
+       pOs << "    BBox=[" << pG.mMin[0] << " ; " << pG.mMax[0] << "] x [" << pG.mMin[1] << " ; " << pG.mMax[1] << "] x [" << pG.mMin[2] << " ; " << pG.mMax[2] << "]" << endl;
+       pOs << "    Inv len.=" << pG.mInvLen[0] << " ; " << pG.mInvLen[1] << " ; " << pG.mInvLen[2] << endl;
+       
+       if (pG.mFlagPrintAll)
+       {
+               int checkNumCells = 0;
+               int numCells = pG.mSize[0] * pG.mSize[1] * pG.mSize[2];
+               for (int i = 0 ; i < numCells ; i++)
+               {
+                       vector<PointOfField>& cell = pG.mGrid[i];
+                       cout << "    Cell " << i << ": #=" << cell.size() << ": " << endl;
+                       for (unsigned j = 0 ; j < cell.size() ; j++)
+                       {
+                               cout << "        " << cell[j] << endl;
+                       }
+                       checkNumCells += cell.size();
+               }
+               
+               if (pG.mNum != checkNumCells) throw IllegalStateException("", __FILE__, __LINE__);
+       }
+       
+       return pOs;
+}
+
+
+} // namespace multipr
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_DecimationAccel.hxx b/src/MULTIPR/MULTIPR_DecimationAccel.hxx
new file mode 100644 (file)
index 0000000..f85f846
--- /dev/null
@@ -0,0 +1,258 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_DecimationAccel.hxx
+ *
+ * \brief   Interface DecimationAccel: acceleration structure used for decimation.
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#ifndef MULTIPR_DECIMATION_ACCEL_HXX
+#define MULTIPR_DECIMATION_ACCEL_HXX
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+extern "C"
+{
+       #include "med.h"
+}
+
+#include <iostream>
+#include <vector>
+
+
+namespace multipr
+{
+
+//*****************************************************************************
+// Predeclaration
+//*****************************************************************************
+
+class PointOfField;
+
+
+//*****************************************************************************
+// Interface DecimationAccel
+//*****************************************************************************
+
+class DecimationAccel
+{      
+public:
+       
+       /** 
+        * Builds an empty DecimationAccel (default constructor).
+        */
+       DecimationAccel() { /* do nothing */ }
+       
+       /**
+        * Destructor. Removes everything.
+        */
+       virtual ~DecimationAccel() { /* do nothing */ } 
+       
+       //---------------------------------------------------------------------
+       // Algorithms
+       //---------------------------------------------------------------------
+       
+       /**
+        * Interface. Configures this acceleration structure. String is used for genericity.
+        * \param  pArgv all the configuration parameters in a string.
+        */
+       virtual void configure(const char* pArgv) = 0;
+       
+       /**
+        * Interface. Creates a new acceleration structure and fills it with the given list of points.
+        * \param  pPts list of points to be inserted in the acceleration structure.
+        */
+       virtual void create(const std::vector<PointOfField>& pPts) = 0;
+       
+       /**
+        * Interface. Finds all the points in a sphere defined by its center (x,y,z) and its radius.
+        * \param  pCenterX x-coordinates of the center of the sphere.
+        * \param  pCenterY y-coordinates of the center of the sphere.
+        * \param  pCenterZ z-coordinates of the center of the sphere.
+        * \param  pRadius  radius of the sphere.
+        * \return all the points in a sphere defined by its center (x,y,z) and its radius.
+        */
+       virtual std::vector<PointOfField> findNeighbours(
+               med_float pCenterX,
+               med_float pCenterY,
+               med_float pCenterZ,
+               med_float pRadius) const = 0;
+       
+       //---------------------------------------------------------------------
+       // I/O
+       //---------------------------------------------------------------------
+       
+       /**
+        * Sets the flag which control the stream operator <<.
+        * \param  pFlag new flag value.
+        */
+       void setPrintAll(bool pFlag) { mFlagPrintAll = pFlag; } 
+       
+       /**
+        * Dumps any GaussLoc to the given output stream.
+        * \param  pOs any output stream.
+        * \param  pA  any DecimationAccel.
+        * \return the output stream pOs.
+        */
+       friend std::ostream& operator<<(std::ostream& pOs, DecimationAccel& pA);
+       
+protected:
+
+       bool mFlagPrintAll;  /** Flag to control the behaviour of the stream operator <<. */
+       
+private:
+       
+       // do not allow copy constructor
+       DecimationAccel(const DecimationAccel&);
+       
+       // do not allow copy
+       DecimationAccel& operator=(const DecimationAccel&);
+       
+       // do not allow operator ==
+       bool operator==(const DecimationAccel&); 
+
+}; // class DecimationAccel
+
+
+//*****************************************************************************
+// Interface DecimationFilter and factory to build filters.
+//*****************************************************************************
+
+class DecimationAccelGrid : public DecimationAccel
+{
+public:
+
+       /**
+        * Builds an empty DecimationAccelGrid (default constructor).
+        */
+       DecimationAccelGrid();
+       
+       /**
+        * Destructor. Removes everything.
+        */
+       virtual ~DecimationAccelGrid();
+       
+       /**
+        * Resets this object in its state by default (empty). Cleans memory.
+        */
+       void reset();
+       
+       //---------------------------------------------------------------------
+       // Algorithms
+       //---------------------------------------------------------------------
+       
+       /**
+        * Configures this acceleration structure. String is used for genericity.
+        * \param  pArgv assumes "size_x size_y size_z": number of cells along each axis.
+        */
+       virtual void configure(const char* pArgv);
+       
+       /**
+        * Creates a new acceleration structure and fills it with the given list of points.
+        * setSize() must have been called before.
+        * \param  pPts list of points to be inserted in the acceleration structure.
+        * \throw  IllegalStateException if setSize() has not been called before.
+        */
+       virtual void create(const std::vector<PointOfField>& pPts);
+       
+       /**
+        * Finds all the points in a sphere defined by its center (x,y,z) and its radius.
+        * \param  pCenterX x-coordinates of the center of the sphere.
+        * \param  pCenterY y-coordinates of the center of the sphere.
+        * \param  pCenterZ z-coordinates of the center of the sphere.
+        * \param  pRadius  radius of the sphere.
+        * \return all the points in a sphere defined by its center (x,y,z) and its radius.
+        */
+       virtual std::vector<PointOfField> findNeighbours(
+               med_float pCenterX,
+               med_float pCenterY,
+               med_float pCenterZ,
+               med_float pRadius) const;
+       
+       /**
+        * Returns the coordinates of the cell which contain the point (x,y,z).
+        * Clamping is performed on (pIx, pIy, pIz) to avoid out of bounds.
+        * \param  pX  (in) X-coordinates of the point.
+        * \param  pY  (in) Y-coordinates of the point.
+        * \param  pZ  (in) Z-coordinates of the point.
+        * \param  pIx (out) X-index of the cell which contain the point (x,y,z).
+        * \param  pIy (out) Y-index.
+        * \param  pIz (out) Z-index.
+        */
+       void getCellCoord(
+               med_float pX, med_float pY, med_float pZ,
+               int* pIx, int* pIy, int* pIz) const;
+       
+       /**
+        * Returns the index of the cell whose coordinates are (i, j, k).
+        * \param  pI
+        * \param  pJ
+        * \param  pK
+        * \return the index of the cell (i, j, k).
+        */
+       int getCellIndex(int pI, int pJ, int pK) const;
+       
+       /**
+        * Returns the list of points contained in the cell of pPt.
+        * \param  pPt any point which coordinates are in the bbox of this acceleration structure.
+        * \return the list of points contained in the cell of pPt.
+        */
+       std::vector<PointOfField>& getCell(const PointOfField& pPt);
+       
+       //---------------------------------------------------------------------
+       // I/O
+       //---------------------------------------------------------------------
+       
+       /**
+        * Dumps any GaussLoc to the given output stream.
+        * \param  pOs any output stream.
+        * \param  pG  any DecimationAccelGrid.
+        * \return the output stream pOs.
+        */
+       friend std::ostream& operator<<(std::ostream& pOs, DecimationAccelGrid& pG);
+       
+private:
+       
+       /**
+        * Computes the axis-aligned bounding box of a set of points.
+        * Sets the fields mMin/mMax.
+        * \param  pPts list of points.
+        */
+       void computeBBox(const std::vector<PointOfField>& pPts);
+       
+private:
+       
+       int                         mNum;        /**< Number of points in the grid. */
+       med_float                   mMin[3];     /**< Bounding box, min corner. */
+       med_float                   mMax[3];     /**< Bounding box, max corner. */
+       med_float                   mInvLen[3];  /**< 1/length of cells, along each dimension. */
+       med_int                     mSize[3];    /**< Number of cells along each dimension. */
+       std::vector<PointOfField>*  mGrid;       /**< Flatten grid structure; each cell is a vector of PointOfField. */         
+       
+private:
+       
+       // do not allow copy constructor
+       DecimationAccelGrid(const DecimationAccelGrid&);
+       
+       // do not allow copy
+       DecimationAccelGrid& operator=(const DecimationAccelGrid&);
+       
+       // do not allow operator ==
+       bool operator==(const DecimationAccelGrid&); 
+       
+}; // class DecimationAccelGrid
+
+
+} // namespace MULTIPR
+
+
+#endif // MULTIPR_DECIMATION_ACCEL_HXX
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_DecimationFilter.cxx b/src/MULTIPR/MULTIPR_DecimationFilter.cxx
new file mode 100644 (file)
index 0000000..ef9e335
--- /dev/null
@@ -0,0 +1,306 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_DecimationFilter.cxx
+ *
+ * \brief   see MULTIPR_DecimationFilter.hxx
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+#include "MULTIPR_DecimationFilter.hxx"
+#include "MULTIPR_Field.hxx"
+#include "MULTIPR_Mesh.hxx"
+#include "MULTIPR_PointOfField.hxx"
+#include "MULTIPR_DecimationAccel.hxx"
+#include "MULTIPR_Exceptions.hxx"
+
+#include <iostream>
+
+using namespace std;
+
+
+namespace multipr
+{
+
+
+//*****************************************************************************
+// Class DecimationFilter implementation
+//*****************************************************************************
+
+// factory
+DecimationFilter* DecimationFilter::create(const char* pFilterName)
+{
+       if (pFilterName == NULL) throw NullArgumentException("filter name should not be NULL", __FILE__, __LINE__);
+       
+       if (strcmp(pFilterName, "Filtre_GradientMoyen") == 0)
+       {
+               return new DecimationFilterGradAvg();
+       }
+       else
+       {
+               throw IllegalArgumentException("unknown filter", __FILE__, __LINE__);
+       }
+}
+
+
+//*****************************************************************************
+// Class DecimationFilterGradAvg
+//*****************************************************************************
+
+DecimationFilterGradAvg::DecimationFilterGradAvg() 
+{
+       // do nothing
+}
+
+
+DecimationFilterGradAvg::~DecimationFilterGradAvg()  
+{ 
+       // do nothing
+}
+
+
+Mesh* DecimationFilterGradAvg::apply(Mesh* pMesh, const char* pArgv, const char* pNameNewMesh)
+{
+       //---------------------------------------------------------------------
+       // Retrieve and check parameters
+       //---------------------------------------------------------------------
+       if (pMesh == NULL) throw NullArgumentException("pMesh should not be NULL", __FILE__, __LINE__);
+       if (pArgv == NULL) throw NullArgumentException("pArgv should not be NULL", __FILE__, __LINE__);
+       if (pNameNewMesh == NULL) throw NullArgumentException("pNameNewMesh should not be NULL", __FILE__, __LINE__);
+       
+       char   fieldName[MED_TAILLE_NOM + 1];
+       int    fieldIt;
+       double threshold;
+       double radius;
+       int    boxing; // number of cells along axis (if 100 then grid will have 100*100*100 = 10**6 cells)
+       
+       int ret = sscanf(pArgv, "%s %d %lf %lf %d",
+               fieldName,
+               &fieldIt,
+               &threshold,
+               &radius,
+               &boxing);
+       
+       if (ret != 5) throw IllegalArgumentException("wrong number of arguments for filter GradAvg; expected 5 parameters", __FILE__, __LINE__);
+       
+       //---------------------------------------------------------------------
+       // Retrieve field = for each point: get its coordinate and the value of the field
+       //---------------------------------------------------------------------
+       Field* field = pMesh->getFieldByName(fieldName);
+       
+       if (field == NULL) throw IllegalArgumentException("field not found", __FILE__, __LINE__);
+       if ((fieldIt < 1) || (fieldIt > field->getNumberOfTimeSteps())) throw IllegalArgumentException("invalid field iteration", __FILE__, __LINE__);
+       
+       vector<PointOfField> points;
+       pMesh->getAllPointsOfField(field, fieldIt, points);
+
+       //---------------------------------------------------------------------
+       // Creates acceleration structure used to compute gradient
+       //---------------------------------------------------------------------
+       DecimationAccel* accel = new DecimationAccelGrid();
+       char strCfg[256]; // a string is used for genericity
+       sprintf(strCfg, "%d %d %d", boxing, boxing, boxing);
+       accel->configure(strCfg);
+       accel->create(points);
+       
+       //---------------------------------------------------------------------
+       // Collects elements of the mesh to be kept
+       //---------------------------------------------------------------------
+       set<int> elementsToKeep;
+       
+       int numElements = pMesh->getNumberOfElements();
+       int numGaussPointsByElt = points.size() / numElements; // for a TETRA10, should be 5 for a field of elements and 10 for a field of nodes
+       
+       // for each element
+       for (int itElt = 0 ; itElt < numElements ; itElt++)
+       {
+               bool keepElement = false;
+               
+               // for each Gauss point of the current element
+               for (int itPtGauss = 0 ; itPtGauss < numGaussPointsByElt ; itPtGauss++)
+               {
+                       const PointOfField& currentPt = points[itElt * numGaussPointsByElt + itPtGauss];
+                       
+                       vector<PointOfField> neighbours = accel->findNeighbours(
+                               currentPt.mXYZ[0], 
+                               currentPt.mXYZ[1], 
+                               currentPt.mXYZ[2], 
+                               radius);
+                       
+                       // if no neighbours => keep element
+                       if (neighbours.size() == 0)
+                       {
+                               keepElement = true;
+                               break;
+                       }
+                       
+                       // otherwise compute gradient...
+                       med_float normGrad = computeNormGrad(currentPt, neighbours);
+                       
+                       // debug
+                       //cout << (itElt * numGaussPointsByElt + j) << ": " << normGrad << endl;
+                       
+                       if ((normGrad >= threshold) || isnan(normGrad))
+                       {
+                               keepElement = true;
+                               break;
+                       }
+               }
+               
+               if (keepElement)
+               {
+                       // add index of the element to keep (index must start at 1)
+                       elementsToKeep.insert(itElt + 1);
+               }
+       }
+
+       //---------------------------------------------------------------------
+       // Cleans
+       //---------------------------------------------------------------------
+       delete accel;
+       
+       //---------------------------------------------------------------------
+       // Create the final mesh by extracting elements to keep from the current mesh
+       //---------------------------------------------------------------------
+       Mesh* newMesh = pMesh->createFromSetOfElements(elementsToKeep, pNameNewMesh);
+       
+       return newMesh;
+}
+
+
+void DecimationFilterGradAvg::getGradientInfo(
+               Mesh*       pMesh, 
+               const char* pFieldName, 
+               int         pFieldIt, 
+               double      pRadius,
+               int         pBoxing,
+               double*     pOutGradMin,
+               double*     pOutGradAvg,
+               double*     pOutGradMax)
+{
+       if (pMesh == NULL) throw NullArgumentException("pMesh should not be NULL", __FILE__, __LINE__);
+       if (pFieldName == NULL) throw NullArgumentException("pFieldName should not be NULL", __FILE__, __LINE__);
+       
+       Field* field = pMesh->getFieldByName(pFieldName);
+       
+       if (field == NULL) throw IllegalArgumentException("field not found", __FILE__, __LINE__);
+       if ((pFieldIt < 1) || (pFieldIt > field->getNumberOfTimeSteps())) throw IllegalArgumentException("invalid field iteration", __FILE__, __LINE__);
+       
+       vector<PointOfField> points;
+       pMesh->getAllPointsOfField(field, pFieldIt, points);
+
+       //---------------------------------------------------------------------
+       // Creates acceleration structure used to compute gradient
+       //---------------------------------------------------------------------
+       DecimationAccel* accel = new DecimationAccelGrid();
+       char strCfg[256]; // a string is used for genericity
+       sprintf(strCfg, "%d %d %d", pBoxing, pBoxing, pBoxing);
+       accel->configure(strCfg);
+       accel->create(points);
+       
+       //---------------------------------------------------------------------
+       // Collects elements of the mesh to be kept
+       //---------------------------------------------------------------------
+       
+       int numElements = pMesh->getNumberOfElements();
+       int numGaussPointsByElt = points.size() / numElements; // for a TETRA10, should be 5 for a field of elements and 10 for a field of nodes
+       
+       *pOutGradMax = -1e300;
+       *pOutGradMin = 1e300;
+       *pOutGradAvg = 0.0;
+       int count = 0;
+       
+       // for each element
+       for (int itElt = 0 ; itElt < numElements ; itElt++)
+       {
+               // for each Gauss point of the current element
+               for (int itPtGauss = 0 ; itPtGauss < numGaussPointsByElt ; itPtGauss++)
+               {
+                       const PointOfField& currentPt = points[itElt * numGaussPointsByElt + itPtGauss];
+                       
+                       vector<PointOfField> neighbours = accel->findNeighbours(
+                               currentPt.mXYZ[0], 
+                               currentPt.mXYZ[1], 
+                               currentPt.mXYZ[2], 
+                               pRadius);
+                       
+                       // if no neighbours => keep element
+                       if (neighbours.size() == 0)
+                       {
+                               continue;
+                       }
+                       
+                       // otherwise compute gradient...
+                       med_float normGrad = computeNormGrad(currentPt, neighbours);
+                       
+                       // debug
+                       //cout << (itElt * numGaussPointsByElt + j) << ": " << normGrad << endl;
+                       
+                       if (!isnan(normGrad))
+                       {
+                               if (normGrad > *pOutGradMax) *pOutGradMax = normGrad;
+                               if (normGrad < *pOutGradMin) *pOutGradMin = normGrad;
+                               *pOutGradAvg += normGrad;
+                               count++;
+                       }
+               }
+       }
+       
+       if (count != 0) *pOutGradAvg /= double(count);
+
+       //---------------------------------------------------------------------
+       // Cleans
+       //---------------------------------------------------------------------
+       delete accel;
+}
+
+
+med_float DecimationFilterGradAvg::computeNormGrad(const PointOfField& pPt, const std::vector<PointOfField>& pNeighbours) const
+{
+       med_float gradX = 0.0;
+       med_float gradY = 0.0;
+       med_float gradZ = 0.0;
+       // for each neighbour
+       for (unsigned i = 0 ; i < pNeighbours.size() ; i++)
+       {
+               const PointOfField& neighbourPt = pNeighbours[i];
+               
+               med_float vecX = neighbourPt.mXYZ[0] - pPt.mXYZ[0];
+               med_float vecY = neighbourPt.mXYZ[1] - pPt.mXYZ[1];
+               med_float vecZ = neighbourPt.mXYZ[2] - pPt.mXYZ[2];
+               
+               med_float norm = med_float( sqrt( vecX*vecX + vecY*vecY + vecZ*vecZ ) );
+               med_float val =  neighbourPt.mVal - pPt.mVal;
+               
+               val /= norm;
+               
+               gradX += vecX * val;
+               gradY += vecY * val;
+               gradZ += vecZ * val;
+       }
+       
+       med_float invSize = 1.0 / med_float(pNeighbours.size());
+       
+       gradX *= invSize;
+       gradY *= invSize;
+       gradZ *= invSize;
+       
+       med_float norm = med_float( sqrt( gradX*gradX + gradY*gradY + gradZ*gradZ ) );
+       
+       return norm;
+       
+}
+
+
+} // namespace multipr
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_DecimationFilter.hxx b/src/MULTIPR/MULTIPR_DecimationFilter.hxx
new file mode 100644 (file)
index 0000000..828da59
--- /dev/null
@@ -0,0 +1,167 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_DecimationFilter.hxx
+ *
+ * \brief   Interface DecimationFilter: filter used for decimation.
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#ifndef MULTIPR_DECIMATION_FILTER_HXX
+#define MULTIPR_DECIMATION_FILTER_HXX
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+extern "C"
+{
+       #include "med.h"
+}
+
+#include <iostream>
+#include <vector>
+
+
+namespace multipr
+{
+
+//*****************************************************************************
+// Predeclaration
+//*****************************************************************************
+
+class Mesh;
+class PointOfField;
+
+
+//*****************************************************************************
+// Interface DecimationFilter and factory to build filters.
+//*****************************************************************************
+
+class DecimationFilter
+{
+public:
+       /**
+        * Decimation filter factory.
+        * \param  pFilterName name of the filter to be instanciated.
+        * \return a new instance of the given filter. 
+        */
+       static DecimationFilter* create(const char* pFilterName);
+       
+public:
+       
+       /** 
+        * Builds an empty DecimationFilter (default constructor).
+        */
+       DecimationFilter() { }
+       
+       /**
+        * Destructor. Removes everything.
+        */
+       virtual ~DecimationFilter() { } 
+       
+       /**
+        * Interface. Creates a new Mesh by decimating the given Mesh with this DecimationFilter.
+        * \param  pMesh        any mesh to be decimated; must not be NULL.
+        * \param  pArgv        all the arguments of the filter as a string; must not be NULL.
+        * \param  pNameNewMesh name of the decimated mesh; must not be NULL.
+        * \return the decimated mesh.
+        */
+       virtual Mesh* apply(Mesh* pMesh, const char* pArgv, const char* pNameNewMesh) = 0;
+       
+private:
+       
+       // do not allow copy constructor
+       DecimationFilter(const DecimationFilter&);
+       
+       // do not allow copy
+       DecimationFilter& operator=(const DecimationFilter&);
+       
+       // do not allow operator ==
+       bool operator==(const DecimationFilter&); 
+
+}; // class DecimationFilter
+
+
+//*****************************************************************************
+// Filter : Average Gradient
+//*****************************************************************************
+
+class DecimationFilterGradAvg : public DecimationFilter
+{
+public:
+
+       /**
+        * Builds an empty DecimationFilterGradAvg (default constructor).
+        */
+       DecimationFilterGradAvg();
+       
+       /**
+        * Destructor. Removes everything.
+        */
+       virtual ~DecimationFilterGradAvg();
+       
+       /**
+        * Creates a new Mesh by decimating the given Mesh with this DecimationFilter.
+        * 
+        * For each element
+        *     Keep this element if all its points (related to a field) have a |gradient| > threshold.
+        *
+        * For each point, gradient is computed by considering all the neighbours in a sphere of radius r.
+        *
+        * \param  pMesh        any mesh to be decimated; must not be NULL.
+        * \param  pArgv        all the arguments of the filter as a string; must not be NULL.
+        *                      for GradAvg, expected "fieldName fieldIt threshold radius boxing" (5 parameters).
+        * \param  pNameNewMesh name of the decimated mesh; must not be NULL.
+        * \return the decimated mesh.
+        */
+       virtual Mesh* apply(Mesh* pMesh, const char* pArgv, const char* pNameNewMesh);
+       
+       /**
+        * Returns information about gradient.
+        */
+       void getGradientInfo(
+               Mesh*       pMesh, 
+               const char* pFieldName, 
+               int         pFieldIt, 
+               double      pRadius,
+               int         pBoxing,
+               double*     pOutGradMin,
+               double*     pOutGradAvg,
+               double*     pOutGradMax);
+       
+private:
+
+       /**
+        * Returns the norm of the gradient of the field at the given point.
+        * Sub-method used by apply().
+        * \param  pPt        any point in the field.
+        * \param  pNeigbours neighbourhood of pPt.
+        * \return the norm of the gradient of the field in pPt.
+        */
+       med_float computeNormGrad(const PointOfField& pPt, const std::vector<PointOfField>& pNeighbours) const;
+       
+private:
+       
+       // do not allow copy constructor
+       DecimationFilterGradAvg(const DecimationFilterGradAvg&);
+       
+       // do not allow copy
+       DecimationFilterGradAvg& operator=(const DecimationFilterGradAvg&);
+       
+       // do not allow operator ==
+       bool operator==(const DecimationFilterGradAvg&); 
+       
+}; // class DecimationFilterGradAvg
+
+
+} // namespace MULTIPR
+
+
+#endif // MULTIPR_DECIMATION_FILTER_HXX
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_Elements.cxx b/src/MULTIPR/MULTIPR_Elements.cxx
new file mode 100644 (file)
index 0000000..226267e
--- /dev/null
@@ -0,0 +1,459 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_Elements.cxx
+ *
+ * \brief   see MULTIPR_Elements.hxx
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+#include "MULTIPR_Elements.hxx"
+#include "MULTIPR_Nodes.hxx"
+#include "MULTIPR_Exceptions.hxx"
+
+#include <iostream>
+#include <set>
+#include <map>
+
+using namespace std;
+
+
+namespace multipr
+{
+
+
+//*****************************************************************************
+// Class Elements implementation
+//*****************************************************************************
+
+Elements::Elements() 
+{
+       mId       = NULL;
+       mFamIdent = NULL;
+       mNames    = NULL;
+       mCon      = NULL;
+       
+       reset(); 
+}
+
+
+Elements::~Elements()  
+{ 
+       reset();  
+}
+
+
+void Elements::reset() 
+{ 
+       mNum           = 0;
+       mEntity        = MED_MAILLE;
+       mGeom          = MED_NONE;
+       mNumNodesByElt = 0;
+       mDim           = 0;
+       
+       if (mId != NULL)       { delete[] mId;       mId       = NULL; }
+       if (mFamIdent != NULL) { delete[] mFamIdent; mFamIdent = NULL; }
+       if (mNames != NULL)    { delete[] mNames;    mNames    = NULL; }
+       if (mCon != NULL)      { delete[] mCon;      mCon      = NULL; }
+
+       mSetOfNodes.clear();
+       
+       mFlagPrintAll = false;
+}
+
+
+med_int Elements::getFamilyIdentifier(med_int pIndex) const 
+{ 
+       if ((pIndex < 0) || (pIndex >= mNum)) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
+       
+       return mFamIdent[pIndex]; 
+}
+
+
+const med_int* Elements::getConnectivity(int pIndex) const
+{
+       if ((pIndex < 0) || (pIndex >= mNum)) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
+       
+       return mCon + mNumNodesByElt * pIndex;
+}
+
+
+void Elements::getCoordinates(med_int pIndexElt, const Nodes* pNodes, med_float* pCoo, int pFirst) const
+{
+       if ((pIndexElt < 0) || (pIndexElt >= mNum)) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
+       if (pNodes == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       if (pCoo == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       
+       // get the list of nodes of the element
+       const med_int* con = getConnectivity(pIndexElt);
+       
+       med_float* destCoo = pCoo;
+       int size = sizeof(med_float) * mDim;
+       
+       // for each node of the element
+       int n = (mNumNodesByElt < pFirst) ? mNumNodesByElt : pFirst;
+       for (int i = 0 ; i < n ; i++)
+       {
+               // get index of node (MED index start at 1)
+               med_int indexNode = con[i] - 1;
+               
+               // get coordinates of this node
+               const med_float* srcCoo = pNodes->getCoordinates(indexNode);
+               
+               // copy coordinates to destCoo
+               memcpy(destCoo, srcCoo, size);
+               
+               // prepare next point
+               destCoo += mDim;
+       }
+}
+
+
+Elements* Elements::extractSubSet(const set<med_int>& pSetIndices) const
+{
+       Elements* subset = new Elements();
+       
+       //---------------------------------------------------------------------
+       // Copy parameters
+       //---------------------------------------------------------------------
+       subset->mNum           = pSetIndices.size();
+       subset->mEntity        = mEntity;
+       subset->mGeom          = mGeom;          // e.g. 310 for a TETRA10
+       subset->mNumNodesByElt = mNumNodesByElt; // e.g. 10 for a TETRA10
+       subset->mDim           = mDim;           // e.g. 3 for a TETRA10
+       
+       //---------------------------------------------------------------------
+       // Allocate arrays
+       //---------------------------------------------------------------------
+       subset->mFamIdent     = new med_int[subset->mNum];
+       subset->mCon          = new med_int[mNumNodesByElt * subset->mNum];
+       
+       //---------------------------------------------------------------------
+       // Copy subset of familys id and connectivity.
+       //---------------------------------------------------------------------
+       med_int* destCon = subset->mCon;
+       set<med_int>::iterator itSet = pSetIndices.begin();
+       for (int itElt = 0 ; itElt < subset->mNum; itElt++)
+       {
+               med_int srcIndex = (*itSet) - 1; // MED index start at 1
+               subset->mFamIdent[itElt] = mFamIdent[srcIndex];
+               
+               med_int* srcCon = mCon + srcIndex * mNumNodesByElt;
+               memcpy(destCon, srcCon, sizeof(med_int) * mNumNodesByElt);
+               
+               destCon += mNumNodesByElt;
+               itSet++;
+       }
+       
+       //---------------------------------------------------------------------
+       // Copy subset of identifiers if necessary
+       //---------------------------------------------------------------------
+       if (isIdentifiers())  
+       { 
+               itSet = pSetIndices.begin();
+               subset->mId = new med_int[subset->mNum]; 
+               for (int itElt = 0 ; itElt < subset->mNum; itElt++)
+               {
+                       med_int srcIndex = (*itSet) - 1; // MED index start at 1
+                       subset->mId[itElt] = mId[srcIndex];
+                       
+                       itSet++;
+               }
+       }
+       
+       //---------------------------------------------------------------------
+       // Copy subset of names if necessary
+       //---------------------------------------------------------------------
+       if (isNames())       
+       { 
+               itSet = pSetIndices.begin();
+               subset->mNames = new char[MED_TAILLE_PNOM * subset->mNum + 1]; 
+               char* destPtr = subset->mNames;
+               for (int itElt = 0 ; itElt < subset->mNum; itElt++)
+               {
+                       med_int srcIndex = (*itSet) - 1; // MED index start at 1
+                       char* srcPtr = mNames + srcIndex * MED_TAILLE_PNOM;
+                       memcpy(destPtr, srcPtr, MED_TAILLE_PNOM);
+                       
+                       destPtr += MED_TAILLE_PNOM;
+                       itSet++;
+               }
+               subset->mNames[MED_TAILLE_PNOM * subset->mNum] = '\0';
+       }
+       
+       return subset;
+}
+
+
+const set<med_int>& Elements::getSetOfNodes()
+{      
+       // lazy get: test if mSetOfNodes has already been built
+       if (mSetOfNodes.size() == 0)
+       {
+               buildSetOfNodes();
+       }
+       
+       return mSetOfNodes;
+}
+
+
+set<med_int> Elements::getSetOfFamilies() const
+{
+       // set of families is empty at the beginning
+       set<med_int> setOfFamilies;
+       
+       // for each element, add its family to the set
+       for (int itElt = 0 ; itElt < mNum ; itElt++)
+       {
+               setOfFamilies.insert(mFamIdent[itElt]);
+       }
+       
+       return setOfFamilies;
+}
+
+
+void Elements::remap()
+{
+       // build set of nodes if necessary
+       if (mSetOfNodes.size() == 0)
+       {
+               buildSetOfNodes();
+       }
+       
+       // build the map for indices convertion
+       map<med_int, med_int> mapOldIndexToNewIndex;
+       med_int newIndex = 1; // MED index start at 1
+       for (set<med_int>::iterator itSet = mSetOfNodes.begin(); itSet != mSetOfNodes.end() ; itSet++)
+       {
+               med_int oldIndex = (*itSet);
+               mapOldIndexToNewIndex.insert(make_pair(oldIndex, newIndex));
+               newIndex++;
+       }
+       
+       // for each node referenced by this set of elements
+       for (int itNode = 0, size = mNum * mNumNodesByElt ; itNode < size ; itNode++)
+       {
+               // convert old index to new index (remap)
+               mCon[itNode] = mapOldIndexToNewIndex[mCon[itNode]];
+       }
+       
+       buildSetOfNodes();
+}
+
+
+void Elements::buildSetOfNodes()
+{
+       if (mSetOfNodes.size() != 0)
+       {
+               mSetOfNodes.clear();
+       }
+       
+       // for each node referenced by this set of elements
+       for (int itNode = 0, size = mNum * mNumNodesByElt ; itNode < size ; itNode++)
+       {
+               // add the node to the set
+               mSetOfNodes.insert(mCon[itNode]);
+       }
+}
+
+
+void Elements::readMED(
+       med_idt               pMEDfile, 
+       char*                 pMeshName, 
+       med_int               pMeshDim, 
+       med_entite_maillage   pEntity, 
+       med_geometrie_element pGeom)
+{
+       if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
+       if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       if ((pMeshDim < 1) || (pMeshDim > 3)) throw IllegalArgumentException("", __FILE__, __LINE__);
+       
+       reset();
+       
+       mEntity        = pEntity;
+       mGeom          = pGeom;
+       mNumNodesByElt = mGeom % 100;
+       mDim           = mGeom / 100;
+       
+       mNum = MEDnEntMaa(
+               pMEDfile, 
+               pMeshName, 
+               MED_CONN,  // type of information requested = CONNECTIVITY
+               pEntity, 
+               pGeom, 
+               MED_NOD);  // nodal connectivity
+       
+       if (mNum < 0) throw IOException("i/o error while reading information about elements in MED file", __FILE__, __LINE__);
+       
+       mCon      = new med_int[mNumNodesByElt * mNum];
+       mNames    = new char[MED_TAILLE_PNOM * mNum + 1];
+       mId       = new med_int[mNum];
+       mFamIdent = new med_int[mNum]; 
+       med_booleen isNames;
+       med_booleen isIdentifiers;
+       
+       med_err ret = MEDelementsLire(
+               pMEDfile, 
+               pMeshName, 
+               pMeshDim, 
+               mCon, 
+               MED_FULL_INTERLACE,
+               mNames, 
+               &isNames,
+               mId,
+               &isIdentifiers,
+               mFamIdent,
+               mNum, 
+               mEntity, 
+               mGeom, 
+               MED_NOD); // NODAL CONNECTIVITY
+       
+       if (ret != 0) throw IOException("i/o error while reading elements in MED file", __FILE__, __LINE__);
+       
+       if (!isNames)
+       {
+               delete[] mNames;
+               mNames = NULL;
+       }
+       
+       if (!isIdentifiers)
+       {
+               delete[] mId;
+               mId = NULL;
+       }
+}
+
+
+void Elements::writeMED(med_idt pMEDfile, char* pMeshName, med_int pMeshDim)
+{
+       if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
+       if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       if (strlen(pMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
+       if ((pMeshDim < 1) || (pMeshDim > 3)) throw IllegalArgumentException("", __FILE__, __LINE__);
+       
+       // special case: if no elements => do nothing
+       if (mNum == 0) return;
+       
+       med_err ret = MEDelementsEcr(
+               pMEDfile,
+               pMeshName,
+               pMeshDim,
+               mCon,
+               MED_FULL_INTERLACE,
+               mNames,
+               isNames()?MED_VRAI:MED_FAUX,
+               mId,
+               isIdentifiers()?MED_VRAI:MED_FAUX,
+               mFamIdent,
+               mNum,
+               mEntity,
+               mGeom,
+               MED_NOD); // NODAL CONNECTIVITY
+               
+       if (ret != 0) throw IOException("i/o error while writing elements in MED file", __FILE__, __LINE__);
+}
+
+
+ostream& operator<<(ostream& pOs, Elements& pE)
+{
+       char strEntity[16];
+       switch (pE.mEntity) 
+       {
+               case MED_MAILLE: strcpy(strEntity, "MED_MAILLE"); break;
+               case MED_FACE:   strcpy(strEntity, "MED_FACE"); break;
+               case MED_ARETE:  strcpy(strEntity, "MED_ARETE"); break;
+               case MED_NOEUD:  strcpy(strEntity, "MED_NOEUD"); break;
+               default:         strcpy(strEntity, "UNKNOWN"); break;
+       }
+       
+       pOs << "Elements: " << endl;
+       pOs << "    #number  =" << pE.mNum << endl;
+       pOs << "    Entity   =" << strEntity << endl;
+       pOs << "    Geom     =" << pE.mGeom << endl; 
+       pOs << "    Has names?" << (pE.isNames()?"yes":"no") << endl;
+       pOs << "    Has id   ?" << (pE.isIdentifiers()?"yes":"no") << endl;
+
+       {
+               set<med_int> setOfFam = pE.getSetOfFamilies();
+               if (setOfFam.size() == 0)
+               {
+                       pOs << "    Families: #fam=0" << endl;
+               }
+               else
+               {
+                       set<med_int>::iterator itFam = setOfFam.end();
+                       itFam--;
+                       pOs << "    Families: #fam=" << setOfFam.size() << " id_min=" << (*(setOfFam.begin())) << " id_max=" << (*itFam) << endl;
+                       
+                       if (pE.mFlagPrintAll)
+                       {
+                               for (int i = 0 ; i < pE.mNum; i++)
+                               {
+                                       pOs << "        Elt " << (i + 1) << ": " << pE.mFamIdent[i] << endl;
+                               }
+                       }
+               }
+       }
+       
+       {
+               set<med_int> setOfNodes = pE.getSetOfNodes();
+               if (setOfNodes.size() == 0)
+               {
+                       pOs << "    Connectivity: #nodes=0" << endl;
+               }
+               else
+               {
+                       set<med_int>::iterator itNode = setOfNodes.end();
+                       itNode--;
+                       pOs << "    Connectivity: #nodes=" << setOfNodes.size() << " id_min=" << (*(setOfNodes.begin())) << " id_max=" << (*itNode) << endl;
+                       
+                       if (pE.mFlagPrintAll)
+                       {
+                               for (int i = 0 ; i < pE.mNum ; i++)
+                               {
+                                       pOs << "        Elt " << (i + 1) << ": ";
+                                       for (int j = 0 ; j < pE.mNumNodesByElt ; j++)
+                                       {
+                                               pOs << pE.mCon[i * pE.mNumNodesByElt + j] << " ";
+                                       }
+                                       pOs << endl;
+                               }
+                       }
+               }
+       }
+       
+       if (pE.mFlagPrintAll)
+       {
+               
+               if (pE.isIdentifiers())
+               {
+                       pOs << "    Num (identifier): " << endl;
+                       for (int i = 0 ; i < pE.mNum; i++)
+                       {
+                               pOs << "        Elt " << (i + 1) << ": " << pE.mId[i] << " " << endl;
+                       }
+               }
+               
+               if (pE.isNames())
+               {
+                       pE.mNames[MED_TAILLE_PNOM * pE.mNum] = '\0';
+                       pOs << "    Names: |" << pE.mNames << "|" << endl;
+               }
+               
+       }
+       
+       return pOs;
+}
+
+
+} // namespace  multipr
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_Elements.hxx b/src/MULTIPR/MULTIPR_Elements.hxx
new file mode 100644 (file)
index 0000000..178aa4c
--- /dev/null
@@ -0,0 +1,248 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_Elements.hxx
+ *
+ * \brief   Class Elements = table of elements in a mesh.
+ *          All elements share the same type (e.g. MED_MAILLE) and the same geometric description (e.g. TETRA10).
+ *          Each element has a family and a table of connectivity.
+ *          Optional: each element has a name and an id.
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#ifndef MULTIPR_ELEMENTS_HXX
+#define MULTIPR_ELEMENTS_HXX
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+extern "C"
+{
+       #include "med.h"
+}
+
+#include <set>
+
+
+namespace multipr
+{
+
+//*****************************************************************************
+// Predeclaration
+//*****************************************************************************
+
+class Nodes;
+
+
+//*****************************************************************************
+// Class Elements
+//*****************************************************************************
+
+class Elements
+{
+public:
+
+       /** 
+        * Builds an empty set of elements (default constructor).
+        */
+       Elements();
+       
+       /**
+        * Destructor. Removes everything.
+        */
+       ~Elements();
+       
+       /**
+        * Resets this object in its state by default (empty). Cleans memory.
+        */
+       void reset();
+       
+       //---------------------------------------------------------------------
+       // Basic accessors/mutators
+       //---------------------------------------------------------------------
+       
+       /**
+        * Returns true iff this object contains no elements (table of elements is empty).
+        * \return true iff this object contains no elements.
+        */
+       bool isEmpty() const { return (mNum == 0); }
+       
+       /**
+        * Returns true iff elements have a name.
+        * \return true iff elements have a name.
+        */
+       bool isNames() const { return (mNames != NULL); }
+       
+       /**
+        * Returns true iff elements have an identifier (= a number).
+        * \return true iff elements have an identifier (= a number).
+        */
+       bool isIdentifiers() const { return (mId != NULL); }    
+       
+       /**
+        * Returns the number of elements.
+        * \return the number of elements.
+        */
+       int getNumberOfElements() const { return mNum; }
+       
+       /**
+        * Returns the type of primitives (e.g. MED_TETRA10).
+        * \return the type of primitives
+        */
+       med_geometrie_element getTypeOfPrimitives() const { return mGeom; }
+       
+       /**
+        * Returns the number of nodes that composed an element.
+        * \return the number of nodes that composed an element.
+        */
+        int getNumberOfNodesByElement() const { return mNumNodesByElt; }
+        
+       /**
+        * Returns the family associated with an element.
+        * \param  pIndex index of any element in [0..NUMBER_OF_ELEMENTS-1].
+        * \return the family associated with an element.
+        * \throw  IndexOutOfBoundsException if pIndex is invalid.
+        */
+       med_int getFamilyIdentifier(med_int pIndex) const;
+       
+       /**
+        * Returns the connectivity of one element.
+        * \param  pIndex must be in [0..NUMBER_OF_ELEMENTS-1].
+        * \return a pointer towards the table of connectivity of the element.
+        * \throw  IndexOutOfBoundsException if pIndex is invalid.
+        */
+       const med_int* getConnectivity(int pIndex) const;
+       
+       /**
+        * Returns the coordinates of all the nodes of one element.
+        * \param  pIndexElt must be in [0..NUMBER_OF_ELEMENTS-1].
+        * \param  pNodes    table of nodes, used to retrieve coordinates.
+        * \param  pCoo      (out) table of coordinates of nodes (e.g. 30 = 3 * 10 med_float for a TETRA10).
+        * \param  pFirst    only get the pFirst coordinates.
+        * \throw  IndexOutOfBoundsException if pIndex is invalid.
+        */
+       void getCoordinates(med_int pIndexElt, const Nodes* pNodes, med_float* pCoo, int pFirst = 100) const;
+       
+       //---------------------------------------------------------------------
+       // Algorithms
+       //---------------------------------------------------------------------
+       
+       /**
+        * Constructor. Creates a subset of this set of elements from a set of indices.
+        * \param  pSetIndices set of indices (start at 1).
+        * \return a restriction of this set of elements.
+        */
+       Elements* extractSubSet(const std::set<med_int>& pSetIndices) const;
+       
+       /**
+        * Returns the set of indices (starting at 1) of all nodes used by this set of elements.
+        * \return the set of indices of all nodes used by this set of elements.
+        */
+       const std::set<med_int>& getSetOfNodes();
+       
+       /**
+        * Returns the set of families referenced by this set of elements.
+        * Each family is described by its identifier.
+        * \return Returns the set of families referenced by this set of elements.
+        */
+       std::set<med_int> getSetOfFamilies() const;
+       
+       /**
+        * Remaps this set of elements such that indices of nodes are continous 1 2 3 4 5 ... *
+        * This method is intended to be used after extractSubSet().
+        */
+       void remap();
+       
+       //---------------------------------------------------------------------
+       // I/O
+       //---------------------------------------------------------------------
+       
+       /**
+        * Reads a set of elements from a MED file.
+        * You must give: name of mesh, dimension of the mesh, type of entity and type of elements.
+        * \param  pMEDfile   any valid MED file opened for reading.
+        * \param  pMeshName  name of the mesh.
+        * \param  pMeshDim   dimension of the mesh.
+        * \param  pEntity    entity to be read (e.g. MED_MAILLE).
+        * \param  pGeom      type of primitves to be read (e.g. MED_TETRA10).
+        * \throw  IOException if any i/o error occurs.
+        */
+       void readMED(
+               med_idt               pMEDfile, 
+               char*                 pMeshName, 
+               med_int               pMeshDim,
+               med_entite_maillage   pEntity, 
+               med_geometrie_element pGeom);
+       
+       /**
+        * Writes this set of elements to a MED file.
+        * WARNING: mesh must have been created and added to the MED file before.
+        * \param  pMEDfile  any valid MED file opened for writing.
+        * \param  pMeshName name of the mesh.
+        * \param  pMeshDim  dimension of the mesh.
+        * \throw  IOException if any i/o error occurs.
+        */
+       void writeMED(med_idt pMEDfile, char* pMeshName, med_int pMeshDim);
+       
+       /**
+        * Sets the flag which control the stream operator <<.
+        * \param  pFlag new flag value.
+        */
+       void setPrintAll(bool pFlag) { mFlagPrintAll = pFlag; } 
+       
+       /**
+        * Dumps any Elements to the given output stream.
+        * \param  pOs any output stream.
+        * \param  pE  any Elements.
+        * \return the output stream pOs.
+        */
+       friend std::ostream& operator<<(std::ostream& pOs, Elements& pE);
+
+private:
+       
+       /**
+        * Builds the set of nodes used by this set of elements.
+        * If the set already exist, then it is cleared and a new set is computed.
+        */
+       void buildSetOfNodes();
+       
+private:
+       
+       med_int               mNum;           /**< Number of elements. */
+       med_entite_maillage   mEntity;        /**< Type of entity, e.g. MED_MAILLE. */
+       med_geometrie_element mGeom;          /**< Type of primitive, e.g. MED_TETRA10. */
+       int                   mDim;           /**< Dimension of elements = mGeom / 100. */
+       int                   mNumNodesByElt; /**< Number of nodes by element = mGeom % 100. */
+       med_int*              mId;            /**< Optional; for each element, its identifier; NULL if undefined. */
+       med_int*              mFamIdent;      /**< For each element, its family (identifier). */
+       char*                 mNames;         /**< Optional; for each element, its name; NULL if undefined. */
+       med_int*              mCon;           /**< For each element, list of nodes (index in 1..*) = table of connectivity. */
+       std::set<med_int>     mSetOfNodes;    /**< Set of all nodes used by this set of elements. */
+       
+       bool                  mFlagPrintAll;  /** Flag to control the behaviour of the stream operator <<. */
+       
+private:
+
+       // do not allow copy constructor
+       Elements(const Elements&);
+       
+       // do not allow copy
+       Elements& operator=(const Elements&);
+       
+       // do not allow operator ==
+       bool operator==(const Elements&); 
+       
+}; // class Elements
+
+
+} // namespace MULTIPR
+
+
+#endif // MULTIPR_NODES_HXX
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_Exceptions.hxx b/src/MULTIPR/MULTIPR_Exceptions.hxx
new file mode 100644 (file)
index 0000000..2b25de1
--- /dev/null
@@ -0,0 +1,203 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_Exceptions.hxx
+ *
+ * \brief   All the exceptions used by MULTIPR.
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#ifndef MULTIPR_EXCEPTIONS_HXX
+#define MULTIPR_EXCEPTIONS_HXX
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+#include <string>
+#include <iostream>
+
+
+namespace multipr
+{
+
+//*****************************************************************************
+// Class RuntimeException
+// Super class for all exceptions used by the module MULTIPR
+//*****************************************************************************
+
+class RuntimeException
+{
+public:
+       
+       /**
+        * Constructor. Build a new RuntimeException.
+        * \param  pMsg   message to be associated with this exception.
+        * \param  pFile  name of the file where the probem occur (you can use the macro __FILE__); "unknown" by default.
+        * \param  pLine  number of the line where the probem occur (you can use the macro __LINE__); 0 by default.
+        */
+       RuntimeException(
+               const std::string& pMsg, 
+               const std::string& pFile = "unknown", 
+               int                pLine = 0) 
+       { 
+               mMsg  = pMsg; 
+               mFile = pFile;
+               mLine = pLine;
+               mType = "RuntimeException";
+       }
+       
+       /**
+        * Dumps info about this exception to the given output stream.
+        */
+       void dump(std::ostream& pOs) const 
+       { 
+               pOs << "MULTIPR: " << mType << " (" << mFile << ", line " << mLine << "): " << mMsg << std::endl; 
+       }
+       
+protected:
+
+       std::string mMsg;    /**< Message associated with this exception. */
+       std::string mFile;   /**< Name of the source file where the problem occurs. */
+       int         mLine;   /**< Number of the line where the problem occurs. */
+       std::string mType;   /**< Type of this exception. */
+};
+
+
+//*****************************************************************************
+// Class NullArgumentException
+// Should be used for a NULL pointer
+//*****************************************************************************
+
+class NullArgumentException : public RuntimeException
+{
+public:
+       NullArgumentException(
+               const std::string& pMsg, 
+               const std::string& pFile="unknown", 
+               int pLine=0) : RuntimeException(pMsg, pFile, pLine) 
+       { 
+               mType = "NullArgumentException";
+       }
+};
+
+
+//*****************************************************************************
+// Class IllegalArgumentException
+// Should be used when a parameter is invalid (check precondition)
+//*****************************************************************************
+
+class IllegalArgumentException : public RuntimeException
+{
+public:
+       IllegalArgumentException(
+               const std::string& pMsg, 
+               const std::string& pFile="unknown", 
+               int pLine=0) : RuntimeException(pMsg, pFile, pLine) 
+       { 
+               mType = "IllegalArgumentException";
+       }
+};
+
+
+//*****************************************************************************
+// Class IllegalStateException
+// Should be used when the internal state of an object is invalid
+//*****************************************************************************
+
+class IllegalStateException : public RuntimeException
+{
+public:
+       IllegalStateException(
+               const std::string& pMsg, 
+               const std::string& pFile="unknown", 
+               int pLine=0) : RuntimeException(pMsg, pFile, pLine)
+       { 
+               mType = "IllegalStateException";
+       }
+};
+
+
+//*****************************************************************************
+// Class IndexOutOfBoundsException
+// Should be used when an index is out of bounds
+//*****************************************************************************
+
+class IndexOutOfBoundsException : public RuntimeException
+{
+public:
+       IndexOutOfBoundsException(
+               const std::string& pMsg, 
+               const std::string& pFile="unknown", 
+               int pLine=0) : RuntimeException(pMsg, pFile, pLine)
+       { 
+               mType = "IndexOutOfBoundsException";
+       }
+};
+
+
+//*****************************************************************************
+// Class IOException
+// Should be used when any i/o error occurs
+//*****************************************************************************
+
+class IOException : public RuntimeException
+{
+public:
+       IOException(
+               const std::string& pMsg, 
+               const std::string& pFile="unknown", 
+               int pLine=0) : RuntimeException(pMsg, pFile, pLine)
+       { 
+               mType = "IOException";
+       }
+};
+
+
+//*****************************************************************************
+// Class FileNotFoundException
+// Should be used to indicate that a file has not been found
+//*****************************************************************************
+
+class FileNotFoundException : public IOException
+{
+public:
+       FileNotFoundException(
+               const std::string& pMsg, 
+               const std::string& pFile="unknown", 
+               int pLine=0) : IOException(pMsg, pFile, pLine)
+       { 
+               mType = "FileNotFoundException";
+       }
+};
+
+
+//*****************************************************************************
+// Class UnsupportedOperationException
+// Should be used when a function/method is not yet implemented or 
+// if an operation is not supported in a given context
+//*****************************************************************************
+
+class UnsupportedOperationException : public RuntimeException
+{
+public:
+       UnsupportedOperationException(
+               const std::string& pMsg, 
+               const std::string& pFile="unknown", 
+               int pLine=0) : RuntimeException(pMsg, pFile, pLine)
+       { 
+               mType = "UnsupportedOperationException";
+       }
+};
+
+
+} // namespace MULTIPR
+
+
+#endif // MULTIPR_EXCEPTIONS_HXX
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_Family.cxx b/src/MULTIPR/MULTIPR_Family.cxx
new file mode 100644 (file)
index 0000000..e6ab2fc
--- /dev/null
@@ -0,0 +1,463 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_Family.cxx
+ *
+ * \brief   see MULTIPR_Family.hxx
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+#include "MULTIPR_Family.hxx"
+#include "MULTIPR_Exceptions.hxx"
+
+#include <iostream>
+
+using namespace std;
+
+
+namespace multipr
+{
+
+
+//*****************************************************************************
+// Class Attributs implementation
+//*****************************************************************************
+
+Attributs::Attributs()
+{
+       mId   = NULL;
+       mVal  = NULL;
+       mDesc = NULL;
+       
+       reset();
+}
+
+
+Attributs::~Attributs()
+{
+       reset();
+}
+
+
+Attributs& Attributs::operator=(const Attributs& pAttr)
+{
+       if (this != &pAttr) // check for self-assignement
+       {
+               reset();
+               
+               mNum = pAttr.mNum;
+               
+               if (mNum < 0) throw IllegalStateException("", __FILE__, __LINE__);
+               
+               if (pAttr.mId != NULL)
+               {
+                       mId = new med_int[mNum];
+                       memcpy(mId, pAttr.mId, sizeof(med_int) * mNum);
+               }
+               
+               if (pAttr.mVal != NULL)
+               {
+                       mVal = new med_int[mNum];
+                       memcpy(mVal, pAttr.mVal, sizeof(med_int) * mNum);
+               }
+               
+               if (pAttr.mDesc != NULL)
+               {
+                       mDesc = new char[MED_TAILLE_DESC * mNum + 1];
+                       memcpy(mDesc, pAttr.mDesc, MED_TAILLE_DESC * mNum + 1);
+               }
+       }
+       
+       return *this;
+}
+
+
+void Attributs::reset()
+{
+       mNum = 0;
+       
+       if (mId   != NULL) { delete[] mId;   mId   = NULL; }
+       if (mVal  != NULL) { delete[] mVal;  mVal  = NULL; }
+       if (mDesc != NULL) { delete[] mDesc; mDesc = NULL; }
+}
+
+
+ostream& operator<<(ostream& pOs, Attributs& pA)
+{
+       if (pA.mNum == 0)
+       {
+               pOs << "NONE" << endl;
+       }
+       else
+       {
+               pOs << endl << "        #attr=" << pA.mNum << endl;
+               
+               if (pA.mId != NULL)
+               {
+                       pOs << "        Id  =[";
+                       for (int i = 0 ; i < pA.mNum ; i++)
+                       {
+                               pOs << pA.mId[i] << " ";
+                       }
+                       pOs << "]" << endl;
+               }
+               else
+               {
+                       pOs << "        Id  =NULL" << endl;
+               }
+               
+               if (pA.mVal != NULL)
+               {
+                       pOs << "        Val =[";
+                       for (int i = 0 ; i < pA.mNum ; i++)
+                       {
+                               pOs << pA.mVal[i] << " ";
+                       }
+                       pOs << "]" << endl;
+               }
+               else
+               {
+                       pOs << "        Val =NULL";
+               }
+               
+               if (pA.mDesc != NULL)
+               {
+                       pOs << "        Desc=|" << pA.mDesc << "|" << endl;
+               }
+               else
+               {
+                       pOs << "        Desc=NULL" << endl;
+               }
+       }
+       
+       return pOs;
+}
+
+
+//*****************************************************************************
+// Class Family implementation
+//*****************************************************************************
+
+Family::Family() 
+{
+       reset(); 
+}
+
+
+Family::~Family()  
+{ 
+       reset();  
+}
+
+
+void Family::reset() 
+{ 
+       mName[0]       = '\0';
+       mId            = 0;
+       mStrNameGroups = "";
+       
+       mElt.clear();
+       mNameGroups.clear();
+       mAttributs.reset();
+       
+       mIsFamilyOfNodes = true;
+       
+       mFlagPrintAll = false;
+}
+
+
+void Family::insertElt(med_int pIndexElt) 
+{ 
+       if (pIndexElt < 1) throw new IllegalArgumentException("", __FILE__, __LINE__);
+       
+       mElt.insert(pIndexElt); 
+}
+
+
+void Family::buildGroups(vector<Group*>& pGroups, map<string, Group*>& pGroupNameToGroup) const
+{
+       // pGroups / pGroupNameToGroup can be empty or not
+       
+       // for each group in this family
+       for (unsigned itGroup = 0 ; itGroup < mNameGroups.size() ; itGroup++)
+       {
+               const string& keyName = mNameGroups[itGroup];
+               
+               // check if the group already exist
+               map<string, Group*>::iterator it = pGroupNameToGroup.find(keyName);
+               
+               Group* group = NULL;
+               if (it != pGroupNameToGroup.end())
+               {
+                       // the group already exists
+                       group = (*it).second;
+               }
+               else
+               {
+                       // a new group have been identified: create a new entry
+                       group = new Group();
+                       group->setName(keyName);
+                       group->setIsGroupOfNodes(isFamilyOfNodes());
+                       
+                       pGroups.push_back(group);
+                       pGroupNameToGroup.insert(make_pair(keyName, group));
+               }
+               
+               // add all elements of the this family to the group
+               for (set<med_int>::iterator itElt = mElt.begin() ; itElt != mElt.end() ; itElt++)
+               {
+                       group->insertElt(*itElt);
+               }
+               
+       }
+}
+
+
+Family* Family::extractGroup(const char* pGroupName)
+{
+       Family* family = new Family();
+       
+       strcpy(family->mName, mName);
+       family->mId = mId;
+       family->mAttributs = mAttributs;
+       
+       if (pGroupName == NULL)
+       {
+               family->mStrNameGroups = mStrNameGroups;
+               family->mNameGroups = mNameGroups;
+       }
+       else
+       {
+               if (strlen(pGroupName) > MED_TAILLE_LNOM) throw IllegalArgumentException("", __FILE__, __LINE__);
+               if (strlen(pGroupName) == 0) throw IllegalArgumentException("", __FILE__, __LINE__);
+               
+               if (strstr(mStrNameGroups.c_str(), pGroupName) == 0)
+               {
+                       // pGroupName found in the list of groups => just keep pGroupName
+                       family->mStrNameGroups = mStrNameGroups;
+                       family->mNameGroups = mNameGroups;
+               }
+               else
+               {
+                       // pGroupName not found in the current list of groups 
+                       // probably not a group of the same nature => keep all the groups
+                       family->mStrNameGroups = pGroupName;
+                       family->mNameGroups.push_back(pGroupName);
+               }
+       }
+       
+       return family;
+}
+
+
+void Family::readMED(med_idt pMEDfile, char* pMeshName, med_int pIndex)
+{
+       if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
+       if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       if (strlen(pMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
+       if (pIndex < 1) throw IllegalArgumentException("", __FILE__, __LINE__);
+       
+       reset();
+       
+       med_int numGroups = MEDnGroupe(pMEDfile, pMeshName, pIndex);
+       
+       if (numGroups < 0) throw IOException("i/o error while reading number of groups in MED file", __FILE__, __LINE__);
+       
+       med_int numAttr = MEDnAttribut(pMEDfile, pMeshName, pIndex);
+       
+       med_int* attrId   = new med_int[numAttr];
+       med_int* attrVal  = new med_int[numAttr];
+       char*    attrDesc = new char[MED_TAILLE_DESC * numAttr + 1];
+       attrDesc[0] = '\0';
+       
+       char* nameGroups = new char[MED_TAILLE_LNOM * numGroups + 1];
+       nameGroups[0] = '\0';
+       
+       med_err ret = MEDfamInfo(
+               pMEDfile, 
+               pMeshName, 
+               pIndex, 
+               mName, 
+               &mId, 
+               attrId, 
+               attrVal, 
+               attrDesc, 
+               &numAttr, 
+               nameGroups, 
+               &numGroups);
+       
+       if (ret != 0) throw IOException("i/o error while reading family information in MED file", __FILE__, __LINE__);
+       
+       attrDesc[MED_TAILLE_DESC * numAttr] = '\0';
+       
+       mAttributs.mNum  = numAttr;
+       mAttributs.mId   = attrId;
+       mAttributs.mVal  = attrVal;
+       mAttributs.mDesc = attrDesc;
+       
+       mStrNameGroups = nameGroups;
+       
+       // split nameGroups
+       for (int itGroup = 0 ; itGroup < numGroups ; itGroup++)
+       {
+               char str[MED_TAILLE_LNOM + 1];
+               strncpy(str, nameGroups + itGroup * MED_TAILLE_LNOM, MED_TAILLE_LNOM);
+               str[MED_TAILLE_LNOM] = '\0';
+               mNameGroups.push_back(str);
+       }
+       
+       delete[] nameGroups;
+       
+       // MEDfamLire is not necessary as we used MEDnoeudsLire/MEDelementsLire instead
+}
+
+
+void Family::writeMED(med_idt pMEDfile, char* pMeshName)
+{
+       if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
+       if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       if (strlen(pMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
+       if (strlen(mName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
+       if (mAttributs.mVal == NULL) throw IllegalStateException("", __FILE__, __LINE__);
+       if (mAttributs.mDesc == NULL) throw IllegalStateException("", __FILE__, __LINE__);
+       if (mAttributs.mId == NULL) throw IllegalStateException("", __FILE__, __LINE__);
+               
+       med_err ret = MEDfamCr(
+               pMEDfile,
+               pMeshName,
+               mName,
+               mId,
+               mAttributs.mId,
+               mAttributs.mVal,
+               mAttributs.mDesc,
+               mAttributs.mNum,
+               const_cast<char*>(mStrNameGroups.c_str()),
+               mNameGroups.size());
+       
+       if (ret != 0) throw IOException("i/o error while creating family in MED file", __FILE__, __LINE__);
+       
+       // MEDfamEcr is not necessary as we used MEDnoeudsEcr/MEDelementsEcr instead
+
+}
+
+
+ostream& operator<<(ostream& pOs, Family& pF)
+{
+       pOs << "Family: " << endl;
+       pOs << "    Name      =|" << pF.mName << "| size=" << strlen(pF.mName) << endl;
+       pOs << "    Id        =" << pF.mId << endl;
+       pOs << "    Family of =" << (pF.isFamilyOfNodes()?"NODES":"ELEMENTS") << endl;  
+       
+       pOs << "    Groups: #groups=" << pF.mNameGroups.size() << endl;
+       for (unsigned itGroup = 0 ; itGroup < pF.mNameGroups.size() ; itGroup++)
+       {
+               pOs << "        Group " << (itGroup + 1) << ": |" << pF.mNameGroups[itGroup] << "| size=" << pF.mNameGroups[itGroup].length() << endl;
+       }
+       pOs << "    Attributs: " << pF.mAttributs;
+       
+       if (pF.mElt.size() != 0)
+       {
+               set<med_int>::iterator itSet = pF.mElt.end();
+               itSet--;
+               pOs << "    Elements: #elt=" << pF.mElt.size() << " min_id=" << (*(pF.mElt.begin())) << " max_id=" << (*itSet) << endl;
+               if (pF.mFlagPrintAll)
+               {
+                       pOs << "        ";
+                       for (set<med_int>::iterator itSet = pF.mElt.begin() ; itSet != pF.mElt.end() ; itSet++)
+                       {
+                               pOs << (*itSet) << " ";
+                       }
+                       pOs << endl;
+               }
+       }
+       else
+       {
+               pOs << "    Elements: #elt=0" << endl;
+       }
+       
+       return pOs;
+}
+
+
+//*****************************************************************************
+// Class Group implementation
+//*****************************************************************************
+
+Group::Group() 
+{
+       reset(); 
+}
+
+
+Group::~Group()  
+{ 
+       reset();  
+}
+
+
+void Group::reset() 
+{ 
+       mName = "";
+       mElt.clear();
+       mIsGroupOfNodes = true;
+       
+       mFlagPrintAll = false;
+}
+
+
+void Group::setName(const string& pName) 
+{ 
+       if (pName.length() > MED_TAILLE_LNOM) throw IllegalArgumentException("", __FILE__, __LINE__);
+       
+       mName = pName; 
+}
+
+
+void Group::insertElt(med_int pIndexElt) 
+{ 
+       if (pIndexElt < 1) throw IllegalArgumentException("", __FILE__, __LINE__);
+       
+       mElt.insert(pIndexElt); 
+}
+
+ostream& operator<<(ostream& pOs, Group& pG)
+{
+       pOs << "Group: " << endl;
+       pOs << "    Name     =|" << pG.mName << "| size=" << pG.mName.length() << endl;
+       pOs << "    Group of =" << (pG.isGroupOfNodes()?"NODES":"ELEMENTS") << endl;    
+
+       if (pG.mElt.size() != 0)
+       {
+               set<med_int>::iterator itSet = pG.mElt.end();
+               itSet--;
+               pOs << "    Elements: #elt=" << pG.mElt.size() << " min_id=" << (*(pG.mElt.begin())) << " max_id=" << (*itSet) << endl;
+               if (pG.mFlagPrintAll)
+               {
+                       pOs << "        ";
+                       for (set<med_int>::iterator itSet = pG.mElt.begin() ; itSet != pG.mElt.end() ; itSet++)
+                       {
+                               pOs << (*itSet) << " ";
+                       }
+                       pOs << endl;
+               }
+       }
+       else
+       {
+               pOs << "    Elements: #elt=0" << endl;
+       }
+       
+       return pOs;
+}
+
+
+} // namespace  multipr
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_Family.hxx b/src/MULTIPR/MULTIPR_Family.hxx
new file mode 100644 (file)
index 0000000..15d1833
--- /dev/null
@@ -0,0 +1,367 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_Family.hxx
+ *
+ * \brief   Class Family, Group and Attributs used to wrap MED file structures.
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#ifndef MULTIPR_FAMILY_HXX
+#define MULTIPR_FAMILY_HXX
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+extern "C"
+{
+       #include "med.h"
+}
+
+
+#include <iostream>
+#include <vector>
+#include <set>
+#include <map>
+
+
+namespace multipr
+{
+
+//*****************************************************************************
+// Predeclaration
+//*****************************************************************************
+
+class Group;
+
+
+//*****************************************************************************
+// Class Attributs
+//*****************************************************************************
+
+class Attributs
+{
+public:
+       
+       /** 
+        * Builds an empty Attributs (default constructor).
+        */
+       Attributs();
+       
+       /**
+        * Destructor. Removes everything.
+        */
+       ~Attributs();
+       
+       /**
+        * Assignment operator (deep copy).
+        * \param  pAttr any Atttibuts to be copied.
+        * \return a reference towards the copy.
+        */
+       Attributs& operator=(const Attributs& pAttr);
+       
+       /**
+        * Resets this object in its state by default (empty). Cleans memory.
+        */
+       void reset();
+       
+       //---------------------------------------------------------------------
+       // I/O
+       //---------------------------------------------------------------------
+       
+       /**
+        * Dumps any Attributs to the given output stream.
+        * \param  pOs any output stream.
+        * \param  pA  any Attributs.
+        * \return the output stream pOs.
+        */
+       friend std::ostream& operator<<(std::ostream& pOs, Attributs& pA);
+       
+public:
+
+       med_int   mNum;     /**< Number of attributes. */
+       med_int*  mId;      /**< Table of identifiers: for each attribute, its identifier. */
+       med_int*  mVal;     /**< Table of values; for each attribute, its value. */
+       char*     mDesc;    /**< Table of description; for each attribute, its description. */
+       
+private:
+
+       // do not allow copy constructor
+       Attributs(const Attributs&);
+       
+       // do not allow operator ==
+       bool operator==(const Attributs&); 
+       
+}; // class Attribut
+
+
+//*****************************************************************************
+// Class Family
+//*****************************************************************************
+
+class Family
+{
+public:
+
+       /** 
+        * Builds an empty Family (default constructor).
+        */
+       Family();
+       
+       /**
+        * Destructor. Removes everything.
+        */
+       ~Family();
+       
+       /**
+        * Resets this object in its state by default (empty). Cleans memory.
+        */
+       void reset();
+       
+       //---------------------------------------------------------------------
+       // Basic accessors/mutators
+       //---------------------------------------------------------------------
+       
+       /**
+        * Returns the identifier (= number) of this Family.
+        * \return the identifier of this Family.
+        */
+       med_int getId() const { return mId; }
+       
+       /**
+        * Returns the name of this Family.
+        * \return the name of this Family.
+        */
+       const char* getName() const { return mName; }
+       
+       /**
+        * Returns true if this Family if a family of nodes, false if is a family of elements (=cells)).
+        * \return true iff this Family if a family of nodes.
+        */
+       bool isFamilyOfNodes() const { return mIsFamilyOfNodes; }
+       
+       /**
+        * Sets whether this Family is a family of nodes or family of elements (= cells).
+        * \param  pIsFamilyOfNodes flag.
+        */
+       void setIsFamilyOfNodes(bool pIsFamilyOfNodes) { mIsFamilyOfNodes = pIsFamilyOfNodes; }
+       
+       /**
+        * Inserts a new element (by its index) into this Family.
+        * \param  pIndexElt index of the element to be added; must be >= 1.
+        * \throw  IllegalArgumentException if pIndexElt <= 0.
+        */
+       void insertElt(med_int pIndexElt);
+       
+       /**
+        * Returns the number of elements in this Family.
+        * \return the number of elements in this Family.
+        */
+       int getSize() const { return mElt.size(); }
+       
+       //---------------------------------------------------------------------
+       // Algorithms
+       //---------------------------------------------------------------------
+
+       /**
+        * Adds all the groups of this Family into the set of groups described by (pGroups, pGroupNameToGroup).
+        * \param  pGroups            current list of groups.
+        * \param  pGroupNameToGroup  table (map) to retrieve a Group* from its name.
+        */
+       void buildGroups(
+               std::vector<Group*>&            pGroups, 
+               std::map<std::string, Group*>&  pGroupNameToGroup) const;
+       
+       /**
+        * Constructor. Returns a copy of this family restricted to the given group if pGroupName != NULL.
+        * Examples: 
+        * 1. If current family have 3 groups "A", "B" and "C" and pGroupName="B", then the new family will only reference the group "B"
+        * 2. If current family have 3 groups "A", "B" and "C" and pGroupName="D", then the new family will reference groups "A", "B" and "C".
+        * WARNING: elements are not copied
+        * \param   pGroupName name of the group to keep.
+        * \return  a copy of this family.
+        */
+       Family* extractGroup(const char* pGroupName);
+       
+       //---------------------------------------------------------------------
+       // I/O
+       //---------------------------------------------------------------------
+
+       /**
+        * Reads a Family from a MED file.
+        * \param  pMEDfile  any valid MED file opened for reading.
+        * \param  pMeshName name of the mesh. 
+        * \param  pIndex    index of the family to be read (must be >= 1).
+        * \throw  IOException if any i/o error occurs.
+        */
+       void readMED(med_idt pMEDfile, char* pMeshName, med_int pIndex);
+       
+       /**
+        * Writes this Family to a MED file.
+        * WARNING: mesh must have been created and added to the MED file before.
+        * \param  pMEDfile  any valid MED file opened for writing.
+        * \param  pPeshName name of the mesh.
+        * \throw  IOException if any i/o error occurs.
+        */
+       void writeMED(med_idt pMEDfile, char* pMeshName);
+       
+       /**
+        * Sets the flag which control the stream operator <<.
+        * \param  pFlag new flag value.
+        */
+       void setPrintAll(bool pFlag) { mFlagPrintAll = pFlag; } 
+       
+       /**
+        * Dumps any Family to the given output stream.
+        * \param  pOs any output stream.
+        * \param  pF  any Family.
+        * \return the output stream pOs.
+        */
+       friend std::ostream& operator<<(std::ostream& pOs, Family& pF);
+       
+private:
+       
+       char                     mName[MED_TAILLE_NOM + 1];   /** Name of the Family */
+       med_int                  mId;               /**< Id: > 0 if family of nodes; < 0 if family of elements. */
+       std::set<med_int>        mElt;              /**< Set of all the elements (by their index in 1..*). */
+       std::string              mStrNameGroups;    /**< A string with name of all groups which contain the Family. */
+       std::vector<std::string> mNameGroups;       /**< List of groups (by name) which contain the Family. */
+       Attributs                mAttributs;        /**< All the attributed related to the Family. */
+       bool                     mIsFamilyOfNodes;  /**< Is it a family of nodes or a family of elements? */
+       
+       bool                     mFlagPrintAll;     /** Flag to control the behaviour of the stream operator <<. */
+       
+private:
+
+       // do not allow copy constructor
+       Family(const Family&);
+       
+       // do not allow copy
+       Family& operator=(const Family&);
+       
+       // do not allow operator ==
+       bool operator==(const Family&); 
+       
+}; // class Family
+
+
+//*****************************************************************************
+// Class Group
+//*****************************************************************************
+
+class Group
+{
+public:
+
+       /** 
+        * Builds an empty group (default constructor).
+        */
+       Group();
+       
+       /**
+        * Destructor. Removes everything.
+        */
+       ~Group();
+       
+       /**
+        * Resets this object in its state by default (empty). Cleans memory.
+        */
+       void reset();
+       
+       //---------------------------------------------------------------------
+       // Basic accessors/mutators
+       //---------------------------------------------------------------------
+       
+       /**
+        * Returns true if it is a group of nodes, false if it is a group of elements.
+        * \return true if it is a group of nodes, false if it is a group of elements.
+        */
+       bool isGroupOfNodes() const { return mIsGroupOfNodes; }
+       
+       /**
+        * Sets whether it is a group of nodes or a group of elements. 
+        * \param  pIsGroupOfNodes true for a group of nodes, false for a group of elements.
+        */
+       void setIsGroupOfNodes(bool pIsGroupOfNodes) { mIsGroupOfNodes = pIsGroupOfNodes; }
+       
+       /**
+        * Returns the name of this Group.
+        * \return the name of this Group.
+        */
+       const std::string& getName() const { return mName; }
+        
+       /**
+        * Sets the name of this Group.
+        * \param  pName new name of this Group (length of name must not exceed MED_TAILLE_LNOM).
+        */
+       void setName(const std::string& pName);
+       
+       /**
+        * Adds the index of a new element to this Group.
+        * \param  pIndexElt must be >= 1.
+        */
+       void insertElt(med_int pIndexElt);
+       
+       /**
+        * Returns the set of all the elements referenced in this Group.
+        * \return the set of all the elements referenced in this Group.
+        */
+       const std::set<med_int>& getSetOfElt() const { return mElt; }
+       
+       /**
+        * Returns the number of elements referenced in this Group.
+        * \return the number of elements referenced in this Group.
+        */
+       int getSize() const { return mElt.size(); }
+       
+       //---------------------------------------------------------------------
+       // I/O
+       //---------------------------------------------------------------------
+       
+       /**
+        * Sets the flag which control the stream operator <<.
+        * \param  pFlag new flag value.
+        */
+       void setPrintAll(bool pFlag) { mFlagPrintAll = pFlag; } 
+       
+       /**
+        * Dumps any Group to the given output stream.
+        * \param  pOs any output stream.
+        * \param  pG  any Group.
+        * \return the output stream pOs.
+        */
+       friend std::ostream& operator<<(std::ostream& pOs, Group& pG);
+       
+private:
+       
+       std::string        mName;            /**< Name of the group. */
+       std::set<med_int>  mElt;             /**< All elements of this group; each element is referenced by its index >= 1; each element is unique. */
+       bool               mIsGroupOfNodes;  /**< Is it a group of nodes or a group of elements? */
+       
+       bool               mFlagPrintAll;    /** Flag to control the behaviour of the stream operator <<. */
+       
+private:
+
+       // do not allow copy constructor
+       Group(const Group&);
+       
+       // do not allow copy
+       Group& operator=(const Group&);
+       
+       // do not allow operator ==
+       bool operator==(const Group&); 
+       
+}; // class Group
+
+
+} // namespace MULTIPR
+
+
+#endif // MULTIPR_FAMILY_HXX
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_Field.cxx b/src/MULTIPR/MULTIPR_Field.cxx
new file mode 100644 (file)
index 0000000..6d1854a
--- /dev/null
@@ -0,0 +1,524 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_Field.cxx
+ *
+ * \brief   see MULTIPR_Field.hxx
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+#include "MULTIPR_Field.hxx"
+#include "MULTIPR_Exceptions.hxx"
+
+#include <iostream>
+
+using namespace std;
+
+
+namespace multipr
+{
+
+
+//*****************************************************************************
+// Class Field implementation
+//*****************************************************************************
+
+Field::Field() 
+{
+       reset(); 
+}
+
+
+Field::~Field()  
+{ 
+       reset();  
+}
+
+
+void Field::reset() 
+{ 
+       mName[0]       = '\0';
+       mEntity        = MED_NOEUD;
+       mGeom          = MED_NONE;
+       mType          = MED_FLOAT64;
+       mSizeOfType    = 8;
+       mNumComponents = 0;
+       mStrComponent  = "";
+       mStrUnit       = "";
+       
+       mNGauss.clear();
+       mDT.clear();
+       mNumDT.clear();
+       mDTUnit.clear();
+       mNumO.clear();
+       mGaussLoc.clear();
+       mProfil.clear();
+       mSizeOfData.clear();
+       mNVal.clear();
+       
+       for (unsigned it = 0 ; it < mVal.size() ; it++)
+       {
+               delete[] mVal[it];
+       }
+       mVal.clear();
+       
+       mFlagPrintAll = false;
+}
+
+
+bool Field::isEmpty() const
+{
+       return (mNGauss.size() == 0);
+}
+
+
+int Field::getNumberOfGaussPointsByElement(int pTimeStepIt) const
+{
+       if ((pTimeStepIt < 1) || (pTimeStepIt > int(mNGauss.size()))) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
+       
+       return mNGauss[pTimeStepIt - 1];
+}
+
+
+const string& Field::getNameGaussLoc(int pTimeStepIt) const
+{
+       if ((pTimeStepIt < 1) || (pTimeStepIt > int(mNGauss.size()))) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
+       
+       return mGaussLoc[pTimeStepIt - 1];
+}
+
+
+const unsigned char* Field::getValue(int pTimeStepIt, int pIndex) const
+{
+       if ((pTimeStepIt < 1) || (pTimeStepIt > int(mNGauss.size()))) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
+       if ((pIndex < 1) || (pIndex > mNVal[pTimeStepIt - 1] / mNGauss[pTimeStepIt - 1])) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
+       
+       // size of one data = size of type * number of components * number of Gauss points
+       int sizeOfOneData = mSizeOfType * mNumComponents * mNGauss[pTimeStepIt - 1];
+       
+       unsigned char* ret = mVal[pTimeStepIt - 1] + (pIndex - 1) * sizeOfOneData;
+       
+       return ret;
+}
+
+
+Field* Field::extractSubSet(const set<med_int>& pSetIndices) const
+{
+       Field* subset = new Field();
+       
+       memcpy(subset->mName, mName, MED_TAILLE_NOM + 1);
+       subset->mEntity        = mEntity;
+       subset->mGeom          = mGeom;
+       subset->mType          = mType;
+       subset->mSizeOfType    = mSizeOfType;
+       subset->mNumComponents = mNumComponents;
+       subset->mStrComponent  = mStrComponent;
+       subset->mStrUnit       = mStrUnit;
+       
+       subset->mNGauss        = mNGauss;
+       subset->mDT            = mDT;
+       subset->mNumDT         = mNumDT;
+       subset->mDTUnit        = mDTUnit;
+       subset->mNumO          = mNumO;
+       subset->mGaussLoc      = mGaussLoc;
+       subset->mProfil        = mProfil;
+       
+       // for each time step
+       for (unsigned itTimeStep = 0 ; itTimeStep < mNGauss.size() ; itTimeStep++)
+       {
+               if (mProfil[itTimeStep].size() != 0) throw UnsupportedOperationException("", __FILE__, __LINE__);
+               // TODO ???
+               // WARNING : do not manage profil for the moment
+               // if there is a profil,
+               // 1. we should set mProfil to NO_PROFIL for this time_step
+               // 2. we should extract data according to the profil
+               
+               int nval = pSetIndices.size() * subset->mNGauss[itTimeStep];
+               subset->mNVal.push_back(nval);
+               
+               int sizeOfData = nval * mSizeOfType * mNumComponents;
+               subset->mSizeOfData.push_back(sizeOfData);
+               
+               unsigned char* data = new unsigned char[sizeOfData];
+               unsigned char* dest = data;
+               int sizeOfOneData = mSizeOfType * mNumComponents * subset->mNGauss[itTimeStep];
+               
+               //cout << "Size of 1 data = " << sizeOfOneData << endl; // debug
+               
+               // for each element to extract
+               for (set<med_int>::iterator itSet = pSetIndices.begin() ; itSet != pSetIndices.end() ; itSet++)
+               {
+                       int indexElt = (*itSet);
+                       
+                       // MED index start at 1.
+                       if (indexElt < 1) throw new IllegalArgumentException("", __FILE__, __LINE__);
+                       
+                       unsigned char* src = mVal[itTimeStep] + (indexElt - 1) * sizeOfOneData;
+                       memcpy(dest, src, sizeOfOneData);
+                       
+                       dest += sizeOfOneData;
+               }
+               subset->mVal.push_back(data);
+       }
+       
+       return subset;
+}
+
+
+void Field::getSetOfGaussLoc(set<string>& pSetOfGaussLoc) const
+{
+       for (unsigned itGaussLoc = 0 ; itGaussLoc < mGaussLoc.size() ; itGaussLoc++)
+       {
+               const string& gaussLocName = mGaussLoc[itGaussLoc];
+               
+               if (gaussLocName.length() != 0)
+               {
+                       pSetOfGaussLoc.insert(gaussLocName);
+               }
+       }
+}
+
+
+void Field::readMED(med_idt pMEDfile, med_int pIndex, char* pMeshName)
+{
+       if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
+       if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       if (strlen(pMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
+       if (pIndex < 1) throw IllegalArgumentException("", __FILE__, __LINE__);
+       
+       reset();
+       
+       mNumComponents = MEDnChamp(pMEDfile, pIndex);
+       
+       if (mNumComponents < 0) throw IOException("", __FILE__, __LINE__);
+       
+       char* strComponent = new char[mNumComponents * MED_TAILLE_PNOM + 1];
+       char* strUnit      = new char[mNumComponents * MED_TAILLE_PNOM + 1];
+       
+       strComponent[0] = '\0';
+       strUnit[0] = '\0';
+       
+       med_err ret = MEDchampInfo(
+               pMEDfile, 
+               pIndex, 
+               mName, 
+               &(mType), 
+               strComponent, 
+               strUnit, 
+               mNumComponents);
+       
+       if (ret != 0) throw IOException("", __FILE__, __LINE__);
+       
+       mStrComponent = strComponent;
+       mStrUnit = strUnit;
+       
+       delete[] strUnit;
+       delete[] strComponent;
+       
+       switch (mType)
+       {
+               case MED_FLOAT64: mSizeOfType = 8; break;
+               case MED_INT64: mSizeOfType = 8; break;
+               case MED_INT32: mSizeOfType = 4; break;
+               case MED_INT: mSizeOfType = 4; break;
+               default: throw IllegalStateException("should not be there", __FILE__, __LINE__);
+       }
+       
+       //---------------------------------------------------------------------
+       // Read fields over nodes
+       //---------------------------------------------------------------------
+       bool fieldOnNodes = false;
+       {
+               med_int numTimeStepNodes = MEDnPasdetemps(
+                       pMEDfile, 
+                       mName, 
+                       MED_NOEUD, 
+                       (med_geometrie_element) 0);
+               
+               if (numTimeStepNodes < 0) throw IOException("", __FILE__, __LINE__);
+               
+               if (numTimeStepNodes != 0)
+               {
+                       fieldOnNodes = true;
+                       mEntity = MED_NOEUD;
+                       mGeom = (med_geometrie_element) 0;
+                       readMEDtimeSteps(pMEDfile, numTimeStepNodes, pMeshName);
+               }
+       }
+
+       //---------------------------------------------------------------------
+       // Read fields over elements
+       //---------------------------------------------------------------------
+       {
+               med_int numTimeStepElt = MEDnPasdetemps(
+                       pMEDfile, 
+                       mName, 
+                       MED_MAILLE, 
+                       MED_TETRA10);
+               
+               if (numTimeStepElt  < 0) throw IOException("", __FILE__, __LINE__);     
+               
+               if (numTimeStepElt != 0)
+               {
+                       if (fieldOnNodes) throw IllegalStateException("", __FILE__, __LINE__);
+                       
+                       mEntity = MED_MAILLE;
+                       mGeom = MED_TETRA10;
+                       readMEDtimeSteps(pMEDfile, numTimeStepElt, pMeshName);
+               }
+       }
+}
+
+
+void Field::readMEDtimeSteps(med_idt pMEDfile, med_int pNumberOfTimeSteps, char* pMeshName)
+{
+       if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
+       if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       if (strlen(pMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
+       if (pNumberOfTimeSteps < 0) throw IllegalArgumentException("", __FILE__, __LINE__);
+       
+       char strEntity[8];
+       switch (mEntity)
+       {
+               case MED_ARETE:
+               case MED_FACE:
+               case MED_MAILLE: strcpy(strEntity, "CELLS"); break;
+               case MED_NOEUD: strcpy(strEntity, "NODES"); break;
+               default: strcpy(strEntity, "UNKNOWN"); break;
+       }
+       
+       // iterates over time step
+       for (int itTimeStep = 1 ; itTimeStep <= pNumberOfTimeSteps ; itTimeStep++)
+       {
+               med_int ngauss;
+               med_int numdt;
+               med_int numo;
+               char dtunit[MED_TAILLE_PNOM + 1];
+               med_float dt;
+               char maa[MED_TAILLE_NOM + 1];
+               med_booleen local;
+               med_int nmaa;
+               
+               med_err ret = MEDpasdetempsInfo(
+                       pMEDfile, 
+                       mName, 
+                       mEntity, 
+                       mGeom, 
+                       itTimeStep, 
+                       &ngauss, 
+                       &numdt, 
+                       &numo, 
+                       dtunit, 
+                       &dt, 
+                       maa, 
+                       &local, 
+                       &nmaa);
+                       
+               if (ret != 0) throw IOException("i/o error while reading #timesteps in MED file", __FILE__, __LINE__);
+               
+               // mesh must be local
+               if (local != MED_VRAI) throw IllegalStateException("only local fields are currently supported", __FILE__, __LINE__);
+               
+               // #mesh must be 1
+               if (nmaa != 1) throw IllegalStateException("field shoud be associated with 1 mesh only", __FILE__, __LINE__);
+               
+               // mesh must be pMeshName
+               //MULTIPR_CHECK((strcmp(maa, pMeshName) == 0), MED_ILLEGAL_FILE, pMEDfile);
+               // if field does not apply on the current mesh, skip
+               if (strcmp(maa, pMeshName) != 0) 
+               {
+                       continue;
+               }
+               
+               mNGauss.push_back(ngauss);
+               mDT.push_back(dt);
+               mNumDT.push_back(numdt);
+               mDTUnit.push_back(dtunit);
+               mNumO.push_back(numo);
+               
+               //MULTIPR_LOG("Time step #" << itTimeStep << ": #gauss=" << ngauss << " dt=" << dt << " maa=" << maa << " has_dt?" << ((numdt==MED_NOPDT)?"no":"yes") << " numdt=" << numdt << " unit=" << dtunit << " has_order?" << ((numo==MED_NONOR)?"no":"yes") << " numo:" << numo << endl);
+               
+               med_int nval = MEDnVal(
+                       pMEDfile, 
+                       mName, 
+                       mEntity, 
+                       mGeom, 
+                       numdt, 
+                       numo, 
+                       pMeshName, 
+                       MED_GLOBAL);
+               
+               if (nval < 0) throw IOException("i/o error while reading field in MED file", __FILE__, __LINE__);
+               
+               mNVal.push_back(nval);
+               
+               char gaussLocName[MED_TAILLE_NOM + 1];
+               char profilName[MED_TAILLE_NOM + 1];
+               int sizeOfData = mSizeOfType * mNumComponents * nval;
+               mSizeOfData.push_back(sizeOfData);
+               unsigned char* fieldData = new unsigned char[sizeOfData];
+               
+               ret = MEDchampLire(
+                       pMEDfile, 
+                       pMeshName,
+                       mName, 
+                       fieldData, 
+                       MED_FULL_INTERLACE, 
+                       MED_ALL, 
+                       gaussLocName, 
+                       profilName, 
+                       MED_COMPACT, //MED_GLOBAL, MED_NO_PFLMOD, MED_COMPACT
+                       mEntity, 
+                       mGeom, 
+                       numdt, 
+                       numo);
+               
+               if (ret != 0) throw IOException("i/o error while reading field in MED file", __FILE__, __LINE__);
+       
+               mGaussLoc.push_back(gaussLocName);
+               mProfil.push_back(profilName);
+               mVal.push_back(fieldData);
+       }
+}
+
+
+void Field::writeMED(med_idt pMEDfile, char* pMeshName)
+{
+       if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
+       if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       if (strlen(pMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
+       if (mNumComponents < 1) throw IllegalStateException("", __FILE__, __LINE__);
+       
+       med_err ret = MEDchampCr(
+               pMEDfile, 
+               mName,             // name of the field
+               mType,             // type of data (MED_FLOAT64, MED_INT32, etc.)
+               const_cast<char*>(mStrComponent.c_str()),     // name of components
+               const_cast<char*>(mStrUnit.c_str()),          // name of units
+               mNumComponents);   // number of components
+       
+       if (ret != 0) throw IOException("i/o error while creating field in MED file", __FILE__, __LINE__);
+       
+       // for each time step
+       for (unsigned i = 0 ; i < mNGauss.size() ; i++)
+       {
+               // skip if no values
+               if (mNVal[i] == 0) continue;
+               
+               ret = MEDchampEcr(
+                       pMEDfile,
+                       pMeshName,          // name of the mesh (first call to MEDchampEcr => name of reference)
+                       mName,              // name of the field
+                       mVal[i],            // data (= values)
+                       MED_FULL_INTERLACE, // data organization
+                       mNVal[i],           // number of values
+                       const_cast<char*>(mGaussLoc[i].c_str()), // name of Gauss reference
+                       MED_ALL,            // components to be selected
+                       const_cast<char*>(mProfil[i].c_str()), // name of profil
+                       MED_GLOBAL,         // how to read data: MED_NO_PFLMOD,MED_COMPACT,MED_GLOBAL
+                       mEntity,            // type of entity (MED_NOEUD, MED_MAILLE, etc.)
+                       mGeom,              // type of geometry (TETRA10, etc.)
+                       mNumDT[i],          // time step iteration
+                       const_cast<char*>(mDTUnit[i].c_str()), // unit of time step
+                       mDT[i],             // time key
+                       mNumO[i]);          // order number
+               
+               if (ret != 0) throw IOException("i/o error while writing field in MED file", __FILE__, __LINE__);
+       }
+}
+
+
+ostream& operator<<(ostream& pOs, Field& pF)
+{
+       char strEntity[16];
+       switch (pF.mEntity) 
+       {
+               case MED_MAILLE: strcpy(strEntity, "MED_MAILLE"); break;
+               case MED_FACE:   strcpy(strEntity, "MED_FACE"); break;
+               case MED_ARETE:  strcpy(strEntity, "MED_ARETE"); break;
+               case MED_NOEUD:  strcpy(strEntity, "MED_NOEUD"); break;
+               default:         strcpy(strEntity, "UNKNOWN"); break;
+       }
+       
+       char strType[16];
+       switch (pF.mType) 
+       {
+               case MED_FLOAT64: strcpy(strType, "MED_FLOAT64"); break;
+               case MED_INT32:   strcpy(strType, "MED_INT32"); break;
+               case MED_INT64:   strcpy(strType, "MED_INT64"); break;
+               case MED_INT:     strcpy(strType, "MED_INT"); break;
+               default:          strcpy(strType, "UNKNOWN"); break;
+       }
+       
+       pOs << "Field: " << endl;
+       pOs << "    Name       =|" << pF.mName << "|" << endl;
+       pOs << "    Entity     =" << strEntity << endl;
+       pOs << "    Geom       =" << pF.mGeom << endl;
+       pOs << "    Type       =" << strType << " (size=" << pF.mSizeOfType << ")" << endl;
+       pOs << "    #Components=" << pF.mNumComponents << endl;
+       pOs << "        Name component=|" << pF.mStrComponent << "|" << endl;
+       pOs << "        Unit component=|" << pF.mStrUnit << "|" << endl;
+       pOs << "    #Time steps=" << pF.mNGauss.size() << endl;
+       
+       for (unsigned itTimeStep = 0 ; itTimeStep < pF.mNGauss.size() ; itTimeStep++)
+       {
+               pOs << "        Time=" << pF.mDT[itTimeStep];
+               pOs << "  it=" << pF.mNumDT[itTimeStep];
+               pOs << "  order=" << pF.mNumO[itTimeStep];
+               pOs << "  #gauss=" << pF.mNGauss[itTimeStep];
+               pOs << "  #val=" << pF.mNVal[itTimeStep];
+               pOs << "  sizeof_val=" << pF.mSizeOfData[itTimeStep];
+               pOs << "  gauss_loc=|" << ((pF.mGaussLoc[itTimeStep].size() == 0)?"NONE":pF.mGaussLoc[itTimeStep]) << "|  size=" << pF.mGaussLoc[itTimeStep].size();
+               pOs << "  profil=|" << ((pF.mProfil[itTimeStep].size() == 0)?"NONE":pF.mProfil[itTimeStep]) << "|  size=" << pF.mProfil[itTimeStep].size() << endl; 
+               
+               if (pF.mFlagPrintAll)
+               {
+                       cout << "    Values: ";
+                       switch (pF.mType)
+                       {
+                       case MED_FLOAT64: 
+                               {
+                                       med_float* src = reinterpret_cast<med_float*>(pF.mVal[itTimeStep]);
+                                       for (int itVal = 0 ; itVal < pF.mNVal[itTimeStep] * pF.mNumComponents ; itVal++)
+                                       {
+                                               cout << src[itVal] << " ";
+                                       }  
+                               }
+                               break;
+                       case MED_INT:
+                       case MED_INT32:   
+                               {
+                                       med_int* src = reinterpret_cast<med_int*>(pF.mVal[itTimeStep]);
+                                       for (int itVal = 0 ; itVal < pF.mNVal[itTimeStep] * pF.mNumComponents ; itVal++)
+                                       {
+                                               cout << src[itVal] << " ";
+                                       }  
+                               }
+                               break;
+                       case MED_INT64:
+                               // not yet implemented
+                               throw UnsupportedOperationException("not yet implemented", __FILE__, __LINE__);
+                       default:          
+                               // should not be there
+                               throw IllegalStateException("should not be there", __FILE__, __LINE__);
+                       }
+                       cout << endl;
+               }
+               
+       }
+       
+       return pOs;
+}
+
+
+} // namespace  multipr
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_Field.hxx b/src/MULTIPR/MULTIPR_Field.hxx
new file mode 100644 (file)
index 0000000..2e82140
--- /dev/null
@@ -0,0 +1,236 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_Field.hxx
+ *
+ * \brief   Class Field used to wrap MED file fields.
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#ifndef MULTIPR_FIELD_HXX
+#define MULTIPR_FIELD_HXX
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+extern "C"
+{
+       #include "med.h"
+}
+
+#include <string>
+#include <vector>
+#include <set>
+
+
+namespace multipr
+{
+
+
+//*****************************************************************************
+// Class Field
+//*****************************************************************************
+
+class Field
+{
+public:
+
+       /** 
+        * Builds an empty field (default constructor).
+        */
+       Field();
+       
+       /**
+        * Destructor. Removes everything.
+        */
+       ~Field();
+       
+       /**
+        * Resets this object in its state by default (empty). Cleans memory.
+        */
+       void reset();
+       
+       //---------------------------------------------------------------------
+       // Basic accessors/mutators
+       //---------------------------------------------------------------------
+       
+       /**
+        * Returns true iff this field is empty (no data).
+        * \return true if this field is empty, false otherwise.
+        */
+       bool isEmpty() const;
+       
+       /**
+        * Returns true iff this field apply on nodes (otherwise, information are related to elements).
+        * \return true iff this field apply on nodes.
+        */
+       bool isFieldOnNodes() const { return (mEntity == MED_NOEUD); }
+       
+       /**
+        * Returns the name of this Field.
+        * \return the name of this Field.
+        */
+       const char* getName() const { return mName; }
+       
+       /**
+        * Returns the number of time steps in this Field.
+        * \return the number of time steps in this Field.
+        */
+       int getNumberOfTimeSteps() const { return mNGauss.size(); }
+       
+       /**
+        * Returns the numeric type of information contained in this Field (e.g. MED_FLOAT64).
+        * \return the numeric type of this Field.
+        */
+       med_type_champ getType() const { return mType; }
+       
+       /**
+        * Returns the number of components of this Field.
+        * \return the number of components of this Field.
+        */
+       int getNumberOfComponents() const { return mNumComponents; }
+       
+       /**
+        * Returns the number of Gauss points for each element at the given time step.
+        * \param  pTimeStepIt iteration of the field; must be in [1..MAX_ITERATION].
+        * \return number of Gauss points in the elements of this Field at the given iteration.
+        * \throw  IndexOutOfBoundsException if pTimeStepIt not in [1..MAX_ITERATION].
+        */
+       int getNumberOfGaussPointsByElement(int pTimeStepIt) const;
+       
+       /**
+        * Returns the name of the Gauss localization related to the given iteration.
+        * \param  pTimeStepIt iteration of the field; must be in [1..MAX_ITERATION].
+        * \return the name of the Gauss localization related to the given iteration.
+        * \throw  IndexOutOfBoundsException if pTimeStepIt not in [1..MAX_ITERATION].
+        */
+       const std::string& getNameGaussLoc(int pTimeStepIt) const;
+       
+       /**
+        * Returns a pointer towards the first value of this Field for the given element at the given time step.
+        * \param  pTimeStepIt iteration of the field; must be in [1..MAX_ITERATION].
+        * \param  pIndex      index of the element; must be >= 1.
+        * \return the value of this Field for the given element at the given time step.
+        * \throw  IndexOutOfBoundsException if pTimeStepIt or pIndex are invalid.
+        */
+       const unsigned char* getValue(int pTimeStepIt, int pIndex) const;
+       
+       //---------------------------------------------------------------------
+       // Algorithms
+       //---------------------------------------------------------------------
+       
+       /**
+        * Creates a subset of this Field restricted to a set of elements (NODES or CELLS).
+        * This method performs a projection of this Field on the given set of elements.         
+        * \param  pSetIndices WARNING: indices start at 1.
+        * \return a new Field restricted to the given set of elements.
+        */
+       Field* extractSubSet(const std::set<med_int>& pSetIndices) const;
+       
+       /**
+        * Adds the set of GaussLoc used by this Field into the given set.
+        * \param  pSetOfGauss any set of Gauss localisation.
+        */
+       void getSetOfGaussLoc(std::set<std::string>& pSetOfGaussLoc) const;
+
+       //---------------------------------------------------------------------
+       // I/O
+       //---------------------------------------------------------------------
+       
+       /**
+        * Reads a field from a MED file.
+        * If the field is not related to the given mesh, the result is an empty field.
+        * \param  pMEDfile  any valid MED file opened for reading.
+        * \param  pIndex    index of the field to be read; must be >= 1.
+        * \param  pMeshName name of the mesh (a field is always related to a mesh).
+        * \throw  IOException if any i/o error occurs.
+        */
+       void readMED(med_idt pMEDfile, med_int pIndex, char* pMeshName);
+       
+       /**
+        * Writes this field to a MED file. The field is linked to the given mesh.
+        * WARNING: all related Gauss info must have been added to the MED file before.
+        * \param  pMEDfile  any valid MED file opened for writing.
+        * \param  pMeshName name of the mesh.
+        * \throw  IOException if any i/o error occurs.
+        */
+       void writeMED(med_idt pMEDfile, char* pMeshName);
+       
+       /**
+        * Sets the flag which control the stream operator <<.
+        * \param  pFlag new flag value.
+        */
+       void setPrintAll(bool pFlag) { mFlagPrintAll = pFlag; } 
+       
+       /**
+        * Dumps any Field to the given output stream.
+        * \param  pOs any output stream.
+        * \param  pF  any Field.
+        * \return the output stream pOs.
+        */
+       friend std::ostream& operator<<(std::ostream& pOs, Field& pF);
+       
+private:
+
+       /**
+        * Reads all the information related to its field and a given time step (by its index).
+        * \param  pMEDfile           MED file handle.
+        * \param  pNumberOfTimeSteps number of timesteps (iteration) to be read.
+        * \param  pMeshName          name of the mesh.
+        * \throw  IOException if any i/o error occurs.
+        */
+       void readMEDtimeSteps(med_idt pMEDfile, med_int pNumberOfTimeSteps, char* pMeshName);
+       
+private:
+       
+       char                         mName[MED_TAILLE_NOM + 1];
+       med_entite_maillage          mEntity;      // type of entity, e.g. MED_MAILLE
+       med_geometrie_element        mGeom;        // type of primitives, e.g. MED_TETRA10 (MED_NONE for a field on nodes)
+       med_type_champ               mType;        // type of field, e.g. MED_FLOAT64, MED_INT32
+       int                          mSizeOfType;  // 8 for MED_FLOAT64, 4 for MED_INT32, etc.
+       med_int                      mNumComponents;
+       std::string                  mStrComponent;
+       std::string                  mStrUnit;
+       
+       // Information related to time steps.
+       // Each vector should contain the same number of elements.
+       // Number of time step = mNGauss.size() = mDT.size() = ...
+       
+       std::vector<med_int>         mNGauss;        /**< For each time step, number of Gauss points in the field. */
+       std::vector<med_float>       mDT;            /**< For each time step, value of time step. */
+       std::vector<med_int>         mNumDT;         /**< For each time step, iteration number. */
+       std::vector<std::string>     mDTUnit;        /**< For each time step, units. */
+       std::vector<med_int>         mNumO;          /**< For each time step, order number. */
+       std::vector<std::string>     mGaussLoc;      /**< For each time step, name of Gauss localization to be used (empty if none). */
+       std::vector<std::string>     mProfil;        /**< For each time step, name of the profil to be used (empty if none). */
+       std::vector<int>             mSizeOfData;    /**< For each time step, sizeof data (mVal) in bytes. */
+       std::vector<med_int>         mNVal;          /**< For each time step, number of values. */
+       std::vector<unsigned char*>  mVal;           /**< For each time step, raw data; can be MED_FLOAT64, MED_INT32, etc. see mType. */
+
+       bool                         mFlagPrintAll;  /**< Flag to control the behaviour of the stream operator <<. */
+       
+private:
+
+       // do not allow copy constructor
+       Field(const Field&);
+       
+       // do not allow copy
+       Field& operator=(const Field&);
+       
+       // do not allow operator ==
+       bool operator==(const Field&); 
+       
+}; // class Field
+
+
+} // namespace MULTIPR
+
+
+#endif // MULTIPR_FIELD_HXX
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_GaussLoc.cxx b/src/MULTIPR/MULTIPR_GaussLoc.cxx
new file mode 100644 (file)
index 0000000..7fd8566
--- /dev/null
@@ -0,0 +1,235 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_GaussLoc.cxx
+ *
+ * \brief   see MULTIPR_GaussLoc.hxx
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+#include "MULTIPR_GaussLoc.hxx"
+#include "MULTIPR_Utils.hxx"
+#include "MULTIPR_Exceptions.hxx"
+
+#include <iostream>
+
+using namespace std;
+
+
+namespace multipr
+{
+
+
+//*****************************************************************************
+// Class GaussLoc implementation
+//*****************************************************************************
+
+GaussLoc::GaussLoc() 
+{
+       mRefCoo    = NULL;
+       mGaussCoo  = NULL;
+       mWeight    = NULL;
+       
+       reset(); 
+}
+
+
+GaussLoc::GaussLoc(const GaussLoc& pGaussLoc)
+{
+       mRefCoo   = NULL;
+       mGaussCoo = NULL;
+       mWeight   = NULL;
+       
+       strcpy(mName, pGaussLoc.mName);
+       
+       mGeom     = pGaussLoc.mGeom;
+       mDim      = pGaussLoc.mDim;
+       mNumNodes = pGaussLoc.mNumNodes;
+       mNumGauss = pGaussLoc.mNumGauss;
+       
+       if (mDim != (mGeom / 100)) throw IllegalStateException("", __FILE__, __LINE__);
+       if (mNumNodes != (mGeom % 100)) throw IllegalStateException("", __FILE__, __LINE__);
+       
+       if (pGaussLoc.mRefCoo != NULL)
+       {
+               mRefCoo = new med_float[mDim * mNumNodes];
+               memcpy(mRefCoo, pGaussLoc.mRefCoo, sizeof(med_float) * mDim * mNumNodes);
+       }
+       
+       if (pGaussLoc.mGaussCoo != NULL)
+       {
+               mGaussCoo  = new med_float[mDim * mNumGauss];
+               memcpy(mGaussCoo, pGaussLoc.mGaussCoo, sizeof(med_float) * mDim * mNumGauss);
+       }
+       
+       if (pGaussLoc.mWeight != NULL)
+       {
+               mWeight = new med_float[mNumGauss];
+               memcpy(mWeight, pGaussLoc.mWeight, sizeof(med_float) * mNumGauss);
+       }
+}
+
+
+GaussLoc::~GaussLoc()  
+{ 
+       reset();  
+}
+
+
+void GaussLoc::reset() 
+{ 
+       mName[0]  = '\0';
+       mGeom     = MED_NONE;
+       mDim      = 0;
+       mNumNodes = 0;
+       mNumGauss = 0;
+       
+       if (mRefCoo   != NULL) { delete[] mRefCoo;   mRefCoo   = NULL; }
+       if (mGaussCoo != NULL) { delete[] mGaussCoo; mGaussCoo = NULL; }
+       if (mWeight   != NULL) { delete[] mWeight;   mWeight   = NULL; }
+}
+
+
+void GaussLoc::getCoordGaussPoints(
+       const med_float* pCooElt,  
+       med_float* pCooGaussPoints) const
+{
+       // debug
+       //printArray2D(pCooElt, mNumNodes, mDim, "Node");
+       
+       // WARNING: assumes TETRA10 !!!
+       // This method is not completely generic and should be extended to support all cases.
+       if (mGeom != MED_TETRA10) throw UnsupportedOperationException("only support TETRA10 for the moment", __FILE__, __LINE__);
+       
+       const med_float* pt1 = pCooElt;
+       const med_float* pt2 = pt1 + mDim;
+       const med_float* pt3 = pt2 + mDim;
+       const med_float* pt4 = pt3 + mDim;
+       
+       const med_float* coeff = mGaussCoo;
+       med_float* dest        = pCooGaussPoints;
+       
+       // for each Gauss point
+       for (int i = 0 ; i < mNumGauss ; i++)
+       {
+               dest[0] = pt2[0] + (pt4[0] - pt2[0]) * coeff[0] + (pt1[0] - pt2[0]) * coeff[1] + (pt3[0] - pt2[0]) * coeff[2];
+               dest[1] = pt2[1] + (pt4[1] - pt2[1]) * coeff[0] + (pt1[1] - pt2[1]) * coeff[1] + (pt3[1] - pt2[1]) * coeff[2];
+               dest[2] = pt2[2] + (pt4[2] - pt2[2]) * coeff[0] + (pt1[2] - pt2[2]) * coeff[1] + (pt3[2] - pt2[2]) * coeff[2];
+               
+               // prepare next point
+               coeff += mDim;
+               dest += mDim;
+       }
+}
+
+
+void GaussLoc::readMED(med_idt pMEDfile, med_int pIndex)
+{
+       if (pMEDfile == 0) throw IOException("pMEDfile should not be NULL", __FILE__, __LINE__);
+       if (pIndex < 1) throw IllegalArgumentException("pIndex should be >= 1", __FILE__, __LINE__);
+       
+       reset();
+       
+       med_err ret = MEDgaussInfo(
+               pMEDfile, 
+               pIndex, 
+               mName, 
+               &mGeom, 
+               &mNumGauss);
+       
+       if (ret != 0) throw IOException("i/o error while reading Gauss localization information in MED file", __FILE__, __LINE__);
+       
+       mDim      = mGeom / 100;
+       mNumNodes = mGeom % 100;
+       
+       mRefCoo   = new med_float[mDim * mNumNodes];
+       mGaussCoo = new med_float[mDim * mNumGauss];
+       mWeight   = new med_float[mNumGauss];
+       
+       ret = MEDgaussLire(
+               pMEDfile, 
+               mRefCoo, 
+               mGaussCoo, 
+               mWeight, 
+               MED_FULL_INTERLACE, 
+               mName);
+               
+       if (ret != 0) throw IOException("i/o error while reading Gauss localization in MED file", __FILE__, __LINE__);
+}
+
+
+void GaussLoc::writeMED(med_idt pMEDfile)
+{
+       if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
+       if (mNumGauss < 0) throw IllegalStateException("", __FILE__, __LINE__);
+       if (mRefCoo == NULL) throw IllegalStateException("", __FILE__, __LINE__);
+       if (mGaussCoo == NULL) throw IllegalStateException("", __FILE__, __LINE__);
+       if (mWeight == NULL) throw IllegalStateException("", __FILE__, __LINE__);
+       if (strlen(mName) > MED_TAILLE_NOM) throw IllegalStateException("", __FILE__, __LINE__);
+       
+       med_err ret = MEDgaussEcr(
+               pMEDfile,  
+               mGeom, 
+               mRefCoo, 
+               MED_FULL_INTERLACE, 
+               mNumGauss, 
+               mGaussCoo,
+               mWeight,
+               mName); 
+               
+       if (ret != 0) throw IOException("i/o error while writing Gauss localization", __FILE__, __LINE__);
+}
+
+
+ostream& operator<<(ostream& pOs, GaussLoc& pG)
+{
+       pOs << "Gauss ref:" << endl;
+       pOs << "    Name     =|" << pG.mName << "|" << endl;
+       pOs << "    Geom     =" << pG.mGeom << endl;
+       pOs << "    #Pt Gauss=" << pG.mNumGauss << endl;
+       
+       pOs << "    Ref nodes coords.: (#nodes=" << pG.mNumNodes << " dim=" << pG.mDim << ")" << endl;
+       for (int itNode = 0 ; itNode < pG.mNumNodes ; itNode++)
+       {
+               pOs << "        Node " << (itNode + 1) << ": ";
+               for (int itDim = 0; itDim < pG.mDim ; itDim++)
+               {
+                       pOs << pG.mRefCoo[itNode * pG.mDim + itDim] << " ";
+               }
+               pOs << endl;
+       }
+       
+       pOs << "    Gauss coords. and weight:" << endl;
+       for (int itGauss = 0 ; itGauss < pG.mNumGauss ; itGauss++)
+       {
+               pOs << "        Pt " << (itGauss+1) << ": ";
+               for (int itDim = 0; itDim < pG.mDim ; itDim++)
+               {
+                       pOs << pG.mGaussCoo[itGauss * pG.mDim + itDim] << " ";
+               }
+               pOs << "weight=" << pG.mWeight[itGauss];
+               pOs << endl;
+       }
+
+       /*
+       // debug
+       med_float res[15];
+       pG.getCoordGaussPoints(pG.mRefCoo, res);
+       printArray2D(res, pG.mNumGauss, pG.mDim, "Gauss pt");
+       */
+       
+       return pOs;
+}
+
+
+} // namespace multipr
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_GaussLoc.hxx b/src/MULTIPR/MULTIPR_GaussLoc.hxx
new file mode 100644 (file)
index 0000000..d55deb7
--- /dev/null
@@ -0,0 +1,150 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_GaussLoc.hxx
+ *
+ * \brief   Class GaussLoc. Allow to locate all the Gauss points in an element of reference (e.g. a TETRA10).
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#ifndef MULTIPR_GAUSSLOC_HXX
+#define MULTIPR_GAUSSLOC_HXX
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+extern "C"
+{
+       #include "med.h"
+}
+
+#include <iostream>
+
+
+namespace multipr
+{
+
+
+//*****************************************************************************
+// Class GaussLoc
+//*****************************************************************************
+
+class GaussLoc
+{
+public:
+
+       /** 
+        * Builds an empty Gauss reference (default constructor).
+        */
+       GaussLoc();
+       
+       /**
+        * Copy constructor (deep copy).
+        * \param  pGaussLoc the GaussLoc to copy.
+        */
+       GaussLoc(const GaussLoc& pGaussLoc);
+       
+       /**
+        * Destructor. Removes everything.
+        */
+       ~GaussLoc();
+       
+       /**
+        * Resets this object in its state by default (empty). Cleans memory.
+        */
+       void reset();
+       
+       //---------------------------------------------------------------------
+       // Basic accessors/mutators
+       //--------------------------------------------------------------------
+       
+       /**
+        * Returns the name of this GaussLoc.
+        * \return the name of this GaussLoc.
+        */
+       std::string getName() const { return mName; }
+       
+       /**
+        * Returns dimension of Gauss points which is also the dimension of reference nodes.
+        * \return dimension of Gauss points.
+        */
+       int getDim() const { return mDim; }
+        
+       /**
+        * Returns number of Gauss points.
+        * \return number of Gauss points.
+        */
+       int getNumGaussPoints() const { return mNumGauss; }
+         
+       //---------------------------------------------------------------------
+       // Algorithms
+       //--------------------------------------------------------------------
+       
+       /**
+        * Returns the coordinates of all the Gauss points for a given element.
+        * \param  pCooElt (in)  coordinates of nodes of an element.
+        * \param  pCoo    (out) coordinates of all the Gauss points (interlaced); memory must have been allocated.
+        */
+       void getCoordGaussPoints(const med_float* pCooElt, med_float* pCooGaussPoints) const;
+       
+       //---------------------------------------------------------------------
+       // I/O
+       //---------------------------------------------------------------------
+       
+       /**
+        * Reads a GaussLoc object from a MED file.
+        * \param  pMEDfile any valid MED file opened for reading.
+        * \param  pIndex   index of the gauss localization to be read; must be >= 1.
+        * \throw  IOException if any i/o error occurs.
+        */
+       void readMED(med_idt pMEDfile, med_int pIndex);
+       
+       /**
+        * Writes this GaussLoc object to the given MED file.
+        * \param  pMEDfile any valid MED file opened for writing.
+        * \throw  IOException if any i/o error occurs.
+        */
+       void writeMED(med_idt pMEDfile);
+
+       /**
+        * Dumps any GaussLoc to the given output stream.
+        * \param  pOs any output stream.
+        * \param  pF  any Field.
+        * \return the output stream pOs.
+        */
+       friend std::ostream& operator<<(std::ostream& pOs, GaussLoc& pG);
+
+private:
+       
+       char                  mName[MED_TAILLE_NOM + 1];  /**< Name of the Gauss info. */
+       med_geometrie_element mGeom;                      /**< Type of elements, e.g. TETRA10 (code is 310). */
+       int                   mDim;                       /**< Dimension of nodes, e.g. 3 for a TETRA10. */
+       int                   mNumNodes;                  /**< Number of nodes in the reference element, e.g. 10 for a TETRA10. */
+       med_int               mNumGauss;                  /**< Number of Gauss points. */
+       med_float*            mRefCoo;                    /**< Table of coordinates of nodes.
+                                                              Example: for a TETRA10: 10 nodes, 3 components => 30 med_float. */
+       med_float*            mGaussCoo;                  /**< Table of coordinates of Gauss points. */
+       med_float*            mWeight;                    /**< Table of weights of Gauss points. */
+       
+private:
+       
+       // do not allow copy
+       GaussLoc& operator=(const GaussLoc&);
+       
+       // do not allow operator ==
+       bool operator==(const GaussLoc&); 
+       
+}; // class GaussLoc
+
+
+} // namespace MULTIPR
+
+
+#endif // MULTIPR_GAUSSLOC_HXX
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_Globals.hxx b/src/MULTIPR/MULTIPR_Globals.hxx
new file mode 100644 (file)
index 0000000..ff51f67
--- /dev/null
@@ -0,0 +1,29 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_Globals.hxx
+ *
+ * \brief   Some useful macros.
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+  
+#ifndef MULTIPR_GLOBALS_HXX
+#define MULTIPR_GLOBALS_HXX
+
+//*****************************************************************************
+// Some useful macros
+//*****************************************************************************
+
+#define ENABLE_LOG 0
+#define MULTIPR_LOG(STR) if (ENABLE_LOG) cout << STR;
+
+
+#endif // MULTIPR_GLOBALS_HXX
+
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_Mesh.cxx b/src/MULTIPR/MULTIPR_Mesh.cxx
new file mode 100644 (file)
index 0000000..fc16c30
--- /dev/null
@@ -0,0 +1,1188 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_Mesh.cxx
+ *
+ * \brief   see MULTIPR_Mesh.hxx
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+#include "MULTIPR_Mesh.hxx"
+#include "MULTIPR_Nodes.hxx"
+#include "MULTIPR_Elements.hxx"
+#include "MULTIPR_Family.hxx"
+#include "MULTIPR_Profil.hxx"
+#include "MULTIPR_GaussLoc.hxx"
+#include "MULTIPR_Field.hxx"
+#include "MULTIPR_MeshDis.hxx"
+#include "MULTIPR_PointOfField.hxx"
+#include "MULTIPR_DecimationFilter.hxx"
+#include "MULTIPR_Utils.hxx"
+#include "MULTIPR_Exceptions.hxx"
+#include "MULTIPR_Globals.hxx"
+#include "MULTIPR_API.hxx"
+
+using namespace std;
+
+
+namespace multipr
+{
+
+
+//*****************************************************************************
+// Class Mesh implementation
+//*****************************************************************************
+
+Mesh::Mesh()
+{
+       mNodes    = NULL;
+       mElements = NULL;
+       
+       reset();
+}
+
+
+Mesh::~Mesh()
+{
+       reset();
+}
+
+
+void Mesh::reset()
+{
+       mMEDfilename[0] = '\0';
+       mMEDfile        = 0;
+       
+       mMeshName[0]    = '\0';
+       mMeshUName[0]   = '\0';
+       mMeshDesc[0]    = '\0';
+       mMeshDim        = -1;
+       mMeshType       = MED_NON_STRUCTURE;
+       
+       for (int itDim = 0 ; itDim < 3 ; itDim++) 
+       { 
+               mMeshBBoxMin[itDim] = numeric_limits<med_float>::quiet_NaN();
+               mMeshBBoxMax[itDim] = numeric_limits<med_float>::quiet_NaN();
+       }
+       
+       if (mNodes != NULL)    { delete mNodes;    mNodes = NULL; }
+       if (mElements != NULL) { delete mElements; mElements = NULL; }
+       
+       for (unsigned itFam = 0 ; itFam < mFamilies.size() ; itFam++)
+       {
+               delete mFamilies[itFam];
+       }  
+       mFamilies.clear();
+       mFamIdToFam.clear();
+       
+       for (unsigned itGroup = 0 ; itGroup < mGroups.size() ; itGroup++)
+       {
+               delete mGroups[itGroup];
+       }  
+       mGroups.clear();
+       mGroupNameToGroup.clear();
+       
+       for (unsigned itGaussLoc = 0 ; itGaussLoc < mGaussLoc.size() ; itGaussLoc++)
+       {
+               delete mGaussLoc[itGaussLoc];
+       }  
+       mGaussLoc.clear();
+       mGaussLocNameToGaussLoc.clear();
+       
+       for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
+       {
+               delete mFields[itField];
+       }  
+       mFields.clear();
+       
+       for (unsigned itProfil = 0 ; itProfil < mProfils.size() ; itProfil++)
+       {
+               delete mProfils[itProfil];
+       }  
+       mProfils.clear();
+       
+       mFlagPrintAll = false;
+}
+
+
+vector<string> Mesh::getNameFields() const
+{
+       vector<string> res;
+       
+       for (int itField = 0 ; itField < mFields.size() ; itField++)
+       {
+               Field* currentField = mFields[itField];
+               res.push_back(currentField->getName());
+       }
+       
+       return res;
+}
+
+
+int Mesh::getTimeStamps(const char* pFieldName) const
+{
+       for (int itField = 0 ; itField < mFields.size() ; itField++)
+       {
+               Field* currentField = mFields[itField];
+               if (strcmp(currentField->getName(), pFieldName) == 0)
+               {
+                       return currentField->getNumberOfTimeSteps();
+               }
+       }
+       
+       return 0;
+}
+
+
+Field* Mesh::getFieldByName(const char* pFieldName) const
+{
+       if (pFieldName == NULL) throw NullArgumentException("pFieldName should not be NULL", __FILE__, __LINE__);
+       
+       Field* retField = NULL;
+       
+       // for each field
+       for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
+       {
+               Field* currentField = mFields[itField];
+               if (strcmp(pFieldName, currentField->getName()) == 0)
+               {
+                       // field found!
+                       retField = currentField;
+                       break;
+               }
+       }
+       
+       return retField;
+}
+
+
+GaussLoc* Mesh::getGaussLocByName(const char* pGaussLocName) const
+{
+       if (pGaussLocName == NULL) throw NullArgumentException("pGaussLocName should not be NULL", __FILE__, __LINE__);
+       
+       map<string, GaussLoc*>::const_iterator itGaussLoc = mGaussLocNameToGaussLoc.find(pGaussLocName);
+       GaussLoc* retGaussLoc = NULL;
+       
+       if (itGaussLoc != mGaussLocNameToGaussLoc.end())
+       {
+               retGaussLoc = (*itGaussLoc).second;
+       }
+       
+       return retGaussLoc;
+}
+
+
+int Mesh::getNumberOfElements() const
+{
+       if (mElements == NULL) throw IllegalStateException("", __FILE__, __LINE__);
+       
+       return mElements->getNumberOfElements();
+}
+
+
+Mesh* Mesh::createFromSetOfElements(const std::set<med_int>& pSetOfElements, const char* pNewMeshName)
+{
+       if (pNewMeshName == NULL) throw NullArgumentException("pNewMeshName", __FILE__, __LINE__);
+       
+       //---------------------------------------------------------------------
+       // Create a new mesh
+       //---------------------------------------------------------------------
+       Mesh* mesh = new Mesh();
+       
+       //---------------------------------------------------------------------
+       // Build name of the new mesh
+       //--------------------------------------------------------------------- 
+       strcpy(mesh->mMeshName, pNewMeshName);
+       
+       MULTIPR_LOG("Mesh name=|" << mesh->mMeshName << "|" << endl);
+       
+       //---------------------------------------------------------------------
+       // Fill general infos
+       //---------------------------------------------------------------------
+       strcpy(mesh->mMeshUName, mMeshUName);
+       strcpy(mesh->mMeshDesc, mMeshDesc);
+       
+       mesh->mMeshDim = mMeshDim;
+       mesh->mMeshType = mMeshType;
+       
+       MULTIPR_LOG("Mesh u. name=|" << mesh->mMeshUName << "|" << endl);
+       MULTIPR_LOG("Mesh desc=|" << mesh->mMeshDesc << "|" << endl);
+       MULTIPR_LOG("Mesh dim=" << mesh->mMeshDim << endl);
+       MULTIPR_LOG("Mesh Type=" << mesh->mMeshType << endl);
+       
+       //---------------------------------------------------------------------
+       // Build nodes and elements
+       //---------------------------------------------------------------------
+       // get all elements involved
+       mesh->mElements = mElements->extractSubSet(pSetOfElements);
+       MULTIPR_LOG((*(mesh->mElements)) << endl);
+       
+       // get all nodes involved
+       const set<med_int> setOfNodes = mesh->mElements->getSetOfNodes();
+       mesh->mNodes = mNodes->extractSubSet(setOfNodes);
+       MULTIPR_LOG((*(mesh->mNodes)) << endl);
+       
+       //---------------------------------------------------------------------
+       // Remap nodes
+       //---------------------------------------------------------------------
+       mesh->mElements->remap();
+       MULTIPR_LOG((*(mesh->mElements)) << endl);
+
+       //---------------------------------------------------------------------
+       // Build families
+       //---------------------------------------------------------------------
+       MULTIPR_LOG("Build fam.:" << endl);
+       // get families of nodes
+       {
+               set<med_int> famOfNodes = mesh->mNodes->getSetOfFamilies();
+               for (set<med_int>::iterator itFam = famOfNodes.begin() ; itFam != famOfNodes.end() ; itFam++)
+               {
+                       Family* famSrc = mFamIdToFam[*itFam];
+                       cout << (*famSrc) << endl;
+                       Family* famDest = famSrc->extractGroup(NULL);
+                       mesh->mFamilies.push_back(famDest);
+               }
+       }
+       
+       // get families of elements
+       {
+               set<med_int> famOfElt = mesh->mElements->getSetOfFamilies();
+               for (set<med_int>::iterator itFam = famOfElt.begin() ; itFam != famOfElt.end() ; itFam++)
+               {
+                       Family* famSrc = mFamIdToFam[*itFam];
+                       Family* famDest = famSrc->extractGroup(NULL);
+                       mesh->mFamilies.push_back(famDest);
+               }
+       }
+       
+       MULTIPR_LOG("Finalize:");
+       
+       // fill families with elements and build groups
+       mesh->finalizeFamiliesAndGroups();
+       
+       MULTIPR_LOG("OK\n");
+       
+       //---------------------------------------------------------------------
+       // Create new fields and collect Gauss
+       //---------------------------------------------------------------------
+       // for each field
+       set<string> newSetOfGauss;
+       for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
+       {
+               Field* currentField = mFields[itField];
+               
+               Field* newField;
+               if (currentField->isFieldOnNodes())
+               {
+                       newField = currentField->extractSubSet(setOfNodes);
+               }
+               else
+               {
+                       newField = currentField->extractSubSet(pSetOfElements);
+               }
+               
+               if (!newField->isEmpty())
+               {
+                       mesh->mFields.push_back(newField);
+                       newField->getSetOfGaussLoc(newSetOfGauss);
+               }
+       }
+       MULTIPR_LOG("Collect fields: ok: #gauss=" << newSetOfGauss.size() << endl);
+
+       //---------------------------------------------------------------------
+       // Build Gauss infos
+       //---------------------------------------------------------------------
+       for (set<string>::iterator itSet = newSetOfGauss.begin() ; itSet != newSetOfGauss.end(); itSet++)
+       {
+               const string& keyName = (*itSet);
+               
+               GaussLoc* gaussLoc = getGaussLocByName(keyName.c_str());
+               if (gaussLoc != NULL)
+               {
+                       GaussLoc* copyGaussLoc = new GaussLoc(*gaussLoc);
+                       mesh->mGaussLoc.push_back(copyGaussLoc);
+                       mesh->mGaussLocNameToGaussLoc.insert(make_pair(copyGaussLoc->getName(), copyGaussLoc));
+               }
+       }
+       
+       //---------------------------------------------------------------------
+       // Compute bbox
+       //---------------------------------------------------------------------
+       mesh->mNodes->getBBox(mesh->mMeshBBoxMin, mesh->mMeshBBoxMax);
+       
+       return mesh;
+}
+
+
+Mesh* Mesh::createFromGroup(const Group* pGroup, const char* pNewMeshName)
+{
+       if (pGroup == NULL) throw NullArgumentException("pGroup should not be NULL", __FILE__, __LINE__);
+       if (pNewMeshName == NULL) throw NullArgumentException("pNewMeshName should not be NULL", __FILE__, __LINE__);
+       if (strlen(pNewMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("pNewMeshName length too long", __FILE__, __LINE__);
+       
+       //---------------------------------------------------------------------
+       // Create a new mesh
+       //---------------------------------------------------------------------
+       Mesh* mesh = new Mesh();
+       
+       //---------------------------------------------------------------------
+       // Build name of the new mesh
+       //--------------------------------------------------------------------- 
+       strcpy(mesh->mMeshName, pNewMeshName);
+       
+       MULTIPR_LOG("Mesh name=|" << mesh->mMeshName << "|" << endl);
+       
+       //---------------------------------------------------------------------
+       // Fill general infos
+       //---------------------------------------------------------------------
+       strcpy(mesh->mMeshUName, mMeshUName);
+       strcpy(mesh->mMeshDesc, mMeshDesc);
+       
+       mesh->mMeshDim = mMeshDim;
+       mesh->mMeshType = mMeshType;
+       
+       MULTIPR_LOG("Mesh u. name=|" << mesh->mMeshUName << "|" << endl);
+       MULTIPR_LOG("Mesh desc=|" << mesh->mMeshDesc << "|" << endl);
+       MULTIPR_LOG("Mesh dim=" << mesh->mMeshDim << endl);
+       MULTIPR_LOG("Mesh Type=" << mesh->mMeshType << endl);
+       
+       //---------------------------------------------------------------------
+       // Build nodes and elements
+       //---------------------------------------------------------------------
+       // get all elements involved
+       const set<med_int> setOfElt = pGroup->getSetOfElt();
+       mesh->mElements = mElements->extractSubSet(setOfElt);
+       MULTIPR_LOG((*(mesh->mElements)) << endl);
+       
+       // get all nodes involved
+       const set<med_int> setOfNodes = mesh->mElements->getSetOfNodes();
+       mesh->mNodes = mNodes->extractSubSet(setOfNodes);
+       MULTIPR_LOG((*(mesh->mNodes)) << endl);
+       
+       //---------------------------------------------------------------------
+       // Remap nodes
+       //---------------------------------------------------------------------
+       mesh->mElements->remap();
+       MULTIPR_LOG((*(mesh->mElements)) << endl);
+
+       //---------------------------------------------------------------------
+       // Build families
+       //---------------------------------------------------------------------
+       MULTIPR_LOG("Build fam.:" << endl);
+       // get families of nodes
+       {
+               set<med_int> famOfNodes = mesh->mNodes->getSetOfFamilies();
+               for (set<med_int>::iterator itFam = famOfNodes.begin() ; itFam != famOfNodes.end() ; itFam++)
+               {
+                       Family* famSrc = mFamIdToFam[*itFam];
+                       Family* famDest = famSrc->extractGroup(pGroup->getName().c_str());
+                       mesh->mFamilies.push_back(famDest);
+               }
+       }
+       
+       // get families of elements
+       {
+               set<med_int> famOfElt = mesh->mElements->getSetOfFamilies();
+               for (set<med_int>::iterator itFam = famOfElt.begin() ; itFam != famOfElt.end() ; itFam++)
+               {
+                       Family* famSrc = mFamIdToFam[*itFam];
+                       Family* famDest = famSrc->extractGroup(pGroup->getName().c_str());
+                       mesh->mFamilies.push_back(famDest);
+               }
+       }
+       
+       MULTIPR_LOG("Finalize:");
+       
+       // fill families with elements and build groups
+       mesh->finalizeFamiliesAndGroups();
+       
+       MULTIPR_LOG("OK\n");
+       
+       //---------------------------------------------------------------------
+       // Create new fields and collect Gauss
+       //---------------------------------------------------------------------
+       // for each field
+       set<string> newSetOfGauss;
+       for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
+       {
+               Field* currentField = mFields[itField];
+               
+               Field* newField;
+               if (currentField->isFieldOnNodes())
+               {
+                       newField = currentField->extractSubSet(setOfNodes);
+               }
+               else
+               {
+                       newField = currentField->extractSubSet(setOfElt);
+               }
+               
+               if (!newField->isEmpty())
+               {
+                       mesh->mFields.push_back(newField);
+                       newField->getSetOfGaussLoc(newSetOfGauss);
+               }
+       }
+       MULTIPR_LOG("Collect fields: ok: #gauss=" << newSetOfGauss.size() << endl);
+
+       //---------------------------------------------------------------------
+       // Build Gauss infos
+       //---------------------------------------------------------------------
+       for (set<string>::iterator itSet = newSetOfGauss.begin() ; itSet != newSetOfGauss.end(); itSet++)
+       {
+               const string& keyName = (*itSet);
+               
+               GaussLoc* gaussLoc = getGaussLocByName(keyName.c_str());
+               if (gaussLoc != NULL)
+               {
+                       GaussLoc* copyGaussLoc = new GaussLoc(*gaussLoc);
+                       mesh->mGaussLoc.push_back(copyGaussLoc);
+                       mesh->mGaussLocNameToGaussLoc.insert(make_pair(copyGaussLoc->getName(), copyGaussLoc));
+               }
+       }
+       
+       //---------------------------------------------------------------------
+       // Compute bbox
+       //---------------------------------------------------------------------
+       mesh->mNodes->getBBox(mesh->mMeshBBoxMin, mesh->mMeshBBoxMax);
+       
+       return mesh;
+}
+
+
+MeshDis* Mesh::splitGroupsOfElements()
+{
+       MeshDis* meshDis = new MeshDis();
+       
+       // get prefix from the original MED filename
+       string strPrefix = removeExtension(mMEDfilename, ".med");
+       
+       int numGroup = 1;
+       
+       // for each group
+       for (unsigned itGroup = 0 ; itGroup < mGroups.size() ; itGroup++)
+       {
+               Group* currentGroup = mGroups[itGroup];
+               
+               // skip this group if it is a group of nodes
+               if (currentGroup->isGroupOfNodes()) 
+               {
+                       continue;
+               }
+               
+               char strPartName[256];
+               sprintf(strPartName, "%s_%d", mMeshName, numGroup);
+               
+               char strMEDfilename[256];
+               sprintf(strMEDfilename, "%s_grain%d.med", strPrefix.c_str(), numGroup);
+               
+               Mesh* mesh = createFromGroup(currentGroup, mMeshName);
+               
+               // skip the group which contain all the others groups, even it contains only 1 group
+               if ((mesh->mElements->getNumberOfElements() == mElements->getNumberOfElements()) && (mGroups.size() > 1))
+               {
+                       delete mesh;
+                       continue;
+               }
+               
+               meshDis->addMesh(
+                       MeshDisPart::MULTIPR_WRITE_MESH,
+                       mMeshName,
+                       numGroup,
+                       strPartName,
+                       "localhost",
+                       strMEDfilename,
+                       mesh);
+               
+               numGroup++;
+       }
+       
+       return meshDis;
+}
+
+
+Mesh* Mesh::decimate(
+       const char* pFilterName,
+       const char* pArgv,
+       const char* pNameNewMesh)
+{
+       //---------------------------------------------------------------------
+       // Check parameters
+       //--------------------------------------------------------------------- 
+       if (pFilterName == NULL) throw NullArgumentException("pFilterName should not be NULL", __FILE__, __LINE__);
+       if (pArgv == NULL) throw NullArgumentException("pArgv should not be NULL", __FILE__, __LINE__);
+       if (pNameNewMesh == NULL) throw NullArgumentException("pNameNewMesh should not be NULL", __FILE__, __LINE__);
+       
+       //---------------------------------------------------------------------
+       // Instanciate filter used for decimation
+       //---------------------------------------------------------------------
+       DecimationFilter* filter = DecimationFilter::create(pFilterName);
+       
+       //---------------------------------------------------------------------
+       // Create new mesh by decimating current one
+       //---------------------------------------------------------------------
+       Mesh* decimatedMesh = filter->apply(this, pArgv, pNameNewMesh);
+       
+       //---------------------------------------------------------------------
+       // Cleans
+       //---------------------------------------------------------------------
+       delete filter;
+       
+       return decimatedMesh;
+}
+
+
+
+void Mesh::getAllPointsOfField(Field* pField, int pTimeStepIt, std::vector<PointOfField>& pPoints)
+{
+       //---------------------------------------------------------------------
+       // Check arguments
+       //---------------------------------------------------------------------
+       
+       if (pField == NULL) throw NullArgumentException("field should not be NULL", __FILE__, __LINE__);
+       if (pTimeStepIt < 1) throw IllegalArgumentException("invalid field iteration; should be >= 1", __FILE__, __LINE__);
+       
+       if (mMeshDim != 3) throw UnsupportedOperationException("not yet implemented", __FILE__, __LINE__);
+       if (pField->getType() != MED_FLOAT64) throw UnsupportedOperationException("not yet implemented", __FILE__, __LINE__);
+       if (pField->getNumberOfComponents() != 1) throw UnsupportedOperationException("field have more than 1 component (vectorial field, expected scalar field)", __FILE__, __LINE__);
+       
+       //---------------------------------------------------------------------
+       // Collect points
+       //---------------------------------------------------------------------
+       
+       if (pField->isFieldOnNodes())
+       {
+               //-------------------------------------------------------------
+               // Case 1: field of nodes
+               //-------------------------------------------------------------
+               if (mNodes == NULL) throw IllegalStateException("no nodes in the current mesh", __FILE__, __LINE__);
+               
+               // for each node
+               for (int itNode = 0, size = mNodes->getNumberOfNodes() ; itNode < size ; itNode++)
+               {
+                       // collect coordinates and value of the point
+                       const med_float* coo = mNodes->getCoordinates(itNode);
+                       
+                       const med_float* val = 
+                               reinterpret_cast<const med_float*>(pField->getValue(pTimeStepIt, itNode + 1));
+
+                       // add new point
+                       pPoints.push_back(PointOfField(coo[0], coo[1], coo[2], val[0]));
+               }
+       }
+       else
+       {
+               //-------------------------------------------------------------
+               // Case 2: field of elements
+               //-------------------------------------------------------------
+       
+               if (mElements == NULL) throw IllegalStateException("no elements in the current mesh", __FILE__, __LINE__);
+               if (mElements->getTypeOfPrimitives() != MED_TETRA10) throw UnsupportedOperationException("only support TETRA10 mesh", __FILE__, __LINE__);
+               
+               const string& nameGaussLoc = pField->getNameGaussLoc(pTimeStepIt);
+               GaussLoc* gaussLoc = getGaussLocByName(nameGaussLoc.c_str());
+               if (gaussLoc == NULL) throw IllegalStateException("no Gauss localization for these elements", __FILE__, __LINE__);
+               
+               int numGauss = pField->getNumberOfGaussPointsByElement(pTimeStepIt);
+               
+               int size = gaussLoc->getDim() * gaussLoc->getNumGaussPoints();
+               med_float* cooGaussPts = new med_float[size];
+               
+               int dim = mElements->getTypeOfPrimitives() / 100;
+               int numNodes = mElements->getTypeOfPrimitives() % 100;
+               size = dim * numNodes;
+               med_float* cooNodes = new med_float[size];
+               
+               // for each elements
+               for (int itElt = 0, size = mElements->getNumberOfElements() ; itElt < size ; itElt++)
+               {
+                       // get coordinates of nodes of the current elements
+                       // OPTIMIZATION: ASSUME TETRA10: ONLY GETS THE 4 FIRST NODES OF EACH ELEMENT
+                       mElements->getCoordinates(itElt, mNodes, cooNodes, 4);
+                       
+                       // compute coordinates of gauss points
+                       gaussLoc->getCoordGaussPoints(cooNodes, cooGaussPts);
+                       
+                       //printArray2D(cooGaussPts, 5, 3, "Gauss pt");
+                       
+                       const med_float* val = 
+                               reinterpret_cast<const med_float*>(pField->getValue(pTimeStepIt, itElt + 1));
+               
+                       // for each point of Gauss of the element
+                       med_float* srcCoo = cooGaussPts;
+                       for (int itPtGauss = 0 ; itPtGauss < numGauss ; itPtGauss++)
+                       {
+                               pPoints.push_back(PointOfField(srcCoo[0], srcCoo[1], srcCoo[2], val[itPtGauss]));
+                               srcCoo += 3;
+                       }
+               }
+               
+               delete[] cooNodes;
+               delete[] cooGaussPts;
+       }
+}
+
+
+float Mesh::evalDefaultRadius(int pN) const
+{
+       if (mFields.size() == 0) return 1.0f;
+       
+       //---------------------------------------------------------------------
+       // Compute default radius
+       //--------------------------------------------------------------------- 
+       
+       med_float volumeBBox = 
+               (mMeshBBoxMax[0] - mMeshBBoxMin[0]) * 
+               (mMeshBBoxMax[1] - mMeshBBoxMin[1]) *
+               (mMeshBBoxMax[2] - mMeshBBoxMin[2]);
+               
+       if (isnan(volumeBBox))
+       {
+               return 1.0f;
+       }
+       
+       const med_float k = 0.8; // considered 80% of the volume
+       
+       // get nunmber of gauss points in the field
+       try
+       {
+               Field* anyField = mFields[mFields.size()-1];
+               int numTimeSteps = anyField->getNumberOfTimeSteps();
+               
+               int numGaussPoints = getNumberOfElements() * anyField->getNumberOfGaussPointsByElement(numTimeSteps-1);
+       
+               med_float radius = med_float(pow( (3.0/4.0) * pN * k * volumeBBox / (3.1415 * numGaussPoints), 1.0/3.0));
+       
+               return float(radius);
+       }
+       catch (...)
+       {
+               return 1.0f;
+       }
+}
+
+
+med_geometrie_element CELL_TYPES[MED_NBR_GEOMETRIE_MAILLE] = 
+{
+       MED_POINT1,
+       MED_SEG2, 
+       MED_SEG3,
+       MED_TRIA3,
+       MED_TRIA6,
+       MED_QUAD4,
+       MED_QUAD8,
+       MED_TETRA4,
+       MED_TETRA10,
+       MED_HEXA8,
+       MED_HEXA20,
+       MED_PENTA6,
+       MED_PENTA15
+};
+
+   
+char CELL_NAMES[MED_NBR_GEOMETRIE_MAILLE][MED_TAILLE_NOM + 1] =  
+{
+       "MED_POINT1",
+       "MED_SEG2", 
+       "MED_SEG3",
+       "MED_TRIA3",
+       "MED_TRIA6",
+       "MED_QUAD4",
+       "MED_QUAD8",
+       "MED_TETRA4",
+       "MED_TETRA10",
+       "MED_HEXA8",
+       "MED_HEXA20",
+       "MED_PENTA6",
+       "MED_PENTA15",
+       "MED_PYRA5",
+       "MED_PYRA13"
+};
+
+
+void Mesh::readSequentialMED(const char* pMEDfilename, const char* pMeshName)
+{
+       reset();
+       
+       //---------------------------------------------------------------------
+       // Check arguments
+       //---------------------------------------------------------------------
+       MULTIPR_LOG("Check arguments: ");
+       if (pMEDfilename == NULL) throw NullArgumentException("pMEDfilename should not be NULL", __FILE__, __LINE__);
+       if (pMeshName == NULL) throw NullArgumentException("pMeshName should not be NULL", __FILE__, __LINE__);
+       MULTIPR_LOG("OK\n");
+       
+       strncpy(mMEDfilename, pMEDfilename, 256);
+       strncpy(mMeshName, pMeshName, MED_TAILLE_NOM);
+       
+       //---------------------------------------------------------------------
+       // Open MED file (READ_ONLY)
+       //---------------------------------------------------------------------
+       MULTIPR_LOG("Open MED file: ");
+       mMEDfile = MEDouvrir(mMEDfilename, MED_LECTURE); // open MED file for reading
+       if (mMEDfile <= 0) throw FileNotFoundException("MED file not found", __FILE__, __LINE__);
+       MULTIPR_LOG("OK\n");
+       
+       //---------------------------------------------------------------------
+       // Check valid HDF format
+       //---------------------------------------------------------------------
+       MULTIPR_LOG("Format HDF: ");
+       if (MEDformatConforme(mMEDfilename) != 0) throw IOException("invalid file", __FILE__, __LINE__);
+       MULTIPR_LOG("OK\n");
+       
+       //---------------------------------------------------------------------
+       // Get MED version
+       //---------------------------------------------------------------------
+       MULTIPR_LOG("MED version: ");
+       med_int verMajor, verMinor, verRelease;
+       med_err ret = MEDversionLire(mMEDfile, &verMajor, &verMinor, &verRelease);
+       if (ret != 0) throw IOException("error while reading MED version", __FILE__, __LINE__);
+       MULTIPR_LOG(verMajor << "." << verMinor << "." << verRelease << ": OK\n");
+       
+       //---------------------------------------------------------------------
+       // Check that there is no profil
+       //---------------------------------------------------------------------
+       MULTIPR_LOG("#profils must be 0: ");
+       med_int nbProfils = MEDnProfil(mMEDfile);
+       if (nbProfils != 0) throw UnsupportedOperationException("not yet implemented", __FILE__, __LINE__);
+       MULTIPR_LOG("OK\n");
+       
+       //---------------------------------------------------------------------
+       // Read all Gauss localizations
+       //---------------------------------------------------------------------
+       readGaussLoc();
+       
+       //---------------------------------------------------------------------
+       // Read scalars (should be 0)
+       //---------------------------------------------------------------------
+       MULTIPR_LOG("Scalars: ");
+       med_int nbScalars = MEDnScalaire(mMEDfile);
+       if (nbScalars != 0) throw UnsupportedOperationException("not yet implemented", __FILE__, __LINE__);
+       MULTIPR_LOG(nbScalars << ": OK\n");     
+       
+       //---------------------------------------------------------------------
+       // Find the mesh
+       //---------------------------------------------------------------------
+       // read number of meshes
+       MULTIPR_LOG("Num meshes: ");
+       med_int nbMeshes = MEDnMaa(mMEDfile);
+       if (nbMeshes <= 0) throw IOException("i/o error while reading number of meshes in MED file", __FILE__, __LINE__);
+       MULTIPR_LOG(nbMeshes << ": OK\n");
+       
+       med_int meshIndex = -1;
+       // iteration over mesh to find the mesh we want
+       // for each mesh in the file (warning: first mesh is number 1)
+       for (int itMesh = 1 ; itMesh <= nbMeshes ; itMesh++)
+       {
+               char meshName[MED_TAILLE_NOM + 1];
+               
+               ret = MEDmaaInfo(
+                       mMEDfile, 
+                       itMesh, 
+                       meshName, 
+                       &mMeshDim, 
+                       &mMeshType, 
+                       mMeshDesc);
+                       
+               if (ret != 0) throw IOException("i/o error while reading mesh information in MED file", __FILE__, __LINE__);
+               MULTIPR_LOG("Mesh: |" << meshName << "|");
+               
+               // test if the current mesh is the mesh we want
+               if (strcmp(pMeshName, meshName) == 0)
+               {
+                       // *** mesh found ***
+                       MULTIPR_LOG(" OK (found)\n");
+                       meshIndex = itMesh;
+                       break;
+               }
+               else
+               {
+                       // not the mesh we want: skip this mesh
+                       MULTIPR_LOG(" skipped\n");
+               }
+       }
+       
+       if (meshIndex == -1)
+       {
+               throw IllegalStateException("mesh not found in the given MED file", __FILE__, __LINE__);
+       }
+       
+       //---------------------------------------------------------------------
+       // Check mesh validity
+       //---------------------------------------------------------------------
+       // dimension of the mesh must be 3 (= 3D mesh)
+       MULTIPR_LOG("Mesh is 3D: ");
+       if (mMeshDim != 3) throw UnsupportedOperationException("dimension of the mesh should be 3; other dimension not yet implemented", __FILE__, __LINE__);
+       MULTIPR_LOG("OK\n");
+       
+       // mesh must not be a grid
+       MULTIPR_LOG("Mesh is not a grid: ");
+       if (mMeshType != MED_NON_STRUCTURE) 
+               throw UnsupportedOperationException("grid not supported", __FILE__, __LINE__);
+       MULTIPR_LOG("OK\n");
+       
+       // mesh must only contain TETRA10 elements
+       MULTIPR_LOG("Only TETRA10: ");
+       med_connectivite connectivite = MED_NOD; // NODAL CONNECTIVITY ONLY
+       bool onlyTETRA10 = true;
+       int numTetra10 = -1;
+       for (int itCell = 0 ; itCell < MED_NBR_GEOMETRIE_MAILLE ; itCell++)
+       {
+               med_int meshNumCells = MEDnEntMaa(
+                       mMEDfile, 
+                       mMeshName, 
+                       MED_CONN, 
+                       MED_MAILLE, 
+                       CELL_TYPES[itCell], 
+                       connectivite);
+               
+               if ((meshNumCells > 0) && (strcmp(CELL_NAMES[itCell], "MED_TETRA10") != 0))
+               {
+                       onlyTETRA10 = false;
+                       break;
+               }
+               if (strcmp(CELL_NAMES[itCell], "MED_TETRA10") == 0)
+               {
+                       numTetra10 = meshNumCells;
+               }
+       }
+       
+       if (!onlyTETRA10) throw UnsupportedOperationException("mesh should only contain TETRA10 elements", __FILE__, __LINE__);
+       MULTIPR_LOG(numTetra10 << ": OK\n");
+       
+       // everything is OK...
+       
+       //---------------------------------------------------------------------
+       // Check num joint = 0
+       //---------------------------------------------------------------------
+       MULTIPR_LOG("Num joints: ");
+       med_int numJoints = MEDnJoint(mMEDfile, mMeshName);
+       MULTIPR_LOG(numJoints << ": OK\n");
+       
+       //---------------------------------------------------------------------
+       // Check num equivalence = 0
+       //---------------------------------------------------------------------
+       MULTIPR_LOG("Num equivalences: ");
+       med_int numEquiv = MEDnEquiv(mMEDfile, mMeshName);
+       MULTIPR_LOG(numEquiv << ": OK\n");
+       
+       //---------------------------------------------------------------------
+       // Read nodes
+       //---------------------------------------------------------------------
+       mNodes = new Nodes();
+       mNodes->readMED(mMEDfile, mMeshName, mMeshDim);
+       mNodes->getBBox(mMeshBBoxMin, mMeshBBoxMax);
+       
+       //---------------------------------------------------------------------
+       // Read elements
+       //---------------------------------------------------------------------
+       mElements = new Elements();
+       mElements->readMED(mMEDfile, mMeshName, mMeshDim, MED_MAILLE, MED_TETRA10);
+       
+       //---------------------------------------------------------------------
+       // Read families
+       //---------------------------------------------------------------------
+       readFamilies();
+       finalizeFamiliesAndGroups();
+       
+       //---------------------------------------------------------------------
+       // Read fields
+       //---------------------------------------------------------------------
+       readFields();
+       
+       //---------------------------------------------------------------------
+       // Close the MED file
+       //---------------------------------------------------------------------
+       MULTIPR_LOG("Close MED file: ");
+       ret = MEDfermer(mMEDfile);
+       if (ret != 0) throw IOException("i/o error while closing MED file", __FILE__, __LINE__);
+       MULTIPR_LOG("OK\n");
+}
+
+
+void Mesh::writeMED(const char* pMEDfilename)
+{
+       MULTIPR_LOG("Write MED: " << pMEDfilename << endl);
+
+       if (pMEDfilename == NULL) throw NullArgumentException("pMEDfilename should not be NULL", __FILE__, __LINE__);
+       if (strlen(pMEDfilename) == 0) throw IllegalArgumentException("pMEDfilename size is 0", __FILE__, __LINE__);
+       
+       remove(pMEDfilename);
+       
+       //---------------------------------------------------------------------
+       // Create the new MED file (WRITE_ONLY)
+       //---------------------------------------------------------------------
+       med_idt newMEDfile = MEDouvrir(const_cast<char*>(pMEDfilename), MED_CREATION);
+       if (newMEDfile == -1) throw IOException("", __FILE__, __LINE__);
+       
+       //---------------------------------------------------------------------
+       // Write scalars
+       //---------------------------------------------------------------------
+       // no scalars to write
+       
+       //---------------------------------------------------------------------
+       // Create mesh: must be created first
+       //---------------------------------------------------------------------
+       med_err ret = MEDmaaCr(
+               newMEDfile,
+               mMeshName,
+               mMeshDim,
+               MED_NON_STRUCTURE,
+               mMeshDesc);
+       
+       if (ret != 0) throw IOException("", __FILE__, __LINE__);
+       MULTIPR_LOG("    Create mesh: |" << mMeshName << "|: OK" << endl);
+       
+       //---------------------------------------------------------------------
+       // Write nodes and elements (mesh must exist)
+       //---------------------------------------------------------------------
+       mNodes->writeMED(newMEDfile, mMeshName);
+       MULTIPR_LOG("    Write nodes: ok" << endl);
+       mElements->writeMED(newMEDfile, mMeshName, mMeshDim);
+       MULTIPR_LOG("    write elt: ok" << endl);
+       
+       //---------------------------------------------------------------------
+       // Write families (mesh must exist)
+       //---------------------------------------------------------------------
+       for (unsigned itFam = 0 ; itFam < mFamilies.size() ; itFam++)
+       {
+               Family* fam = mFamilies[itFam];
+               fam->writeMED(newMEDfile, mMeshName);
+       }
+       MULTIPR_LOG("    Write families: ok" << endl);
+       
+       //---------------------------------------------------------------------
+       // Write profil
+       //---------------------------------------------------------------------
+       // no profil
+       
+       //---------------------------------------------------------------------
+       // Write Gauss localization (must be written before fields)
+       //---------------------------------------------------------------------
+       for (unsigned itGaussLoc = 0 ; itGaussLoc < mGaussLoc.size() ; itGaussLoc++)
+       {
+               
+               GaussLoc* gaussLoc = mGaussLoc[itGaussLoc];
+               gaussLoc->writeMED(newMEDfile);
+       }
+       MULTIPR_LOG("    Write Gauss: ok" << endl);
+       
+       //---------------------------------------------------------------------
+       // Write fields
+       //---------------------------------------------------------------------
+       for (unsigned itField = 0 ; itField < mFields.size() ; itField++)
+       {
+               Field* field = mFields[itField];
+               field->writeMED(newMEDfile, mMeshName);
+       }
+       MULTIPR_LOG("    Write fields: ok" << endl);
+       
+       //---------------------------------------------------------------------
+       // Close the new MED file
+       //---------------------------------------------------------------------
+       ret = MEDfermer(newMEDfile);
+       if (ret != 0) throw IOException("", __FILE__, __LINE__);
+}
+
+
+void Mesh::readGaussLoc()
+{
+       MULTIPR_LOG("Gauss ref: ");
+       med_int numGauss = MEDnGauss(mMEDfile);
+       if (numGauss < 0) throw IOException("", __FILE__, __LINE__);
+       MULTIPR_LOG(numGauss << ": OK\n");
+       
+       for (int itGauss = 1 ; itGauss <= numGauss ; itGauss++)
+       {
+               GaussLoc* gaussLoc = new GaussLoc();
+               gaussLoc->readMED(mMEDfile, itGauss);
+               
+               MULTIPR_LOG((*gaussLoc) << endl);
+               
+               mGaussLoc.push_back(gaussLoc);
+               mGaussLocNameToGaussLoc.insert(make_pair(gaussLoc->getName(), gaussLoc));
+       }
+}
+
+
+void Mesh::readFamilies()
+{
+       med_int numFamilies = MEDnFam(mMEDfile, mMeshName);
+       if (numFamilies <= 0) throw IOException("", __FILE__, __LINE__);
+       
+       for (int itFam = 1 ; itFam <= numFamilies ; itFam++)
+       {
+               Family* fam = new Family();
+               fam->readMED(mMEDfile, mMeshName, itFam);
+               mFamilies.push_back(fam);
+       }
+}
+
+
+void Mesh::finalizeFamiliesAndGroups()
+{
+       //---------------------------------------------------------------------
+       // Build mapping between family id and pointers towards families
+       //---------------------------------------------------------------------
+       for (unsigned itFam = 0 ; itFam < mFamilies.size() ; itFam++)
+       {
+               Family* fam  = mFamilies[itFam];
+               mFamIdToFam.insert(make_pair(fam->getId(), fam));
+       }
+       
+       //---------------------------------------------------------------------
+       // Fill families of nodes
+       //---------------------------------------------------------------------
+       for (int itNode = 1 ; itNode <= mNodes->getNumberOfNodes() ; itNode++)
+       {
+               // get family of the ith nodes
+               int famIdent = mNodes->getFamIdent(itNode - 1); // MED nodes start at 1
+               map<med_int, Family*>::iterator itFam = mFamIdToFam.find(famIdent);
+               
+               if (itFam == mFamIdToFam.end()) throw IllegalStateException("", __FILE__, __LINE__);
+               
+               Family* fam = (*itFam).second;
+               
+               // insert the current node to its family
+               fam->insertElt(itNode);
+               fam->setIsFamilyOfNodes(true);
+       }
+       
+       //---------------------------------------------------------------------
+       // Fill families of elements
+       //---------------------------------------------------------------------
+       for (int itElt = 1 ; itElt <= mElements->getNumberOfElements() ; itElt++)
+       {
+               // get family of the ith element (MED index start at 1)
+               int famIdent = mElements->getFamilyIdentifier(itElt - 1);
+               map<med_int, Family*>::iterator itFam = mFamIdToFam.find(famIdent);
+               
+               if (itFam == mFamIdToFam.end()) throw IllegalStateException("", __FILE__, __LINE__);
+               
+               Family* fam = (*itFam).second;
+               
+               // insert the current node its family
+               fam->insertElt(itElt);
+               fam->setIsFamilyOfNodes(false);
+       }
+       
+       //---------------------------------------------------------------------
+       // Build groups
+       //---------------------------------------------------------------------
+       // for each family
+       for (unsigned itFam = 0 ; itFam < mFamilies.size() ; itFam++)
+       {
+               mFamilies[itFam]->buildGroups(mGroups, mGroupNameToGroup);
+       }
+}
+
+
+void Mesh::readFields()
+{
+       //---------------------------------------------------------------------
+       // Read number of fields
+       //---------------------------------------------------------------------
+       MULTIPR_LOG("Read fields: ");
+       med_int numFields = MEDnChamp(mMEDfile, 0);
+       if (numFields <= 0) throw IOException("", __FILE__, __LINE__);
+       MULTIPR_LOG(numFields << ": OK\n");
+
+       //---------------------------------------------------------------------
+       // Iterate over fields
+       //---------------------------------------------------------------------
+       // for each field, read number of components and others infos
+       for (int itField = 1 ; itField <= numFields ; itField++)
+       {
+               Field* field = new Field();
+               field->readMED(mMEDfile, itField, mMeshName);
+               
+               // if the nth field does not apply on our mesh => slip it
+               if (field->isEmpty())
+               {
+                       delete field;
+               }
+               else
+               {
+                       mFields.push_back(field);
+               }
+       }
+}
+
+
+ostream& operator<<(ostream& pOs, Mesh& pM)
+{
+       pOs << "Mesh: " << endl;
+       pOs << "    MED file =|" << pM.mMEDfilename << "|" << endl;
+       pOs << "    Name     =|" << pM.mMeshName << "|" << endl;
+       pOs << "    Unv name =|" << pM.mMeshUName << "|" << endl;
+       pOs << "    Desc     =|" << pM.mMeshDesc << "|" << endl;
+       pOs << "    Dim      =" << pM.mMeshDim << endl;
+       pOs << "    Type     =" << ((pM.mMeshType == MED_STRUCTURE)?"STRUCTURE":"NON_STRUCTURE") << endl;
+       pOs << "    BBox     =[" << pM.mMeshBBoxMin[0] << " ; " << pM.mMeshBBoxMax[0] << "] x [" << pM.mMeshBBoxMin[1] << " ; " << pM.mMeshBBoxMax[1] << "] x [" << pM.mMeshBBoxMin[2] << " ; " << pM.mMeshBBoxMax[2] << "]" << endl;   
+       
+       if (pM.mFlagPrintAll)
+       {
+               cout << (*(pM.mNodes)) << endl;
+               cout << (*(pM.mElements)) << endl;
+               
+               pOs << "    Families : #=" << pM.mFamilies.size() << endl;
+               for (unsigned i = 0 ; i < pM.mFamilies.size() ; i++)
+               {
+                       cout << (*(pM.mFamilies[i])) << endl;
+               }
+               
+               pOs << "    Groups   : #=" << pM.mGroups.size() << endl;
+               for (unsigned i = 0 ; i < pM.mGroups.size() ; i++)
+               {
+                       cout << (*(pM.mGroups[i])) << endl;
+               }
+               
+               pOs << "    Gauss loc: #=" << pM.mGaussLoc.size() << endl;
+               for (unsigned i = 0 ; i < pM.mGaussLoc.size() ; i++)
+               {
+                       cout << (*(pM.mGaussLoc[i])) << endl;
+               }
+               
+               pOs << "    Fields   : #=" << pM.mFields.size() << endl;
+               for (unsigned i = 0 ; i < pM.mFields.size() ; i++)
+               {
+                       cout << (*(pM.mFields[i])) << endl;
+               }
+       }
+       else
+       {
+               pOs << "    Nodes    : #=" << pM.mNodes->getNumberOfNodes() << endl;
+               
+               const set<med_int>& setOfNodes = pM.mElements->getSetOfNodes();
+               if (setOfNodes.size() == 0)
+               {
+                       pOs << "    Elt      : #=" << pM.mElements->getNumberOfElements() << endl;
+               }
+               else
+               {
+                       set<med_int>::iterator itNode = setOfNodes.end();
+                       itNode--;
+                       pOs << "    Elt      : #=" << pM.mElements->getNumberOfElements() << " node_id_min=" << (*(setOfNodes.begin())) << " node_id_max=" << (*itNode) << endl;
+               }
+               
+               pOs << "    Families : #=" << pM.mFamilies.size() << endl;
+               pOs << "    Groups   : #=" << pM.mGroups.size() << endl;
+               pOs << "    Gauss loc: #=" << pM.mGaussLoc.size() << endl;
+               pOs << "    Fields   : #=" << pM.mFields.size() << endl;
+       }
+       
+       return pOs;
+}
+
+
+} // namespace  multipr
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_Mesh.hxx b/src/MULTIPR/MULTIPR_Mesh.hxx
new file mode 100644 (file)
index 0000000..d72bd8b
--- /dev/null
@@ -0,0 +1,378 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_Mesh.hxx
+ *
+ * \brief   Class Mesh used by the MULTIPR API; used to wrap MED file meshes.
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#ifndef MULTIPR_MESH_HXX
+#define MULTIPR_MESH_HXX
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+extern "C"
+{
+       #include "med.h"
+}
+
+#include <iostream>
+#include <fstream>
+#include <set>
+#include <map>
+#include <vector>
+#include <string>
+
+
+namespace multipr
+{
+
+//*****************************************************************************
+// Pre-declaration
+//*****************************************************************************
+
+class GaussLoc;
+class Profil;
+class Nodes;
+class Elements;
+class Family;
+class Field;
+class Group;
+class MeshDis;
+class PointOfField;
+
+
+//*****************************************************************************
+// Class Mesh
+//*****************************************************************************
+
+/**
+ * Assumes:
+ * - 3D mesh in a 3D space
+ * - Unstructured mesh (not a grid)
+ * - Nodal connectivity
+ * - Cartesian coordinates system
+ * Always use FULL_INTERLACE arrays
+ */
+class Mesh
+{
+public:
+
+       /**
+        * Builds an empty Mesh (default constructor).
+        */
+       Mesh();
+        
+       /**
+        * Destructor. Removes everything.
+        */
+       ~Mesh();
+        
+       /**
+        * Resets this object in its state by default (empty). Cleans memory.
+        */
+       void reset();
+       
+       //---------------------------------------------------------------------
+       // Basic accessors/mutators
+       //---------------------------------------------------------------------
+       
+       /**
+        * Returns the name of this Mesh.
+        * \return the name of this Mesh.
+        */
+       const char* getName() const { return mMeshName; }
+       
+       /**
+        * Returns the name of all the fields.
+        * \return the name of all the fields.
+        */
+       std::vector<std::string> getNameFields() const; 
+       
+       /**
+        * Returns the number of iteration for a given field.
+        * \return the number of iteration for a given field.
+        */
+       int getTimeStamps(const char* pFieldName) const; 
+       
+       /**
+        * Returns a Field from its name; NULL if it does not exist.
+        * \param  pFieldName name of the field to be retrieved.
+        * \return the Field pFieldName of it exists, NULL otherwise.
+        * \throw  NullArgumentException if pFieldName is NULL.
+        */
+       Field* getFieldByName(const char* pFieldName) const;
+       
+       /**
+        * Returns a GaussLoc from its name; NULL if it does not exist.
+        * \param  pGaussLocName name of the GaussLoc to be retrieved.
+        * \return the GaussLoc pGaussLocName if it exists, NULL otherwise.
+        * \throw  NullArgumentException if pGaussLocName is NULL.
+        */
+       GaussLoc* getGaussLocByName(const char* pGaussLocName) const;   
+        
+       /**
+        * Returns true iff the given 3D-point is in the bounding box of this Mesh.
+        * \param  pX 
+        * \param  pY 
+        * \param  pZ
+        * \return true iff the given 3D-point is in the bounding box of this Mesh.
+        */
+       bool isInBBox(med_float pX, med_float pY, med_float pZ) const
+       {
+               return ((pX >= mMeshBBoxMin[0]) && (pX <= mMeshBBoxMax[0]) &&
+                       (pY >= mMeshBBoxMin[1]) && (pY <= mMeshBBoxMax[1]) &&
+                       (pZ >= mMeshBBoxMin[2]) && (pZ <= mMeshBBoxMax[2]));
+       }
+        
+       /**
+        * Returns the number of elements.
+        * \return the number of elements.
+        */
+       int getNumberOfElements() const;
+       
+       //---------------------------------------------------------------------
+       // Algorithms
+       //---------------------------------------------------------------------
+       
+       /**
+        * Creates a Mesh from a subset of its elements (cells).
+        * \param  pSetOfElements subset of elements to keep.
+        * \param  pNewMeshName   name of the new Mesh.
+        * \return a new Mesh which is a restriction of this Mesh to the given set of elements.
+        * \throw  NullArgumentException if pNewMeshName is NULL.
+        */
+       Mesh* createFromSetOfElements(const std::set<med_int>& pSetOfElements, const char* pNewMeshName);
+       
+       /**
+        * Creates a Mesh from one of its group.
+        * \param  pGroup       any group of this Mesh.  
+        * \param  pNewMeshName name of the new Mesh.
+        * \return a new Mesh which is a restriction of this Mesh to pGroup.
+        * \throw  NullArgumentException if pGroup or pNewMeshName is NULL.
+        */
+       Mesh* createFromGroup(const Group* pGroup, const char* pNewMeshName);
+       
+       /**
+        * Creates a distributed mesh (MeshDis) by creating a new mesh for each group of elements in this Mesh.
+        * \return a distributed mesh from groups of this Mesh.
+        */
+       MeshDis* splitGroupsOfElements();
+       
+       /**
+        * Creates a new mesh by decimating this one.
+        * \param  pFilterName  name of the filter to be used for decimation (e.g. Filtre_GradientMoyen); should not be NULL.
+        * \param  pArgv        all the arguments for filtering as a single string.
+        * \param  pNameNewMesh name of the new mesh.
+        * \return the decimated mesh.
+        * \throw  NullArgumentException if one of the arguments is NULL.
+        * \throw  RuntimeException if any error occurs while decimating data.
+        */
+       Mesh* decimate(
+               const char* pFilterName,
+               const char* pArgv,
+               const char* pNameNewMesh);
+       
+       /**
+        * Gets all the points in a field. Each point has coordinates and a value.
+        * \param  pField      any field of this Mesh.
+        * \param  pTimeStepIt time step iteration.
+        * \param  pPoints     (out) list of points.
+        * \throw  NullArgumentException if pField is NULL.
+        * \throw  IllegalArgumentException if pTimeStepIt is invalid.
+        */
+       void getAllPointsOfField(Field* pField, int pTimeStepIt, std::vector<PointOfField>& pPoints);
+       
+       /**
+        * Returns a default value for neighborhood radius.
+        * Return value is such that, for any point in the field, average number of neighbours is pN.
+        * \param  pN average number of neighbours.
+        * \return a default value for neighborhood radius; 1.0 if some error occurs.
+        */
+       float evalDefaultRadius(int pN) const;
+       
+       //---------------------------------------------------------------------
+       // I/O
+       //---------------------------------------------------------------------
+       
+       /**
+        * Reads a Mesh from a sequential MED file. Resets the object before.
+        * \param  pMEDfilename
+        * \param  pMeshName
+        * \throw  IOException if any i/o error occurs.
+        */
+       void readSequentialMED(const char* pMEDfilename, const char* pMeshName);
+       
+       /**
+        * Writes this Mesh and all related things into a MED file.
+        * \param  pMEDfilename
+        * \throw  IOException if any i/o error occurs.
+        */
+       void writeMED(const char* pMEDfilename);
+       
+       /**
+        * Sets the flag which control the stream operator <<.
+        * \param pFlag new flag value.
+        */
+       void setPrintAll(bool pFlag) { mFlagPrintAll = pFlag; } 
+       
+       /**
+        * Dumps any Mesh to the given output stream.
+        * \param  pOs any output stream.
+        * \param  pM  any Mesh.
+        * \return the output stream pOs.
+        */
+       friend std::ostream& operator<<(std::ostream& pOs, Mesh& pM);
+       
+private:
+        
+       /**
+        * Reads all Gauss localizations in the current MED file.
+        * \throw  IOException if an i/o error occurs.
+        */
+       void readGaussLoc();
+        
+       /**
+        * Reads families in the currentMED file and build groups.
+        * \throw  IOException if an i/o error occurs.
+        */
+       void readFamilies();
+       
+       /**
+        * Finalizes the constructions of families and groups. 
+        * Fill structures with elements.
+        */
+       void finalizeFamiliesAndGroups();
+       
+       /**
+        * Reads fields related to this mesh in the current MED file.
+        * \throw  IOException if an i/o error occurs.
+        */
+       void readFields();
+       
+private:
+
+       /**
+        * Name of the associated MED file.
+        */
+       char                              mMEDfilename[256];
+       
+       /**
+        * MED file handle.
+        */
+       med_idt                           mMEDfile;
+       
+       /**
+        * Name of this mesh.
+        */
+       char                              mMeshName[MED_TAILLE_NOM + 1];
+       
+       /**
+        * Universal name of this mesh.
+        */ 
+       char                              mMeshUName[MED_TAILLE_DESC + 1];
+       
+       /**
+        * Description.
+        */
+       char                              mMeshDesc[MED_TAILLE_DESC + 1]; 
+       
+       /**
+        * Dimension.
+        */
+       med_int                           mMeshDim;
+       
+       /**
+        * Type of mesh (MED_NON_STRUCTURE or MED_STRUCTURE (=grid)) 
+        */
+       med_maillage                      mMeshType;
+       
+       /** 
+        * Axis aligned bounding box of this mesh.
+        */
+       med_float                         mMeshBBoxMin[3];
+       med_float                         mMeshBBoxMax[3];
+
+       /**
+        * All the nodes used by this mesh. 
+        */
+       Nodes*                            mNodes;
+       
+       /**
+        * All the TETRA10 elements used by this mesh.
+        */
+       Elements*                         mElements;
+       
+       /**
+        * Table of families used by this mesh.
+        */
+       std::vector<Family*>              mFamilies;
+       
+       /**
+        * Map to retrieve a Family from its name.
+        */
+       std::map<med_int, Family*>        mFamIdToFam;
+       
+       /**
+        * Table of groups used by this mesh.
+        */
+       std::vector<Group*>               mGroups;
+       
+       /**
+        * Map to retrieve a Group from its name.
+        */
+       std::map<std::string, Group*>     mGroupNameToGroup;
+       
+       /**
+        * Table of GaussLoc. 
+        */
+       std::vector<GaussLoc*>            mGaussLoc; 
+       
+       /**
+        * Map to retrieve a Gauss info from its name.
+        */
+       std::map<std::string, GaussLoc*>  mGaussLocNameToGaussLoc;
+       
+       /**
+        * Table of fields related to this mesh.
+        * Number of fiels = mFields.size().
+        */
+       std::vector<Field*>               mFields;
+       
+       /**
+        * Table of profils.
+        */
+       std::vector<Profil*>              mProfils;
+       
+       /** 
+        * Flag to control the behaviour of the stream operator <<. 
+        */
+       bool                              mFlagPrintAll;
+       
+private:
+
+       // do not allow copy constructor
+       Mesh(const Mesh&);
+       
+       // do not allow copy
+       Mesh& operator=(const Mesh&);
+       
+       // do not allow operator ==
+       bool operator==(const Mesh&); 
+       
+}; // class Mesh
+
+
+} // namespace MULTIPR
+
+
+#endif // MULTIPR_MESH_HXX
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_MeshDis.cxx b/src/MULTIPR/MULTIPR_MeshDis.cxx
new file mode 100644 (file)
index 0000000..3a856f3
--- /dev/null
@@ -0,0 +1,893 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_MeshDis.cxx
+ *
+ * \brief   see MULTIPR_MeshDis.hxx
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+#include "MULTIPR_MeshDis.hxx"
+#include "MULTIPR_Mesh.hxx"
+#include "MULTIPR_Utils.hxx"
+#include "MULTIPR_Globals.hxx"
+#include "MULTIPR_API.hxx"
+#include "MULTIPR_Exceptions.hxx"
+#include "MULTIPR_ProgressCallback.hxx"
+
+#include "MEDSPLITTER_API.hxx"
+
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+
+
+namespace multipr
+{
+
+
+//*****************************************************************************
+// Global variables (exported)
+//*****************************************************************************
+
+MULTIPR_ProgressCallback* gProgressCallback = NULL;
+
+
+//*****************************************************************************
+// Class MeshDisEntry implementation
+//*****************************************************************************
+
+MeshDisPart::MeshDisPart()
+{
+       mMesh             = NULL;
+       mCollection       = NULL;
+       mOldCollection    = NULL;
+       
+       reset();
+}
+
+
+MeshDisPart::~MeshDisPart()
+{
+       reset();
+}
+
+
+void MeshDisPart::reset()
+{
+       mToDoOnNextWrite = MULTIPR_UNDEFINED;
+       
+       mMeshName[0]     = '\0';
+       mId              = 0;
+       mPartName[0]     = '\0';
+       mPath[0]         = '\0';
+       mMEDFileName[0]  = '\0';
+       
+       if (mMesh != NULL)
+       {
+               delete mMesh;
+               mMesh = NULL;
+       }
+       
+       mSplit           = 0;
+       
+       if (mCollection != NULL)
+       {
+               delete mCollection;
+               mCollection = NULL;
+       }
+       
+       if (mOldCollection != NULL)
+       {
+               delete mOldCollection;
+               mOldCollection = NULL;
+       }
+}
+
+
+const char* MeshDisPart::getMEDFileNameSuffix() const
+{      
+       // "agregat100grains_12pas_grain97.med"                       -> "grain97"
+       // "agregat100grains_12pas_grain100_part2.med"                -> "grain100_part2"
+       // "aagregat100grains_12pas_grain98_gradmoy-low-25.0-0.3.med" -> "grain98_gradmoy-low-25-0.3"
+       
+       string prefix = removeExtension(mMEDFileName, ".med");
+       prefix.erase(0, prefix.rfind("grain"));
+       return prefix.c_str();
+}
+
+
+void MeshDisPart::create(
+               OnNextWrite pToDoOnNextWrite,
+               const char* pMeshName, 
+               int         pId,
+               const char* pPartName,
+               const char* pPath,
+               const char* pMEDFileName,
+               Mesh*       pMesh)
+{
+       if (pToDoOnNextWrite == MULTIPR_UNDEFINED) throw IllegalArgumentException("", __FILE__, __LINE__);
+       if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       if (pId < 1) throw IllegalArgumentException("", __FILE__, __LINE__);
+       if (pPartName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       if (pPath == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       if (pMEDFileName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       
+       reset();
+       
+       mToDoOnNextWrite = pToDoOnNextWrite;
+       strcpy(mMeshName, pMeshName);
+       mId = pId;
+       strcpy(mPartName, pPartName);
+       strcpy(mPath, pPath);
+       strcpy(mMEDFileName, pMEDFileName);
+       mMesh = pMesh;
+       
+}
+
+
+void MeshDisPart::readMED()
+{
+       if (mMesh != NULL) throw IllegalStateException("", __FILE__, __LINE__);
+       if (mCollection != NULL) throw IllegalStateException("", __FILE__, __LINE__);
+       if (mOldCollection != NULL) throw IllegalStateException("", __FILE__, __LINE__);
+       
+       //cout << "read MED : mesh=" << mMEDfilename << endl;
+       
+       mMesh = new Mesh();
+       mMesh->readSequentialMED(mMEDFileName, mMeshName);
+}
+
+
+ostream& operator<<(ostream& pOs, MeshDisPart& pM)
+{
+       switch (pM.mToDoOnNextWrite)
+       {
+               case MeshDisPart::MULTIPR_UNDEFINED: 
+                       pOs << "undefined"; 
+                       break;
+                       
+               case MeshDisPart::MULTIPR_KEEP_AS_IT: 
+                       pOs << pM.mMeshName << " " << pM.mId << " " << pM.mPartName << " " << pM.mPath << " " << pM.mMEDFileName;
+                       break;
+                       
+               case MeshDisPart::MULTIPR_WRITE_MESH:
+                       pOs << pM.mMeshName << " " << pM.mId << " " << pM.mPartName << " " << pM.mPath << " " << pM.mMEDFileName;
+                       break;
+                       
+               case MeshDisPart::MULTIPR_WRITE_PARTS:
+                       pOs << pM.mMeshName << " " << pM.mId << " " << pM.mPartName << " " << pM.mPath << " " << pM.mMEDFileName << " SPLIT " << pM.mSplit;
+                       break;
+               
+               default: throw IllegalStateException("", __FILE__, __LINE__);
+       }
+       
+       return pOs;
+}
+
+
+//*****************************************************************************
+// Class MeshDis implementation
+//*****************************************************************************
+
+MeshDis::MeshDis()
+{
+       reset();
+}
+
+
+MeshDis::~MeshDis()
+{
+       reset();
+}
+
+
+void MeshDis::reset()
+{
+       mMEDfilename[0] = '\0';
+       
+       for (unsigned itPart = 0 ; itPart != mParts.size() ; itPart++)
+       {
+               MeshDisPart* part = mParts[itPart];
+               delete part;
+       }
+       mParts.clear();
+       
+       //mProgressCallback = NULL;
+}
+
+
+void MeshDis::addMesh(
+       MeshDisPart::OnNextWrite pToDoOnNextWrite,
+       const char* pMeshName, 
+       int         pId,
+       const char* pPartName,
+       const char* pPath,
+       const char* pMEDFileName,
+       Mesh*       pMesh)
+{
+       MeshDisPart* part = new MeshDisPart();
+       
+       part->create(
+               pToDoOnNextWrite,
+               pMeshName,
+               pId,
+               pPartName,
+               pPath,
+               pMEDFileName,
+               pMesh);
+       
+       mParts.push_back(part);
+}
+
+
+void MeshDis::insertMesh(
+       MeshDisPart::OnNextWrite pToDoOnNextWrite,
+       const char* pMeshName, 
+       int         pId,
+       const char* pPartName,
+       const char* pPath,
+       const char* pMEDFileName,
+       Mesh*       pMesh,
+       int         pPosition)
+{
+       MeshDisPart* part = new MeshDisPart();
+       
+       part->create(
+               pToDoOnNextWrite,
+               pMeshName,
+               pId,
+               pPartName,
+               pPath,
+               pMEDFileName,
+               pMesh);
+       
+       mParts.insert(mParts.begin() + pPosition, part);
+       
+       // rename id of following parts
+       for (unsigned i = pPosition + 1 ; i < mParts.size() ; i++)
+       {
+               mParts[i]->mId = i + 1;
+       }
+}
+
+
+MeshDisPart* MeshDis::findPart(const char* pPartName)
+{
+       if (pPartName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       
+       MeshDisPart* part = NULL;
+       
+       for (unsigned itPart = 0 ; itPart < mParts.size() ; itPart++)
+       {
+               MeshDisPart* currentPart = mParts[itPart];
+               
+               if (strcmp(currentPart->getPartName(), pPartName) == 0)
+               {
+                       part = currentPart;
+                       break;
+               }
+       }
+       
+       return part;
+       
+}
+
+
+vector<string> MeshDis::getMeshes() const
+{
+       vector<string> res;
+       
+       if (mParts.size() > 0)
+       {
+               MeshDisPart* part = mParts[0];
+               const char* meshName = part->getMeshName();
+               res.push_back(meshName);
+       }
+       
+       return res;
+}
+
+
+vector<string> MeshDis::getFields() const
+{
+       vector<string> res;
+       
+       if (mParts.size() == 0)
+       {
+               return res;
+       }
+       
+       // all the parts of the distributed MED file should have the same fields
+       // => just return the name of fields of the first part
+       switch (mParts[0]->mToDoOnNextWrite)
+       {
+               case MeshDisPart::MULTIPR_KEEP_AS_IT: 
+               case MeshDisPart::MULTIPR_WRITE_PARTS:
+               {
+                       vector<pair<string, int> > tmp = multipr::getListFields(mParts[0]->getMEDFileName());
+       
+                       for (int i = 0 ; i < tmp.size() ; i++)
+                       {
+                               res.push_back(tmp[i].first);
+                       }
+                       return res;
+               }
+                       
+               case MeshDisPart::MULTIPR_WRITE_MESH:
+                       return mParts[0]->mMesh->getNameFields();
+               
+               default: 
+                       throw IllegalStateException("", __FILE__, __LINE__);
+       }
+}
+
+
+int MeshDis::getTimeStamps(const char* pFieldName) const
+{
+       if (mParts.size() == 0)
+       {
+               // no parts in this distributed MED file => no fields => #iteration = 0
+               return 0;
+       }
+       
+       // all the parts of the distributed MED file should have the same fields
+       // => just return the number of iteration found in the field of the first part
+       switch (mParts[0]->mToDoOnNextWrite)
+       {
+               case MeshDisPart::MULTIPR_KEEP_AS_IT: 
+               case MeshDisPart::MULTIPR_WRITE_PARTS:
+               {
+                       vector<pair<string, int> > tmp = multipr::getListFields(mParts[0]->getMEDFileName());
+               
+                       for (int i = 0 ; i < tmp.size() ; i++)
+                       {
+                               if (strcmp(tmp[i].first.c_str(), pFieldName) == 0)
+                               {
+                                       return tmp[i].second;
+                               }
+                       }
+                       
+                       // pFieldName not found in the list of fields
+                       return 0;
+               }
+                       
+               case MeshDisPart::MULTIPR_WRITE_MESH:
+                       return mParts[0]->mMesh->getTimeStamps(pFieldName);
+               
+               default: 
+                       throw IllegalStateException("", __FILE__, __LINE__);
+       }
+}
+
+
+string MeshDis::getPartInfo(const char* pPartName)
+{
+       MeshDisPart* part = findPart(pPartName);
+       
+       if (part != NULL)
+       {
+               char num[16];
+               sprintf(num, "%d", part->mId);
+               
+               string res = 
+                       string(part->mMeshName) + 
+                       string(" ") +
+                       string(num) +
+                       string(" ") +
+                       string(part->mPartName) +
+                       string(" ") +
+                       string(part->mPath) +
+                       string(" ") +
+                       string(part->mMEDFileName);
+
+               return res;
+       }
+       else
+       {
+               // part not found => return empty string
+               return "";
+       }
+}
+
+
+void MeshDis::splitPart(const char* pPartName, int pNbParts, int pPartitionner)
+{
+       if (pPartName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       if (pNbParts < 2) throw IllegalArgumentException("", __FILE__, __LINE__);
+       if ((pPartitionner != MULTIPR_METIS) && (pPartitionner != MULTIPR_SCOTCH)) throw IllegalArgumentException("should be 0=METIS or 1=SCOTCH", __FILE__, __LINE__);
+       
+       //---------------------------------------------------------------------
+       // Find the MED file corresponding to the given part
+       //---------------------------------------------------------------------
+       MeshDisPart* part = findPart(pPartName);
+       
+       if (part == NULL)
+       {
+               throw IllegalArgumentException("part not found in this distributed MED file", __FILE__, __LINE__);
+       }
+       
+       //---------------------------------------------------------------------
+       // Load the sequential MED file
+       //---------------------------------------------------------------------
+       MEDSPLITTER::MESHCollection* collection;
+       collection = new MEDSPLITTER::MESHCollection(part->getMEDFileName(), part->getMeshName());
+       
+       //---------------------------------------------------------------------
+       // Partition the group
+       //---------------------------------------------------------------------
+       MEDSPLITTER::Topology* topology;
+       if (pPartitionner == MULTIPR_METIS)
+       {
+               try
+               {
+                       topology = collection->createPartition(pNbParts, MEDSPLITTER::Graph::METIS);
+               }
+               catch (...)
+               {
+                       throw RuntimeException("MEDSPLITTER error: createPartition(), using METIS", __FILE__, __LINE__);
+               }
+       }
+       else if (pPartitionner == MULTIPR_SCOTCH)
+       {
+               try
+               {
+                       topology = collection->createPartition(pNbParts, MEDSPLITTER::Graph::SCOTCH);
+               }
+               catch (...)
+               {
+                       throw RuntimeException("MEDSPLITTER error: createPartition(), using SCOTCH", __FILE__, __LINE__);
+               }
+       }
+       else
+       {
+               throw IllegalStateException("unknown partitionner", __FILE__, __LINE__);
+       }
+       
+       try
+       {
+               MEDSPLITTER::MESHCollection* newCollection = new MEDSPLITTER::MESHCollection(*collection, topology);
+               
+               part->mToDoOnNextWrite = MeshDisPart::MULTIPR_WRITE_PARTS; 
+               part->mSplit           = pNbParts;
+               part->mOldCollection   = collection;
+               part->mCollection      = newCollection;
+       }
+       catch (...)
+       {
+               throw RuntimeException("MEDSPLITTER error: new MESHCollection()", __FILE__, __LINE__);
+       }
+}
+
+
+void MeshDis::decimatePart(
+       const char* pPartName, 
+       const char* pFieldName,
+       med_int     pFieldIt,
+       const char* pFilterName,
+       med_float   pTMed, 
+       med_float   pTLow,
+       med_float   pRadius,
+       int         pBoxing)
+{
+       //---------------------------------------------------------------------
+       // Check arguments
+       //---------------------------------------------------------------------
+       if (pPartName == NULL) throw NullArgumentException("partname should not be NULL", __FILE__, __LINE__);
+       if (pFieldName == NULL) throw NullArgumentException("fieldname should not be NULL", __FILE__, __LINE__);
+       if (pFieldIt < med_int(1)) throw IllegalArgumentException("invalid field iteration; should be >= 1", __FILE__, __LINE__);
+       if (pTMed < 0.0) throw IllegalArgumentException("med res.: threshold must be > 0", __FILE__, __LINE__);
+       if (pTMed >= pTLow) throw IllegalArgumentException("threshold for med res. must be < threshold for low res.", __FILE__, __LINE__);      
+       if (pRadius <= med_float(0.0)) throw IllegalArgumentException("radius should be > 0", __FILE__, __LINE__);
+       if ((pBoxing < 1) || (pBoxing > 200)) throw IllegalArgumentException("boxing should be in [1..200]", __FILE__, __LINE__);
+       
+       //---------------------------------------------------------------------
+       // Find the MED file corresponding to the given part
+       //---------------------------------------------------------------------
+       MeshDisPart* part = findPart(pPartName);
+       if (part == NULL)
+       {
+               throw IllegalArgumentException("part not found in the given distributed MED file", __FILE__, __LINE__);
+       }
+       
+       //---------------------------------------------------------------------
+       // Load the associated sequential MED file
+       //---------------------------------------------------------------------
+       if (part->mMesh == NULL)
+       {
+               part->readMED();
+       }
+       
+       Mesh* meshFull = part->mMesh;
+       cout << (*meshFull) << endl;
+       
+       const char* originalFilename = part->getMEDFileName();
+       string strPrefix = removeExtension(originalFilename, ".med");
+       
+       //---------------------------------------------------------------------
+       // Decimates the given mesh
+       //---------------------------------------------------------------------
+       // arguments for decimation are passed as a string for genericity
+       char argv[256];
+       char newPartName[MED_TAILLE_NOM + 1];
+       char newMEDFileName[256];
+       
+       // *** create a new mesh = MEDIUM resolution ***
+       sprintf(argv, "%s %d %lf %lf %d", pFieldName, pFieldIt, pTMed, pRadius, pBoxing);
+       sprintf(newPartName, "%s_MED", pPartName);
+       sprintf(newMEDFileName, "%s_gradmoy-med-%s-%s.med", 
+               strPrefix.c_str(), 
+               realToString(pTMed).c_str(), 
+               realToString(pRadius).c_str());
+       
+       {
+               Mesh* meshMedium = meshFull->decimate(pFilterName, argv, part->getMeshName());
+               cout << (*meshMedium) << endl;
+               
+               insertMesh(
+                       MeshDisPart::MULTIPR_WRITE_MESH,
+                       part->getMeshName(),
+                       part->mId + 1,
+                       newPartName,
+                       "localhost",
+                       newMEDFileName,
+                       meshMedium,
+                       part->mId + 0);
+       }
+       
+       // *** create a new mesh = LOW resolution ***
+       sprintf(argv, "%s %d %lf %lf %d", pFieldName, pFieldIt, pTLow, pRadius, pBoxing);
+       sprintf(newPartName, "%s_LOW", pPartName);
+       sprintf(newMEDFileName, "%s_gradmoy-low-%s-%s.med", 
+               strPrefix.c_str(), 
+               realToString(pTLow).c_str(), 
+               realToString(pRadius).c_str());
+       
+       {
+               Mesh* meshLow = meshFull->decimate(pFilterName, argv, part->getMeshName());
+               cout << (*meshLow) << endl;
+               
+               insertMesh(
+                       MeshDisPart::MULTIPR_WRITE_MESH,
+                       part->getMeshName(),
+                       part->mId + 2,
+                       newPartName,
+                       "localhost",
+                       newMEDFileName,
+                       meshLow,
+                       part->mId + 1);
+       }
+}
+
+
+int MeshDis::computeNumParts()
+{
+       int numParts = 0;
+       
+       for (unsigned itPart = 0 ; itPart < mParts.size() ; itPart++)
+       {
+               switch (mParts[itPart]->mToDoOnNextWrite)
+               {
+               case MeshDisPart::MULTIPR_KEEP_AS_IT: 
+               case MeshDisPart::MULTIPR_WRITE_MESH:
+                       numParts++;
+                       break;
+               
+               case MeshDisPart::MULTIPR_WRITE_PARTS:
+                       numParts += mParts[itPart]->mSplit;
+                       break;
+               
+               default: throw IllegalStateException("", __FILE__, __LINE__);
+               }
+       }
+       
+       return numParts;
+}
+
+
+void MeshDis::readDistributedMED(const char* pMEDfilename)
+{
+       //cout << "DBG: readDistributedMED" << endl;
+       if (pMEDfilename == NULL) throw NullArgumentException("filename should not be NULL", __FILE__, __LINE__);
+       
+       const int MAX_SIZEOF_LINE = 1024;
+       
+       reset();
+       strcpy(mMEDfilename, pMEDfilename);
+       
+       //---------------------------------------------------------------------
+       // Open master file (ASCII file)
+       //---------------------------------------------------------------------
+       ifstream fileMaster(mMEDfilename);
+       if (fileMaster.fail()) throw IOException("i/o error while opening MED master file", __FILE__, __LINE__);
+
+       //cout << "DBG: readDistributedMED: open" << endl;
+
+       //---------------------------------------------------------------------
+       // Read header
+       //---------------------------------------------------------------------
+       char charbuffer[MAX_SIZEOF_LINE];
+       fileMaster.getline(charbuffer, MAX_SIZEOF_LINE);
+       if (fileMaster.fail()) throw IOException("i/o error while reading MED master file", __FILE__, __LINE__);
+       
+       // check format
+       if ((charbuffer[0] != '#') ||
+           (charbuffer[1] != ' ') ||
+               (charbuffer[2] != 'M') ||
+               (charbuffer[3] != 'E') ||
+               (charbuffer[4] != 'D'))
+               throw IOException("not a valid distributed MED file", __FILE__, __LINE__);
+               
+       while ((charbuffer[0] == '#') || (strlen(charbuffer) == 0))
+       {
+               fileMaster.getline(charbuffer, MAX_SIZEOF_LINE);
+               if (fileMaster.fail()) throw IOException("i/o error while reading MED master file", __FILE__, __LINE__);
+       }
+       
+       // read number of parts
+       int nbParts = atoi(charbuffer);
+       //cout << "DBG: readDistributedMED: #parts=" << nbParts << endl;
+       
+       //---------------------------------------------------------------------
+       // Read infos about sub-parts
+       //---------------------------------------------------------------------
+       char   lMeshName[MED_TAILLE_NOM + 1];
+       int    lId;
+       char   lPartName[MED_TAILLE_NOM + 1];
+       char   lPath[256];
+       char   lMEDFileName[256];       
+       
+       for (int i = 0 ; i < nbParts ; i++)
+       {
+               fileMaster.getline(charbuffer, MAX_SIZEOF_LINE);
+               if (fileMaster.fail()) throw IOException("i/o error while reading MED master file", __FILE__, __LINE__);
+               
+               while ((charbuffer[0] == '#') || (strlen(charbuffer) == 0))
+               {
+                       fileMaster.getline(charbuffer, MAX_SIZEOF_LINE);
+                       if (fileMaster.fail()) throw IOException("i/o error while reading MED master file", __FILE__, __LINE__);
+               }
+               
+               lMeshName[0]    = '\0';
+               lId             = 0;
+               lPartName[0]    = '\0';
+               lPath[0]        = '\0';
+               lMEDFileName[0] = '\0';
+               
+               int ret = sscanf(charbuffer, "%s %d %s %s %s", 
+                       lMeshName,
+                       &lId,
+                       lPartName,
+                       lPath,
+                       lMEDFileName);
+       
+               if (ret != 5) throw IOException("i/o error while reading MED master file; bad format", __FILE__, __LINE__);
+
+               //cout << "DBG: read: " << lMeshName << " " << lId << " " << lPartName << endl;
+               addMesh(
+                       MeshDisPart::MULTIPR_KEEP_AS_IT,
+                       lMeshName,
+                       lId,
+                       lPartName,
+                       lPath,
+                       lMEDFileName,
+                       NULL);
+       }
+       
+       //---------------------------------------------------------------------
+       // Close master file
+       //---------------------------------------------------------------------
+       fileMaster.close();
+       if (fileMaster.fail()) throw IOException("i/o error while closing MED master file", __FILE__, __LINE__);
+       //cout << "DBG: readDistributedMED: close" << endl;
+}
+
+
+/**
+ * Retrieves the output of MEDSPLITTER and convert it for MULTIPR.
+ */
+int convertMedsplitterToMultipr(ofstream& pFileMaster, const char* pTmpFilename, int pId, MeshDisPart* pPart)
+{
+       MULTIPR_LOG("convert" << endl);
+       
+       const int MAX_SIZEOF_LINE = 1024;
+       char charbuffer[MAX_SIZEOF_LINE];
+       
+       // Open medsplitter master file (ASCII file)
+       ifstream fileMasterMedsplitter(pTmpFilename);
+       if (fileMasterMedsplitter.fail()) throw IOException("i/o error while opening MEDSPLITTER master file", __FILE__, __LINE__);
+       
+       fileMasterMedsplitter.getline(charbuffer, MAX_SIZEOF_LINE);
+       if (fileMasterMedsplitter.fail()) throw IOException("i/o error while reading MEDSPLITTER master file", __FILE__, __LINE__);     
+
+       while ((charbuffer[0] == '#') || (strlen(charbuffer) == 0))
+       {
+               fileMasterMedsplitter.getline(charbuffer, MAX_SIZEOF_LINE);
+               if (fileMasterMedsplitter.fail()) throw IOException("i/o error while reading MEDSPLITTER master file", __FILE__, __LINE__);
+       }
+
+       // read number of parts
+       int nbParts = atoi(charbuffer);
+       cout << "nb parts=" << nbParts << endl;
+
+       char   lMeshName[MED_TAILLE_NOM + 1];
+       int    lId;
+       char   lPartName[MED_TAILLE_NOM + 1];
+       char   lPath[256];
+       char   lMEDFileName[256];
+       
+       for (int i = 0 ; i < nbParts ; i++)
+       {
+               fileMasterMedsplitter.getline(charbuffer, MAX_SIZEOF_LINE);
+               if (fileMasterMedsplitter.fail()) throw IOException("", __FILE__, __LINE__);
+               
+               // parses the current line
+               lMeshName[0]    = '\0';
+               lId             = 0;
+               lPartName[0]    = '\0';
+               lPath[0]        = '\0';
+               lMEDFileName[0] = '\0';
+               
+               int ret = sscanf(charbuffer, "%s %d %s %s %s", 
+                       lMeshName,
+                       &lId,
+                       lPartName,
+                       lPath,
+                       lMEDFileName);
+                       
+               if (ret != 5) throw IOException("i/o error while reading MEDSPLITTER master file; bad format", __FILE__, __LINE__);
+               
+               //cout << lMeshName << " " << (pId + i) << " " << pPart->getPartName() << "_" << (i + 1) << " " << lPath << " " << lMEDFileName << endl;
+               
+               pFileMaster << lMeshName << " " << (pId + i) << " " << pPart->getPartName() << "_" << (i + 1) << " " << lPath << " " << lMEDFileName << endl;
+       }
+       
+       fileMasterMedsplitter.close();
+       if (fileMasterMedsplitter.fail()) throw IOException("i/o error while closing MEDSPLITTER master file", __FILE__, __LINE__);
+       
+       // remove master file generated by MEDSPLITTER
+       remove(pTmpFilename);
+       
+       return nbParts;
+}
+
+
+void MeshDis::writeDistributedMED(const char* pMEDfilenamePrefix)
+{
+       if (pMEDfilenamePrefix == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       
+       //---------------------------------------------------------------------
+       // Build master filename
+       //---------------------------------------------------------------------
+       string strPrefix = string(pMEDfilenamePrefix);
+       const char* strExtension = ".med";
+       string strMasterFilename;
+       
+       // add suffix "_grains_maitre" iff it is not yet in the filename
+       if (strstr(pMEDfilenamePrefix, "_grains_maitre") == 0)
+       {
+               strMasterFilename= strPrefix + "_grains_maitre" + strExtension;
+       }
+       else
+       {
+               strMasterFilename = strPrefix + strExtension;
+       }
+       
+       MULTIPR_LOG("Create master: " << strMasterFilename << endl);
+       strcpy(mMEDfilename, strMasterFilename.c_str());
+       
+       //---------------------------------------------------------------------
+       // Create an ASCII master file for the resulting distributed mesh and write header
+       //---------------------------------------------------------------------
+       remove(strMasterFilename.c_str());
+       ofstream fileMaster(strMasterFilename.c_str());
+       
+       if (fileMaster == 0) throw IOException("i/o error while creating MED master file", __FILE__, __LINE__);
+       
+       fileMaster << "# MED file v2.3 - Master file created by MULTIPR v" << getVersion() << endl;
+       fileMaster << "#" << " " << endl;
+       
+       fileMaster << computeNumParts() << endl;
+       if (fileMaster.fail()) throw IOException("i/o error while writing MED master file", __FILE__, __LINE__);
+       
+       //---------------------------------------------------------------------
+       // Create a new MED file (v2.3)
+       //---------------------------------------------------------------------
+       int id = 1;
+       
+       if (gProgressCallback != NULL) gProgressCallback->start("Save mesh", mParts.size());
+       
+       try
+       {
+       
+       // for each sub-meshes
+       for (unsigned itPart = 0 ; itPart < mParts.size() ; itPart++)
+       {
+               switch (mParts[itPart]->mToDoOnNextWrite)
+               {
+                       case MeshDisPart::MULTIPR_KEEP_AS_IT: 
+                       {
+                               mParts[itPart]->mId = id;
+                               id++;
+                               fileMaster << (*mParts[itPart]) << endl;
+                               cout << (*mParts[itPart]) << endl;
+                               break;
+                       }
+                       
+                       case MeshDisPart::MULTIPR_WRITE_MESH:
+                       {
+                               if (strlen(mParts[itPart]->getMEDFileName()) == 0) throw IOException("MED filename is empty", __FILE__, __LINE__);
+                               if (mParts[itPart]->mMesh == NULL) throw IllegalStateException("invalid mesh (shoult not be NULL)", __FILE__, __LINE__);
+                               mParts[itPart]->mMesh->writeMED(mParts[itPart]->getMEDFileName());
+                               mParts[itPart]->mId = id;
+                               id++;
+                               fileMaster << (*mParts[itPart]) << endl;
+                               cout << (*mParts[itPart]) << endl;
+                               break;
+                       }
+                       
+                       case MeshDisPart::MULTIPR_WRITE_PARTS:
+                       {
+                               // split this part using medsplitter
+                               if (mParts[itPart]->mOldCollection == NULL) throw IllegalStateException("", __FILE__, __LINE__);
+                               string strPrefix = removeExtension(mParts[itPart]->getMEDFileName(), ".med"); 
+                               char tmpFilename[256];
+                               sprintf(tmpFilename, "%s_part", strPrefix.c_str());
+                               mParts[itPart]->mCollection->write(tmpFilename);
+                               mParts[itPart]->mCollection->castAllFields(*(mParts[itPart]->mOldCollection));
+                               int ret = convertMedsplitterToMultipr(fileMaster, tmpFilename, id, mParts[itPart]);
+                               id += ret;
+                               remove(mParts[itPart]->getMEDFileName());
+                               break;
+                       }
+               
+                       default: throw IllegalStateException("should not be there", __FILE__, __LINE__);
+               }
+               
+               if (gProgressCallback != NULL) gProgressCallback->moveOn();
+       }
+       
+       }
+       catch (RuntimeException& e)
+       {
+               if (gProgressCallback != NULL) gProgressCallback->done();
+               throw e;
+       }
+       
+       if (gProgressCallback != NULL) gProgressCallback->done();
+       
+       //---------------------------------------------------------------------
+       // Close master file
+       //---------------------------------------------------------------------
+       fileMaster.close();
+       if (fileMaster.fail()) throw IOException("i/o error while closing MED master file", __FILE__, __LINE__);
+}
+
+
+ostream& operator<<(ostream& pOs, MeshDis& pM)
+{
+       pOs << "Mesh Dis.:" << endl;
+       pOs << "    Filename   =|" << pM.mMEDfilename << "|" << endl;
+       pOs << "    #Sub-meshes=" << pM.mParts.size() << endl;
+       
+       for (unsigned itPart = 0 ; itPart < pM.mParts.size() ; itPart++)
+       {
+               cout << "        " << (itPart + 1) << ": " << (*(pM.mParts[itPart])) << endl; 
+       }
+       
+       return pOs;
+}
+
+
+} // namespace multipr
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_MeshDis.hxx b/src/MULTIPR/MULTIPR_MeshDis.hxx
new file mode 100644 (file)
index 0000000..bcfeebc
--- /dev/null
@@ -0,0 +1,436 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_MeshDis.hxx
+ *
+ * \brief   Class MeshDis: distributed mesh.
+ *          = MASTER file (ASCII) -> list of sequential MED file.
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#ifndef MULTIPR_MESHDIS_HXX
+#define MULTIPR_MESHDIS_HXX
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+extern "C"
+{
+       #include "med.h"
+}
+
+#include <iostream>
+#include <vector>
+
+// include MEDSPLITTER used to split mesh using METIS or SCOTCH
+#include "MEDMEM_define.hxx"
+#include "MEDMEM_Mesh.hxx"
+#include "MEDMEM_Family.hxx"
+#include "MEDSPLITTER_Graph.hxx"
+#include "MEDSPLITTER_MESHCollection.hxx"
+#include "MEDSPLITTER_Topology.hxx"
+
+
+namespace multipr
+{
+
+//*****************************************************************************
+// Pre-declaration
+//*****************************************************************************
+
+class Mesh;
+
+
+//*****************************************************************************
+// Class MeshDisPart = a sub-part of a distributed mesh.
+//
+// It can be :
+// - a sequential MED file representing a Group (scenario 1)
+// - a sequential MED file representing a part of a Group (scenario 2 -> MEDSPLITTER)
+// - a lower resolution of a part (decimation)
+//*****************************************************************************
+
+class MeshDisPart
+{
+
+public:
+
+       /**
+        * Action to be done for this part on next writing on disk.
+        */
+       enum OnNextWrite
+       {
+               MULTIPR_UNDEFINED,
+               MULTIPR_KEEP_AS_IT,
+               MULTIPR_WRITE_MESH,
+               MULTIPR_WRITE_PARTS
+       };
+       
+public:
+
+       /**
+        * Builds an empty part of a distributed mesh (default constructor).
+        */
+       MeshDisPart();
+       
+       /**
+        * Destructor. Removes everything.
+        */
+       ~MeshDisPart();
+       
+       /**
+        * Resets this object in its state by default (empty). Cleans memory.
+        */
+       void reset();
+       
+       /**
+        * Creates a MeshDisPart.
+        * \param  pToDoOnNextWrite
+        * \param  pMeshName
+        * \param  pId
+        * \param  pPartName
+        * \param  pPath
+        * \param  pMEDFileName
+        * \param  pMesh can be NULL.
+        */
+       void create(
+               OnNextWrite pToDoOnNextWrite,
+               const char* pMeshName, 
+               int         pId,
+               const char* pPartName,
+               const char* pPath,
+               const char* pMEDFileName,
+               Mesh*       pMesh);
+       
+       //---------------------------------------------------------------------
+       // Basic accessors/mutators
+       //---------------------------------------------------------------------
+       
+       /**
+        * Returns the name of this part.
+        * \return the name of this part.
+        */
+       const char* getPartName() const { return mPartName; }
+       
+       /**
+        * Returns the name of the mesh of this part.
+        * \return the name of the mesh of this part.
+        */
+       const char* getMeshName() const { return mMeshName; }
+       
+       /**
+        * Returns the MED filename which contain this part.
+        * \return the MED filename which contain this part.
+        */
+       const char* getMEDFileName() const { return mMEDFileName; }
+       
+       /**
+        * Returns the suffix of the related MED filename (without .med extension).
+        * For examples:
+        * 1. "agregat100grains_12pas_grain97.med"                       -> "grain97"
+        * 2. "agregat100grains_12pas_grain100_part2.med"                -> "grain100_part2"
+        * 3. "aagregat100grains_12pas_grain98_gradmoy-low-25.0-0.3.med" -> "grain98_gradmoy-low-25-0.3"
+        */
+       const char* getMEDFileNameSuffix() const;
+       
+       /**
+        * Returns the action to be performed on this part on next write.
+        * \return the action to be performed on this part on next write.
+        */
+       OnNextWrite getOnNextWrite() const { return mToDoOnNextWrite; }
+        
+       //---------------------------------------------------------------------
+       // I/O
+       //---------------------------------------------------------------------
+       
+       /**
+        * Reads the sequentiel MED file corresponding to this part.
+        * \throw  IOException if an i/o error occurs.
+        */
+       void readMED();
+        
+       /**
+        * Dumps any MeshDisPart to the given output stream.
+        * \param  pOs any output stream.
+        * \param  pM  any MeshDisPart.
+        * \return the output stream pOs.
+        */
+       friend std::ostream& operator<<(std::ostream& pOs, MeshDisPart& pM);
+       
+private:
+
+       // MeshDisPart can be used:
+       // 1 (KEEP_AS_IT)  : To store data read from one line of an ASCII master file (distributed MED file)
+       // 2 (WRITE_MESH)  : As a temporary structure to store all infos about a mesh corresponding to a group (before writing on disk).
+       // 3 (WRITE_PARTS) : As a temporary structure to store all infos about splitting using MEDSPLITTER.
+       
+       OnNextWrite  mToDoOnNextWrite;               /**< See enum OnNextWrite. */
+       
+       //---------------------------------------------------------------------
+       // Case 1, 2, and 3
+       //---------------------------------------------------------------------         
+       char   mMeshName[MED_TAILLE_NOM + 1];        /**< Name of the mesh. */
+       int    mId;                                  /**< Id of this part in [1..n]. */
+       char   mPartName[MED_TAILLE_NOM + 1];        /**< Name of this part. */
+       char   mPath[256];                           /**< Path of the MED file. */
+       char   mMEDFileName[256];                    /**< Name of the MED file which contain this part. */
+       
+       //---------------------------------------------------------------------
+       // Case 2: mesh of the related sequential MED file (can be NULL if not loaded)
+       //---------------------------------------------------------------------
+       Mesh*  mMesh;                                /**< Mesh associated with this part; can be NULL. */
+       
+       //---------------------------------------------------------------------
+       // Case 3 only: temporary result of MEDSPLITTER
+       //---------------------------------------------------------------------
+       int                          mSplit;         /**< For MEDSPLITTER: number of parts. Temporary. */
+       MEDSPLITTER::MESHCollection* mCollection;    /**< New data after splitting. */
+       MEDSPLITTER::MESHCollection* mOldCollection; /**< Data before splitting (we need them when we want to write new data on disk. */
+       
+private:
+
+       // do not allow copy constructor
+       MeshDisPart(const MeshDisPart&);
+       
+       // do not allow copy
+       MeshDisPart& operator=(const MeshDisPart&);
+       
+       // do not allow operator ==
+       bool operator==(const MeshDisPart&); 
+       
+       //---------------------------------------------------------------------
+       // Friends
+       //--------------------------------------------------------------------- 
+       friend class MeshDis;
+       
+}; // class MeshDisPart
+
+
+//*****************************************************************************
+// Class MeshDis
+//*****************************************************************************
+
+class MeshDis
+{
+public:
+
+       /**
+        * Builds an empty mesh (default constructor).
+        */
+       MeshDis();
+        
+       /**
+        * Destructor. Removes everything.
+        */
+       ~MeshDis();
+        
+       /**
+        * Resets this object in its state by default (empty). Clean memory.
+        */
+       void reset();
+       
+       //---------------------------------------------------------------------
+       // Basic accessors/mutators
+       //---------------------------------------------------------------------
+
+       /**
+        * Returns the name of this distributed MED file (=name of the master file).
+        * \return the name of this distributed MED file (=name of the master file).
+        */
+       const char* getFilename() const { return mMEDfilename; }
+        
+       /**
+        * Adds a new part to this distributed mesh.
+        * Used by the split process (extract groups).
+        * \param  pToDoOnNextWrite
+        * \param  pMeshName
+        * \param  pId
+        * \param  pPartName
+        * \param  pPath
+        * \param  pMEDFileName
+        * \param  pMesh can be NULL.
+        */
+       void addMesh(
+               MeshDisPart::OnNextWrite pToDoOnNextWrite,
+               const char* pMeshName, 
+               int         pId,
+               const char* pPartName,
+               const char* pPath,
+               const char* pMEDFileName,
+               Mesh*       pMesh);
+       
+       /**
+        * Inserts a new part to this distributed mesh.
+        * Used by the decimation process.
+        * \param  pToDoOnNextWrite
+        * \param  pMeshName
+        * \param  pId
+        * \param  pPartName
+        * \param  pPath
+        * \param  pMEDFileName
+        * \param  pMesh can be NULL.
+        * \param  pPosition insert after this position. Start at 1.
+        */
+       void insertMesh(
+               MeshDisPart::OnNextWrite pToDoOnNextWrite,
+               const char* pMeshName, 
+               int         pId,
+               const char* pPartName,
+               const char* pPath,
+               const char* pMEDFileName,
+               Mesh*       pMesh,
+               int         pPosition);
+               
+       /**
+        * Returns the current number of parts in this distributed mesh.
+        * \return the current number of parts in this distributed mesh.
+        */
+       int getNumParts() const { return mParts.size(); }
+       
+       /**
+        * Returns the nth part of this distributed mesh.
+        * \param  pIndex index of the part (in 0..getNumParts()-1).
+        * \return the nth part of this distributed mesh.
+        */
+       MeshDisPart* getPart(int pIndex) const { return mParts[pIndex]; }
+       
+       /**
+        * Returns the list of meshes contained in this distributed MED file.
+        * \return the list of meshes contained in this distributed MED file.
+        */
+       std::vector<std::string> getMeshes() const; 
+       
+       /**
+        * Returns the list of fields contained in this distributed MED file.
+        * \return the list of fields contained in this distributed MED file.
+        */
+       std::vector<std::string> getFields() const; 
+       
+       /**
+        * Returns the number of iteration for a given field.
+        * \param  pFieldName field name.
+        * \return the number of iteration for a given field.
+        */
+       int getTimeStamps(const char* pFieldName) const; 
+       
+       /**
+        * Returns all information about a part.
+        * \param  pPartName name of the part.
+        * \return all information about a part.
+        */
+       std::string getPartInfo(const char* pPartName);
+        
+       //---------------------------------------------------------------------
+       // Algorithms
+       //---------------------------------------------------------------------
+       
+       /**
+        * Finds a part of this distributed mesh by its name.
+        * Returns NULL if the part does not exist.
+        * \param  pPartName part to be found; must not be NULL.
+        * \return a pointer towards the part if it exists, NULL otherwise.
+        * \throw  NullArgumentException if pPartName is NULL.
+        */
+       MeshDisPart* findPart(const char* pPartName);
+       
+       /**
+        * Updates this distributed mesh by splitting one of its part.
+        * This splitting method leans on medsplitter, by V. Bergeaud (CEA).
+        * \param  pPartName     name of the part to be splitted.
+        * \param  pNbParts      number of sub-parts.
+        * \param  pPartitionner MULTIPR_METIS or MULTIPR_SCOTCH.
+        * \throw  RuntimeException if any error occurs.
+        */
+       void splitPart(const char* pPartName, int pNbParts, int pPartitionner);
+       
+       /**
+        * Creates 3 resolution (CURRENT = FULL, MEDIUM and LOW) of a part of this distributed mesh.
+        * Names of new meshes are <original_name>_MED and <original_name>_LOW.
+        * \param  pPartName
+        * \param  pFielName
+        * \param  pFieldIt
+        * \param  pFilterName
+        * \param  pTMed        threshold used to generate MEDIUM resolution.
+        * \param  pTLow        threshold used to generate LOW resolution (must be >= pTMed).
+        * \param  pRadius
+        * \param  pBoxing number of cells along each axis; e.g. if 100 then grid will have 100*100*100 = 10**6 cells; 100 by default.
+        * \throw  RuntimeException if any error occurs.
+        */
+       void decimatePart(
+               const char* pPartName, 
+               const char* pFieldName,
+               med_int     pFieldIt,
+               const char* pFilterName,
+               med_float   pTMed, 
+               med_float   pTLow,
+               med_float   pRadius,
+               int         pBoxing = 100);
+       
+       //---------------------------------------------------------------------
+       // I/O
+       //---------------------------------------------------------------------
+       
+       /**
+        * Reads the master file of a distributed MED file.
+        * \param  pMEDfilename
+        * \throw  NullArgumentException if pMEDfilename is NULL.
+        * \throw  IOException if any i/o error occurs.
+        */
+       void readDistributedMED(const char* pMEDfilename);
+       
+       /**
+        * Writes this distributed MED file (including master file and sub MED files if necessary).
+        * \param  pMEDfilenamePrefix
+        * \throw  NullArgumentException if pMEDfilename is NULL.
+        * \throw  IOException if any i/o error occurs.
+        */
+       void writeDistributedMED(const char* pMEDfilenamePrefix);
+       
+       /**
+        * Dumps any MeshDis to the given output stream.
+        * \param  pOs any output stream.
+        * \param  pM  any MeshDis.
+        * \return the output stream pOs.
+        */
+       friend std::ostream& operator<<(std::ostream& pOs, MeshDis& pM);
+       
+private:
+
+       /**
+        * Recomputes the number of parts in this distributed mesh.
+        * This method is used by writeDistributedMED().
+        * \return the number of parts in this distributed mesh.
+        */
+       int computeNumParts();
+       
+private:
+
+       char                        mMEDfilename[256];  /** Name of this distributed MED file (= name of the master file). */
+       std::vector<MeshDisPart*>   mParts;             /**< Table of sub-parts; a distributed mesh is composed of N sub-part, where N = mParts.size(). */
+       //MULTIPR_ProgressCallback*   mProgressCallback;
+       
+private:
+
+       // do not allow copy constructor
+       MeshDis(const MeshDis&);
+       
+       // do not allow copy
+       MeshDis& operator=(const MeshDis&);
+       
+       // do not allow operator ==
+       bool operator==(const MeshDis&); 
+       
+}; // class MeshDis
+
+
+} // namespace MULTIPR
+
+
+#endif // MULTIPR_MESHDIS_HXX
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_Nodes.cxx b/src/MULTIPR/MULTIPR_Nodes.cxx
new file mode 100644 (file)
index 0000000..a499c95
--- /dev/null
@@ -0,0 +1,400 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_Nodes.cxx
+ *
+ * \brief   see MULTIPR_Nodes.hxx
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+#include "MULTIPR_Nodes.hxx"
+#include "MULTIPR_Exceptions.hxx"
+
+#include <iostream>
+
+using namespace std;
+
+
+namespace multipr
+{
+
+
+//*****************************************************************************
+// Class Nodes implementation
+//*****************************************************************************
+
+Nodes::Nodes() 
+{
+       mId           = NULL;
+       mFamIdent     = NULL;
+       mNames        = NULL;
+       mCoo          = NULL;
+       mNamesCoo     = NULL;
+       mNamesUnitCoo = NULL;
+       
+       reset(); 
+}
+
+
+Nodes::~Nodes()  
+{ 
+       reset();  
+}
+
+
+void Nodes::reset() 
+{ 
+       mNum         = 0;
+       mDim         = 0;
+       mCoordSystem = MED_CART;
+       
+       if (mId           != NULL) { delete[] mId;           mId           = NULL; }
+       if (mFamIdent     != NULL) { delete[] mFamIdent;     mFamIdent     = NULL; }
+       if (mNames        != NULL) { delete[] mNames;        mNames        = NULL; }
+       if (mCoo          != NULL) { delete[] mCoo;          mCoo          = NULL; }
+       if (mNamesCoo     != NULL) { delete[] mNamesCoo;     mNamesCoo     = NULL; }
+       if (mNamesUnitCoo != NULL) { delete[] mNamesUnitCoo; mNamesUnitCoo = NULL; }
+       
+       mFlagPrintAll = false;
+}
+
+
+const med_float* Nodes::getCoordinates(med_int pIndexNode) const 
+{ 
+       if ((pIndexNode < 0) || (pIndexNode >= mNum)) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
+       
+       return mCoo + pIndexNode * mDim; 
+}
+
+
+med_int Nodes::getFamIdent(med_int pIndexNode) const 
+{ 
+       if ((pIndexNode < 0) || (pIndexNode >= mNum)) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
+       
+       return mFamIdent[pIndexNode]; 
+}
+
+
+void Nodes::getBBox(med_float pMin[3], med_float pMax[3]) const
+{
+       //---------------------------------------------------------------------
+       // Special case: no nodes => bbox = [0 ; 0] x [0 ; 0] x [0 ; 0]
+       //---------------------------------------------------------------------
+       if (mNum == 0)
+       {
+               for (int itDim = 0 ; itDim < mDim ; itDim++) 
+               { 
+                       pMin[itDim] = med_float(0.0);
+                       pMax[itDim] = med_float(0.0);
+               }
+               
+               return;
+       }
+       
+       //---------------------------------------------------------------------
+       // Compute axis-aligned bounding box
+       //---------------------------------------------------------------------
+       for (int itDim = 0 ; itDim < mDim ; itDim++) 
+       { 
+               pMin[itDim] = numeric_limits<med_float>::max();
+               pMax[itDim] = -pMin[itDim];
+       }
+       for (int itNode = 0 ; itNode < mNum ; itNode++)
+       {       
+               for (int itDim = 0 ; itDim < mDim ; itDim++)
+               {
+                       med_float coord = mCoo[itNode * mDim + itDim];
+                       if (coord < pMin[itDim]) pMin[itDim] = coord;
+                       if (coord > pMax[itDim]) pMax[itDim] = coord;
+               }
+       }
+}
+
+
+set<med_int> Nodes::getSetOfFamilies() const
+{
+       set<med_int> setOfFamilies;
+       
+       // for each node, ad its family to the set
+       for (int itNode = 0 ; itNode < mNum ; itNode++)
+       {
+               setOfFamilies.insert(mFamIdent[itNode]);
+       }
+       
+       return setOfFamilies;
+}
+
+
+Nodes* Nodes::extractSubSet(const set<med_int>& pSetIndices) const
+{
+       Nodes* subset = new Nodes();
+       
+       subset->mNum         = pSetIndices.size();
+       subset->mDim         = mDim;
+       subset->mCoordSystem = mCoordSystem;
+       
+       //---------------------------------------------------------------------
+       // Allocate arrays
+       //---------------------------------------------------------------------
+       subset->mFamIdent     = new med_int[subset->mNum];      
+       subset->mCoo          = new med_float[subset->mDim * subset->mNum];
+       subset->mNamesCoo     = new char[subset->mDim * MED_TAILLE_PNOM + 1];
+       subset->mNamesUnitCoo = new char[subset->mDim * MED_TAILLE_PNOM + 1];
+       
+       memcpy(subset->mNamesCoo, mNamesCoo, subset->mDim * MED_TAILLE_PNOM + 1);
+       memcpy(subset->mNamesUnitCoo, mNamesUnitCoo, subset->mDim * MED_TAILLE_PNOM + 1);
+       
+       //---------------------------------------------------------------------
+       // Copy subset of familys id and coords.
+       //---------------------------------------------------------------------
+       set<med_int>::iterator itSet = pSetIndices.begin();
+       for (int i = 0 ; i < subset->mNum; i++)
+       {
+               
+               med_int srcIndex = (*itSet) - 1; // MED index start at 1
+               subset->mFamIdent[i] = mFamIdent[srcIndex];
+               
+               med_float* srcCoo = mCoo + srcIndex * mDim;
+               med_float* destCoo = subset->mCoo + i * subset->mDim;
+               for (int itDim = 0 ; itDim < mDim ; itDim++)
+               {
+                       destCoo[itDim] = srcCoo[itDim];
+               }
+               
+               itSet++;
+       }
+       
+       //---------------------------------------------------------------------
+       // Copy subset of identifiers if necessary
+       //---------------------------------------------------------------------
+       if (isIdentifiers())  
+       { 
+               itSet = pSetIndices.begin();
+               subset->mId = new med_int[subset->mNum]; 
+               for (int i = 0 ; i < subset->mNum; i++)
+               {
+                       med_int srcIndex = (*itSet) - 1; // MED index start at 1
+                       subset->mId[i] = mId[srcIndex];
+                       
+                       itSet++;
+               }
+       }
+       
+       //---------------------------------------------------------------------
+       // Copy subset of names if necessary
+       //---------------------------------------------------------------------
+       if (isNames())       
+       { 
+               subset->mNames = new char[MED_TAILLE_PNOM * subset->mNum + 1]; 
+               char* destPtr = subset->mNames;
+               itSet = pSetIndices.begin();
+               for (int i = 0 ; i < subset->mNum; i++)
+               {
+                       med_int srcIndex = (*itSet) - 1; // MED index start at 1
+                       char* srcPtr = mNames + srcIndex * MED_TAILLE_PNOM;
+                       memcpy(destPtr, srcPtr, MED_TAILLE_PNOM);
+                       destPtr += MED_TAILLE_PNOM;
+                       
+                       itSet++;
+               }
+               subset->mNames[MED_TAILLE_PNOM * subset->mNum] = '\0';
+       }
+       
+       return subset;
+}
+
+
+void Nodes::readMED(med_idt pMEDfile, char* pMeshName, med_int pDim)
+{
+       if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
+       if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       if (pDim != 3) throw IllegalArgumentException("", __FILE__, __LINE__);
+       
+       reset();
+       
+       mDim = pDim;
+       mNum = MEDnEntMaa(
+               pMEDfile, 
+               pMeshName, 
+               MED_COOR, 
+               MED_NOEUD, 
+               med_geometrie_element(0), 
+               med_connectivite(0));
+       
+       if (mNum <= 0) throw IOException("", __FILE__, __LINE__);
+       
+       mId           = new med_int[mNum];
+       mFamIdent     = new med_int[mNum];      
+       mNames        = new char[MED_TAILLE_PNOM * mNum + 1];
+       mCoo          = new med_float[mDim * mNum];
+       mNamesCoo     = new char[mDim * MED_TAILLE_PNOM + 1];
+       mNamesUnitCoo = new char[mDim * MED_TAILLE_PNOM + 1];
+       
+       mNames[0] = '\0';
+       mNamesCoo[0] = '\0';
+       mNamesUnitCoo[0] = '\0';
+       
+       med_booleen isIdentifiers;
+       med_booleen isNames;
+       
+       med_err ret = MEDnoeudsLire(
+               pMEDfile, 
+               pMeshName, 
+               mDim,
+               mCoo, 
+               MED_FULL_INTERLACE,
+               &mCoordSystem, 
+               mNamesCoo, 
+               mNamesUnitCoo,
+               mNames, 
+               &isNames, 
+               mId, 
+               &isIdentifiers,
+               mFamIdent,    
+               mNum);
+               
+       if (ret != 0) throw IOException("", __FILE__, __LINE__);
+       
+       // check if coordinates system is CARTESIAN
+       if (mCoordSystem != MED_CART) throw IllegalStateException("", __FILE__, __LINE__);
+       
+       if (!isNames)
+       {
+               delete[] mNames;
+               mNames = NULL;
+       }
+       
+       if (!isIdentifiers)
+       {
+               delete[] mId;
+               mId = NULL;
+       }
+}
+
+
+void Nodes::writeMED(med_idt pMEDfile, char* pMeshName) const
+{
+       if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
+       if (pMeshName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       if (strlen(pMeshName) > MED_TAILLE_NOM) throw IllegalArgumentException("", __FILE__, __LINE__);
+       if ((mDim < 1) || (mDim > 3)) throw IllegalStateException("", __FILE__, __LINE__);
+       if (mFamIdent == NULL) throw IllegalStateException("", __FILE__, __LINE__);
+       if (mCoo == NULL) throw IllegalStateException("", __FILE__, __LINE__);
+       if (mNamesCoo == NULL) throw IllegalStateException("", __FILE__, __LINE__);
+       if (mNamesUnitCoo == NULL) throw IllegalStateException("", __FILE__, __LINE__);
+       
+       // special case: if no nodes => do nothing
+       if (mNum == 0) return;
+       
+       med_err ret = MEDnoeudsEcr(
+               pMEDfile,
+               pMeshName,
+               mDim,
+               mCoo,
+               MED_FULL_INTERLACE,
+               mCoordSystem,
+               mNamesCoo,
+               mNamesUnitCoo,
+               mNames,
+               isNames()?MED_VRAI:MED_FAUX,
+               mId,
+               isIdentifiers()?MED_VRAI:MED_FAUX,
+               mFamIdent,
+               mNum);
+       
+       if (ret != 0) throw IOException("i/o error while writing nodes", __FILE__, __LINE__);
+       
+}
+
+
+ostream& operator<<(ostream& pOs, Nodes& pN)
+{
+       char strCoordSystem[16];
+       switch (pN.mCoordSystem) 
+       {
+               case MED_CART:  strcpy(strCoordSystem, "CARTESIAN"); break;
+               case MED_CYL:   strcpy(strCoordSystem, "CYLINDRIC"); break;
+               case MED_SPHER: strcpy(strCoordSystem, "SPHERIC"); break;
+               default:        strcpy(strCoordSystem, "UNKNOWN"); break;
+       }
+       
+       pOs << "Nodes: " << endl;
+       pOs << "    #number      =" << pN.mNum << endl;
+       pOs << "    Dimension    =" << pN.mDim << endl;
+       pOs << "    Coord. system=" << strCoordSystem << endl;
+       pOs << "    Has names    ?" << (pN.isNames()?"yes":"no") << endl;
+       pOs << "    Has id       ?" << (pN.isIdentifiers()?"yes":"no") << endl;
+       pOs << "    Axis names   =" << "|" << pN.mNamesCoo << "|" << endl;
+       pOs << "    Unit axis    =" << "|" << pN.mNamesUnitCoo << "|" << endl;
+       
+       {
+               set<med_int> setOfFam = pN.getSetOfFamilies();
+               if (setOfFam.size() == 0)
+               {
+                       pOs << "    Families: #fam=0" << endl;
+               }
+               else
+               {
+                       set<med_int>::iterator itFam = setOfFam.end();
+                       itFam--;
+                       pOs << "    Families: #fam=" << setOfFam.size() << " id_min=" << (*(setOfFam.begin())) << " id_max=" << (*itFam) << endl;
+               }
+               
+               if (pN.mFlagPrintAll)
+               {
+                       for (int itNode = 0 ; itNode < pN.mNum; itNode++)
+                       {
+                               pOs << "        Node " << (itNode+1) << ": " << pN.mFamIdent[itNode] << endl;
+                       }
+               }
+       }
+       
+       med_float bboxMin[3], bboxMax[3];
+       pN.getBBox(bboxMin, bboxMax);
+       pOs << "    BBox: [" << bboxMin[0] << " ; " << bboxMax[0] << "] x [" << bboxMin[1] << " ; " << bboxMax[1] << "] x [" << bboxMin[2] << " ; " << bboxMax[2] << "]" << endl; 
+       
+       if (pN.mFlagPrintAll)
+       {
+               pOs << "    Coordinates: " << endl;
+               for (int itNode = 0 ; itNode < pN.mNum ; itNode++)
+               {
+                       pOs << "        Node " << (itNode+1) << ": ";
+                       for (int itDim = 0 ; itDim < pN.mDim ; itDim++)
+                       {
+                               pOs << pN.mCoo[itNode * pN.mDim + itDim] << " ";
+                       }
+                       pOs << endl;
+               }
+               
+               if (pN.isIdentifiers())
+               {
+                       pOs << "    Num: " << endl;
+                       for (int itNode = 0 ; itNode < pN.mNum; itNode++)
+                       {
+                               pOs << "        Node " << (itNode+1) << ": " << pN.mId[itNode] << endl;
+                       }
+               }
+               
+               if (pN.isNames())
+               {
+                       pN.mNames[MED_TAILLE_PNOM * pN.mNum] = '\0';
+                       pOs << "    Names: |" << pN.mNames << "|" << endl;
+               }
+               
+       }
+       
+       return pOs;
+}
+
+
+} // namespace  multipr
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_Nodes.hxx b/src/MULTIPR/MULTIPR_Nodes.hxx
new file mode 100644 (file)
index 0000000..ed39c9d
--- /dev/null
@@ -0,0 +1,190 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_Nodes.hxx
+ *
+ * \brief   Class Nodes = table of nodes.
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#ifndef MULTIPR_NODES_HXX
+#define MULTIPR_NODES_HXX
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+extern "C"
+{
+       #include "med.h"
+}
+
+#include <iostream>
+#include <set>
+
+
+namespace multipr
+{
+
+
+//*****************************************************************************
+// Class Nodes
+//*****************************************************************************
+
+class Nodes
+{
+public:
+
+       /** 
+        * Builds an empty set of nodes (default constructor).
+        */
+       Nodes();
+       
+       /**
+        * Destructor. Removes everything.
+        */
+       ~Nodes();
+       
+       /**
+        * Resets this object in its state by default (empty). Cleans memory.
+        */
+       void reset();
+       
+       //---------------------------------------------------------------------
+       // Basic accessors/mutators
+       //---------------------------------------------------------------------
+       
+       /**
+        * Returns true if nodes have a name.
+        * \return true if nodes have a name.
+        */
+       bool isNames() const { return (mNames != NULL); }
+       
+       /**
+        * Returns true if elements have an identifier (= a number).
+        * \return true if elements have an identifier (= a number).
+        */
+       bool isIdentifiers() const { return (mId != NULL); }
+         
+       /**
+        * Returns the coordinates of one node according to its index.
+        * \param  pIndexNode index of node in [0..NUMBER_OF_NODES-1].
+        * \return the coordinates of one node.
+        * \throw  IndexOutOfBoundsException if pIndexNode is invalid.
+        */
+       const med_float* getCoordinates(med_int pIndexNode) const;
+       
+       /**
+        * Returns the family of one node.
+        * \param  pIndexNode index of node in [0..NUMBER_OF_NODES-1].
+        * \return the family of the given node.
+        * \throw  IndexOutOfBoundsException if pIndexNode is invalid.
+        */
+       med_int getFamIdent(med_int pIndexNode) const;
+       
+       /**
+        * Returns the number of nodes.
+        * \return the number of nodes.
+        */
+       int getNumberOfNodes() const { return mNum; }
+       
+       //---------------------------------------------------------------------
+       // Algorithms
+       //---------------------------------------------------------------------
+       
+       /**
+        * Returns the axis-aligned bounding box (CARTESIAN coordinates system) of this set of nodes.
+        * \param  pMin (out) coordinates of the min-corner of the bbox.
+        * \param  pMin (out) coordinates of the max-corner of the bbox.
+        */
+       void getBBox(med_float pMin[3], med_float pMax[3]) const;
+
+       /**
+        * Returns the set of families referenced by this set of nodes.
+        * Each family is described by its identifier.
+        * \return the set of families referenced by this set of nodes.
+        */
+       std::set<med_int> getSetOfFamilies() const;
+       
+       /**
+        * Constructor. Creates a subset of this set of nodes from a set of indices.
+        * \param  pSetOfIndices set of indices; each index must be >= 1.
+        * \return a subset of this set of nodes from a set of indices.
+        */
+       Nodes* extractSubSet(const std::set<med_int>& pSetIndices) const;
+       
+       //---------------------------------------------------------------------
+       // I/O
+       //---------------------------------------------------------------------
+
+       /**
+        * Reads all nodes of a mesh from a MED file.
+        * \param  pMEDfile   any valid MED file opened for reading.
+        * \param  pMeshName  name of the mesh to be read.
+        * \param  pDim       dimension of the mesh.
+        * \throw  IOException if any i/o error occurs.
+        */
+       void readMED(med_idt pMEDfile, char* pMeshName, med_int pDim);
+       
+       /**
+        * Writes this set of nodes to a MED file. Nodes are associated with the given mesh.
+        * WARNING: mesh must have been created and added to the MED file before.
+        * \param  pMEDfile  any valid MED file opened for writing.
+        * \param  pMeshName any mesh of the MED file. 
+        * \throw  IOException if any i/o error occurs.
+        */
+       void writeMED(med_idt pMEDfile, char* pMeshName) const;
+        
+       /**
+        * Sets the flag which control the stream operator <<.
+        * \param  pFlag new flag value.
+        */
+       void setPrintAll(bool pFlag) { mFlagPrintAll = pFlag; } 
+        
+       /**
+        * Dumps any Nodes to the given output stream.
+        * \param  pOs any output stream.
+        * \param  pN  any Nodes.
+        * \return the output stream pOs.
+        */
+       friend std::ostream& operator<<(std::ostream& pOs, Nodes& pN);
+       
+private:
+       
+       med_int     mNum;            /**< Number of nodes in this set. */
+       med_int     mDim;            /**< Dimension of nodes. */
+       med_repere  mCoordSystem;    /**< Type of coordinates system; should be MED_CART for cartesian. */
+       
+       med_int*    mId;             /**< Optional; for each node, its identifier; NULL if undefined. */
+       med_int*    mFamIdent;       /**< For each node, its identifier of its family. */
+       char*       mNames;          /**< Optional; for each node, its name; NULL if undefined. */
+       med_float*  mCoo;            /**< For each node, coordinates of node; array is interlaced: x1 y1 z1 x2 y2 z2 ...*/
+       char*       mNamesCoo;       /**< Names of axis of the coordinates system. */     
+       char*       mNamesUnitCoo;   /**< Unit of axis of the coordinates system.  */
+       
+       bool        mFlagPrintAll;   /** Flag to control the behaviour of the stream operator <<. */
+       
+private:
+
+       // do not allow copy constructor
+       Nodes(const Nodes&);
+       
+       // do not allow copy
+       Nodes& operator=(const Nodes&);
+       
+       // do not allow operator ==
+       bool operator==(const Nodes&); 
+       
+}; // class Nodes
+
+
+} // namespace MULTIPR
+
+
+#endif // MULTIPR_NODES_HXX
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_Obj.cxx b/src/MULTIPR/MULTIPR_Obj.cxx
new file mode 100644 (file)
index 0000000..99e69f8
--- /dev/null
@@ -0,0 +1,427 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_Obj.cxx
+ *
+ * \brief   see MULTIPR_Obj.hxx
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+#include "MULTIPR_Obj.hxx"
+#include "MULTIPR_Exceptions.hxx"
+#include "MULTIPR_Mesh.hxx"
+#include "MULTIPR_MeshDis.hxx"
+#include "MULTIPR_Utils.hxx"
+
+#include <stdio.h>
+#include <iostream>
+
+using namespace std;
+
+
+namespace multipr
+{
+
+
+//*****************************************************************************
+// Class Obj implementation
+//*****************************************************************************
+
+Obj::Obj() 
+{
+       mMeshDis = NULL;
+       
+       reset(); 
+}
+
+
+Obj::~Obj()  
+{ 
+       reset();  
+}
+
+
+void Obj::reset() 
+{ 
+       mMEDfilename     = "";
+       mMeshName        = "";
+       mState           = MULTIPR_OBJ_STATE_RESET;
+       
+       if (mMeshDis != NULL) { delete mMeshDis; mMeshDis = NULL; }
+}
+
+
+void Obj::create(const char* pMEDfilename)
+{
+       if (pMEDfilename == NULL) throw multipr::NullArgumentException("file name must not be NULL", __FILE__, __LINE__);
+       
+       // reset everything before associating a new MED file to this object
+       reset();
+       
+       mMEDfilename = pMEDfilename;
+       
+       // check if file exists
+       FILE* f = fopen(pMEDfilename, "rb");
+       if (f == 0) 
+       {
+               // file does not exist
+               mState = MULTIPR_OBJ_STATE_ERROR;
+               throw FileNotFoundException("file not found", __FILE__, __LINE__);
+       }
+       fclose(f);
+       
+       // test whether it is a sequential MED file or a distributed MED file
+       med_idt file = MEDouvrir(const_cast<char*>(pMEDfilename), MED_LECTURE); // open sequential MED file for reading
+       if (file > 0)
+       {
+               // sequential MED file has been sucessfuly openened
+               
+               // CASE 1: sequential MED file
+               med_int ret = MEDfermer(file);
+               
+               if (ret != 0) 
+               {
+                       // error while closing sequential MED file
+                       mState = MULTIPR_OBJ_STATE_ERROR;
+                       throw multipr::IOException("i/o error while closing MED file", __FILE__, __LINE__);
+               }
+               
+               mState = MULTIPR_OBJ_STATE_SEQ_INIT;
+               cout << "Sequential MED file " << pMEDfilename << " has been successfuly opened" << endl;
+       }
+       else
+       {
+               // CASE 2: distributed MED file?
+               try
+               {
+                       mMeshDis = new multipr::MeshDis();
+                       mMeshDis->readDistributedMED(pMEDfilename);
+               
+                       mState = MULTIPR_OBJ_STATE_DIS;
+                       cout << "Distributed MED file " << pMEDfilename << " has been successfuly opened" << endl;
+               }
+               catch (...)
+               {
+                       // neither a sequential MED file, nor a distributed MED file => error
+                       mState = MULTIPR_OBJ_STATE_ERROR;
+                       throw IOException("file is nor a sequential MED file, neither a distributed MED file", __FILE__, __LINE__);
+               }
+       }
+}
+
+
+void Obj::setMesh(const char* pMeshName)
+{
+       // setMesh() is only available for sequential MED file (not distributed MED file)
+       if ((mState != MULTIPR_OBJ_STATE_SEQ_INIT) &&
+           (mState != MULTIPR_OBJ_STATE_SEQ)) throw IllegalStateException("expected a sequential MED file", __FILE__, __LINE__);
+       
+       mMeshName = pMeshName;
+       
+       // change state to MULTIPR_OBJ_STATE_SEQ (in case of state=MULTIPR_OBJ_STATE_SEQ_INIT)
+       mState = MULTIPR_OBJ_STATE_SEQ;
+}
+
+
+vector<string> Obj::getMeshes() const
+{
+       // test whether it is a sequential MED file or a distributed MED file
+       if ((mState == MULTIPR_OBJ_STATE_SEQ_INIT) ||
+           (mState == MULTIPR_OBJ_STATE_SEQ))
+       {
+               // CASE 1: sequential MED file
+               return multipr::getListMeshes(mMEDfilename.c_str());
+       }
+       else
+       {
+               // CASE 2: distributed MED file
+               if (mMeshDis == NULL)
+               {
+                       throw IllegalStateException("distributed MED file should not be NULL", __FILE__, __LINE__);
+               }
+               
+               return mMeshDis->getMeshes();
+       }
+}
+
+
+vector<string> Obj::getFields() const
+{
+       // test whether it is a sequential MED file or a distributed MED file
+       if ((mState == MULTIPR_OBJ_STATE_SEQ_INIT) ||
+           (mState == MULTIPR_OBJ_STATE_SEQ)) 
+       {
+               // CASE 1: sequential MED file
+               vector<pair<string, int> > tmp = multipr::getListFields(mMEDfilename.c_str());
+               
+               vector<string> res;
+               for (int i = 0 ; i < tmp.size() ; i++)
+               {
+                       res.push_back(tmp[i].first);
+               }
+               
+               return res;
+       }
+       else
+       {
+               // CASE 2: distributed MED file
+               if (mMeshDis == NULL) throw IllegalStateException("distributed MED file should not be NULL", __FILE__, __LINE__);
+               
+               return mMeshDis->getFields();
+       }
+}
+
+
+int Obj::getTimeStamps(const char* pFieldName) const
+{
+       // test whether it is a sequential MED file or a distributed MED file
+       if ((mState == MULTIPR_OBJ_STATE_SEQ_INIT) ||
+           (mState == MULTIPR_OBJ_STATE_SEQ)) 
+       {
+               // CASE 1: sequential MED file
+               vector<pair<string, int> > tmp = multipr::getListFields(mMEDfilename.c_str());
+       
+               for (int i = 0 ; i < tmp.size() ; i++)
+               {
+                       if (strcmp(tmp[i].first.c_str(), pFieldName) == 0)
+                       {
+                               return tmp[i].second;
+                       }
+               }
+               
+               // pFieldName not found in the list of fields
+               return 0;
+       }
+       else
+       {
+               // CASE 2: distributed MED file
+               if (mMeshDis == NULL) throw IllegalStateException("distributed MED file should not be NULL", __FILE__, __LINE__);
+               
+               return mMeshDis->getTimeStamps(pFieldName);
+       }
+}
+
+
+vector<string> Obj::getParts() const
+{
+       // getParts() is only available for distributed MED file (not sequential MED file)
+       if ((mState != MULTIPR_OBJ_STATE_DIS) &&
+           (mState != MULTIPR_OBJ_STATE_DIS_MEM)) throw IllegalStateException("expected a distributed MED file", __FILE__, __LINE__);
+       
+       return getListParts();
+}
+
+
+string Obj::getPartInfo(const char* pPartName) const
+{
+       // getParts() is only available for distributed MED file (not sequential MED file)
+       if ((mState != MULTIPR_OBJ_STATE_DIS) &&
+           (mState != MULTIPR_OBJ_STATE_DIS_MEM)) throw IllegalStateException("expected a distributed MED file", __FILE__, __LINE__);
+       
+       if (mMeshDis == NULL) throw IllegalStateException("distributed MED file should not be NULL", __FILE__, __LINE__);
+       
+       return mMeshDis->getPartInfo(pPartName);
+       
+}
+
+
+vector<string> Obj::partitionneDomaine()
+{
+       if (mState == MULTIPR_OBJ_STATE_SEQ_INIT) throw IllegalStateException("use setMesh() before", __FILE__, __LINE__);
+       
+       // partitionneDomaine() is only available for sequential MED file (not distributed MED file)
+       if (mState != MULTIPR_OBJ_STATE_SEQ) throw IllegalStateException("unexpected operation", __FILE__, __LINE__);
+       
+       //-------------------------------------------------------------
+       // Read the sequential mesh
+       //-------------------------------------------------------------
+       cout << "Read sequential MED file: " << mMEDfilename << ": please wait... " << endl;
+       
+       Mesh mesh;
+       mesh.readSequentialMED(mMEDfilename.c_str(), mMeshName.c_str());
+       cout << mesh << endl;
+       
+       //-------------------------------------------------------------
+       // Build distributed mesh from groups
+       //-------------------------------------------------------------
+       cout << "Build distributed mesh: please wait... " << endl;
+       try
+       {
+               mMeshDis = mesh.splitGroupsOfElements();
+       }
+       catch (RuntimeException& e)
+       {
+               delete mMeshDis;
+               mMeshDis = NULL;
+               throw e;
+       }
+       
+       mState = MULTIPR_OBJ_STATE_DIS_MEM;
+       
+       return getListParts();
+}
+
+
+vector<string> Obj::partitionneGrain(
+       const char* pPartName, 
+       int         pNbParts, 
+       int         pPartitionner)
+{
+       if (mMeshDis == NULL) throw IllegalStateException("expected a distributed MED file", __FILE__, __LINE__);
+       if (pPartName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       if (pNbParts < 2) throw IllegalArgumentException("", __FILE__, __LINE__);
+       if ((pPartitionner != 0) && (pPartitionner != 1)) throw IllegalArgumentException("partitionner should be 0=METIS or 1=SCOTCH", __FILE__, __LINE__);
+
+       // partitionneGrain() is only available for distributed MED file (not sequential MED file)
+       if ((mState != MULTIPR_OBJ_STATE_DIS_MEM) &&
+           (mState != MULTIPR_OBJ_STATE_DIS)) throw IllegalStateException("unexpected operation", __FILE__, __LINE__);
+       
+       // if distributed MED file is currently in memory, then write to disk before performing partitionneGrain()
+       // (because MEDSPLIITER starts from a file)
+       if (mState == MULTIPR_OBJ_STATE_DIS_MEM)
+       {
+               //-----------------------------------------------------
+               // Write distributed mesh
+               //-----------------------------------------------------
+               cout << "Write distributed mesh: please wait... " << endl;
+               string strPrefix = removeExtension(mMEDfilename.c_str(), ".med");
+               mMeshDis->writeDistributedMED(strPrefix.c_str());
+               
+               mMEDfilename = mMeshDis->getFilename();
+               
+               delete mMeshDis;
+               
+               //---------------------------------------------------------------------
+               // Read the distributed mesh
+               //--------------------------------------------------------------------- 
+               int ret = MEDformatConforme(mMEDfilename.c_str());
+               if (ret == 0) throw IOException("waiting for a distributed MED file (not a sequential one)", __FILE__, __LINE__);
+       
+               mMeshDis = new MeshDis();
+               mMeshDis->readDistributedMED(mMEDfilename.c_str());
+               
+               mState = MULTIPR_OBJ_STATE_DIS;
+       }
+
+       //---------------------------------------------------------------------
+       // Split the given part (pGroupName)
+       //---------------------------------------------------------------------
+       mMeshDis->splitPart(pPartName, pNbParts, pPartitionner);
+       cout << mMeshDis << endl;
+
+       //---------------------------------------------------------------------
+       // Write new distributed mesh
+       //---------------------------------------------------------------------
+       string strPrefix = multipr::removeExtension(mMEDfilename.c_str(), ".med");
+       mMeshDis->writeDistributedMED(strPrefix.c_str());
+       
+       //---------------------------------------------------------------------
+       // Read the distributed mesh
+       //---------------------------------------------------------------------
+       delete mMeshDis;
+       mMeshDis = new MeshDis();
+       //cout << "read dis MED file: filename=" << mMEDfilename << endl;
+       mMeshDis->readDistributedMED(mMEDfilename.c_str());
+       
+       return getListParts();
+}
+
+
+vector<string> Obj::decimePartition(
+       const char* pPartName,
+       const char* pFieldName,
+       int         pFieldIt,
+       const char* pFilterName,
+       double      pTmed,
+       double      pTlow,
+       double      pRadius,
+       int         pBoxing)
+{
+       
+       // decimePartition() is only available for distributed MED file (not sequential MED file)
+       if ((mState != MULTIPR_OBJ_STATE_DIS_MEM) &&
+           (mState != MULTIPR_OBJ_STATE_DIS)) throw IllegalStateException("unexpected operation", __FILE__, __LINE__);
+           
+       if (mMeshDis == NULL) throw IllegalStateException("expected a distributed MED file", __FILE__, __LINE__);
+       
+       //---------------------------------------------------------------------
+       // Decimate
+       //---------------------------------------------------------------------
+       mMeshDis->decimatePart(
+               pPartName, 
+               pFieldName,
+               pFieldIt,
+               pFilterName,
+               pTmed,
+               pTlow,
+               pRadius,
+               pBoxing);
+               
+       mState = MULTIPR_OBJ_STATE_DIS_MEM;
+       
+       return getListParts();
+}
+
+
+vector<string> Obj::getListParts() const
+{
+       if (mMeshDis == NULL) throw IllegalStateException("not a distributed mesh", __FILE__, __LINE__);
+       
+       vector<string> names;
+       
+       int numParts = mMeshDis->getNumParts();
+       for (int i = 0 ; i < numParts ; i++)
+       {
+               names.push_back( mMeshDis->getPart(i)->getPartName() );
+       }
+       
+       return names;
+}
+
+
+void Obj::save()
+{
+       // only save file if it is a distributed MED file currently in memory
+       if (mState == MULTIPR_OBJ_STATE_DIS_MEM)
+       {
+               //-------------------------------------------------------------
+               // Write new distributed mesh
+               //-------------------------------------------------------------
+               string strPrefix = multipr::removeExtension(mMEDfilename.c_str(), ".med");
+               mMeshDis->writeDistributedMED(strPrefix.c_str());               
+               mMEDfilename = mMeshDis->getFilename();
+               
+               cout << "Write MED master file: " << mMEDfilename << ": OK" << endl;
+               
+               //-------------------------------------------------------------
+               // Read the distributed mesh
+               //-------------------------------------------------------------
+               delete mMeshDis;
+               mMeshDis = new MeshDis();
+               mMeshDis->readDistributedMED(mMEDfilename.c_str());
+               
+               mState = MULTIPR_OBJ_STATE_DIS;
+       }
+}
+
+
+ostream& operator<<(ostream& pOs, Obj& pO)
+{
+       pOs << "Obj:" << endl;
+       pOs << "    Name:" << pO.mMEDfilename << endl;
+       
+       return pOs;
+}
+
+
+} // namespace multipr
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_Obj.hxx b/src/MULTIPR/MULTIPR_Obj.hxx
new file mode 100644 (file)
index 0000000..ea1ab55
--- /dev/null
@@ -0,0 +1,249 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_GaussLoc.hxx
+ *
+ * \brief   Class MULTIPR_Obj. 
+ *          This class is used as an interface to implement MULTIPR services in the salome MODULE 
+ *          as described in the spec/design doc.
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#ifndef MULTIPR_OBJ_HXX
+#define MULTIPR_OBJ_HXX
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+
+namespace multipr
+{
+
+class MeshDis;
+
+
+//*****************************************************************************
+// Class Obj
+//*****************************************************************************
+
+enum ObjState
+{
+       MULTIPR_OBJ_STATE_ERROR,
+       MULTIPR_OBJ_STATE_RESET,
+       MULTIPR_OBJ_STATE_SEQ_INIT,
+       MULTIPR_OBJ_STATE_SEQ,
+       MULTIPR_OBJ_STATE_DIS,
+       MULTIPR_OBJ_STATE_DIS_MEM
+}; // enum ObjState
+
+
+class Obj
+{
+public:
+
+       /** 
+        * Builds an empty Gauss reference (default constructor).
+        */
+       Obj();
+       
+       /**
+        * Destructor. Removes everything.
+        */
+       ~Obj();
+       
+       /**
+        * Resets this object in its state by default (empty). Cleans memory.
+        */
+       void reset();
+       
+       /**
+        * Associate a MED file (sequential or distributed) with this object.
+        * This method also:
+        * - reset everything before starting
+        * - determine if the given file is a sequential (SEQ) or a distributed (DIS) MED file
+        * - read the ASCII master file if it is a distributed MED file
+        * - set state
+        */
+       void create(const char* pMEDfilename);
+        
+       //---------------------------------------------------------------------
+       // Basic accessors/mutators
+       //--------------------------------------------------------------------
+       
+       /**
+        * Returns true iff this obj represents a valid sequential MED file.
+        * \return true iff this obj represents a valid sequential MED file.
+        */
+       bool isValidSequentialMEDFile() const { return (mState == MULTIPR_OBJ_STATE_SEQ) || (mState == MULTIPR_OBJ_STATE_SEQ_INIT); }
+       
+       /**
+        * Returns true iff this obj represents a valid distributed MED file.
+        * \return true iff this obj represents a valid distributed  MED file.
+        */
+       bool isValidDistributedMEDFile() const { return (mState == MULTIPR_OBJ_STATE_DIS) || (mState == MULTIPR_OBJ_STATE_DIS_MEM); }
+        
+       /**
+        * Defines the mesh to be processed.
+        * \param  pMeshName name of the mesh to be partitionned.
+        */
+       void setMesh(const char* pMeshName);
+        
+       /**
+        * Returns the list of meshes contained in the sequential MED file.
+        * Assumes this object encapsulates a sequential MED file.
+        * \return the list of meshes contained in the sequential MED file.
+        */
+       std::vector<std::string> getMeshes() const;
+       
+       /**
+        * Returns the list of fields contained in the sequential MED file.
+        * Assumes this object encapsulates a sequential MED file.
+        * \return the list of fields contained in the sequential MED file.
+        */
+       std::vector<std::string> getFields() const;
+       
+       /**
+        * Returns the number of timestamps for a given field.
+        * Assumes this object encapsulates a sequential MED file.
+        * \param  pFieldName name of any field.
+        * \return the number of timestamps for a given field; 0 if field not found.
+        */
+       int getTimeStamps(const char* pFieldName) const;
+       
+       /**
+        * Returns the name of all partitions.
+        * Assumes this object encapsulates a distributed MED file.
+        * \return the name of all partitions.
+        */
+       std::vector<std::string> getParts() const;
+       
+       /**
+        * Returns all information about a part.
+        * \param  pPartName name of the part.
+        * \return all information about a part.
+        */
+       std::string getPartInfo(const char* pPartName) const;
+         
+       //---------------------------------------------------------------------
+       // Algorithms
+       //--------------------------------------------------------------------
+       
+       /**
+        * Creates a distributed MED file (v2.3) by extracting all the groups from the current mesh of the current MED sequential MED file.
+        *         Assumes:
+        *         - the file is in MED format and can be read using MED file v2.3.
+        *         - the file is sequential (not a distributed MED).
+        *         - the file only contains TETRA10 elements (dimension of space and mesh is 3).
+        *         - the file have no profil.
+        * \return the name of each part.
+        * \throw  RuntimeException if any error occurs.
+        */
+       std::vector<std::string> partitionneDomaine();
+       
+       /** 
+        * Creates a distributed MED file (V2.3) by splitting a group of a MED file previously created by partitionneDomaine.
+        *         Assumes:
+        *         - the file is a distributed MED file, previously created by partitionneDomaine()
+        *           (=> each part only contain 1 mesh, TETRA10 elements only)
+        *         - nbPart > 1
+        * \param  pPartName     name of the part to be splitted.
+        * \param  pNbParts      number of parts; must be > 1.
+        * \param  pPartitionner use value 0=MULTIPR_METIS for Metis or 1=MULTIPR_SCOTCH for Scotch.
+        * \return the name of each part.
+        * \throw  RuntimeException if any error occurs.
+        */
+       std::vector<std::string> partitionneGrain(
+               const char* pPartName, 
+               int         pNbParts, 
+               int         pPartitionner=0);
+       
+       /**
+        * Creates 3 resolutions of the given part of a distributed MED file (V2.3).
+        *         Assumes:
+        *         - the file is a distributed MED file, previously created by partitionneDomaine() or partitionneGrain()
+        *           (=> each part only contain 1 mesh, TETRA10 elements only)
+        * \param  pPartName    name of the part to be decimated.
+        * \param  pFieldName   name of the field used for decimation.
+        * \param  pFieldIt     iteration (time step) of the field.
+        * \param  pFilterName  name of the filter to be used.
+        * \param  pTmed        threshold used for medium resolution.
+        * \param  pTlow        threshold used for low resolution; tmed must be less than tlow
+        * \param  pTadius      radius used to determine the neighbourhood.
+        * \param  pBoxing      number of cells along each axis; must be >= 1; e.g. if 100 then acceleration grid will have 100*100*100 = 10**6 cells.
+        * \return the name of each part.
+        * \throw  RuntimeException if any error occurs.
+        */
+       std::vector<std::string> decimePartition(
+               const char* pPartName,
+               const char* pFieldName,
+               int         pFieldIt,
+               const char* pFilterName,
+               double      pTmed,
+               double      pTlow,
+               double      pRadius,
+               int         pBoxing);
+       
+       //---------------------------------------------------------------------
+       // I/O
+       //---------------------------------------------------------------------
+       
+       /**
+        * Saves the associated MED file if necessary.
+        * \throw  IOException if any i/o error occurs.
+        */
+       void save();
+
+       /**
+        * Dumps any Obj to the given output stream.
+        * \param  pOs any output stream.
+        * \param  pO  any Obj.
+        * \return the output stream pOs.
+        */
+       friend std::ostream& operator<<(std::ostream& pOs, Obj& pO);
+       
+private:
+
+       /**
+        * Returns the list of parts contained in the current distributed mesh.
+        * \return the list of parts contained in the current distributed mesh.
+        * \throw  IllegalStateException if the distributed mesh does not still exist.
+        */
+       std::vector<std::string> getListParts() const;
+
+private:
+       
+       std::string  mMEDfilename;     /**< Name of the MED file: sequential or distributed. */
+       std::string  mMeshName;        /**< Mesh to be partitionned. */
+       ObjState     mState;           /**< State of this object. */
+       MeshDis*     mMeshDis;         /**< Distributed mesh. */
+       
+       
+private:
+       
+       // do not allow copy constructor
+       Obj(const Obj&);
+       
+       // do not allow copy
+       Obj& operator=(const Obj&);
+       
+       // do not allow operator ==
+       bool operator==(const Obj&); 
+       
+}; // class Obj
+
+
+} // namespace MULTIPR
+
+
+#endif // MULTIPR_OBJ_HXX
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_PointOfField.hxx b/src/MULTIPR/MULTIPR_PointOfField.hxx
new file mode 100644 (file)
index 0000000..907aab4
--- /dev/null
@@ -0,0 +1,100 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_PointOfField.hxx
+ *
+ * \brief   Class PointOfField used for decimation. PointOfField = a point in a field = coordinates + value.
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#ifndef MULTIPR_POINTOFFIELD_HXX
+#define MULTIPR_POINTOFFIELD_HXX
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+extern "C"
+{
+       #include "med.h"
+}
+
+
+namespace multipr
+{
+
+
+//*****************************************************************************
+// Class PointOfField
+//*****************************************************************************
+
+class PointOfField
+{
+public:
+
+       /** 
+        * Builds an empty set of elements (default constructor).
+        */
+       PointOfField() { reset(); }
+       
+       /**
+        * Constructor.
+        * \param  pX   x-coordinate of the point.
+        * \param  pY   y-coordinate of the point.
+        * \param  pZ   z-coordinate of the point.
+        * \param  pVal value of the field at the given point.
+        */
+       PointOfField(med_float pX, med_float pY, med_float pZ, med_float pVal)
+       {
+               mXYZ[0] = pX;
+               mXYZ[1] = pY;
+               mXYZ[2] = pZ;
+               mVal    = pVal;
+       }
+       
+       /**
+        * Destructor. Removes everything.
+        */
+       ~PointOfField() { reset(); }
+       
+       /**
+        * Resets this object in its state by default (empty).
+        */
+       void reset()
+       {
+               mXYZ[0] = std::numeric_limits<med_float>::quiet_NaN();
+               mXYZ[1] = std::numeric_limits<med_float>::quiet_NaN();
+               mXYZ[2] = std::numeric_limits<med_float>::quiet_NaN();
+               mVal    = std::numeric_limits<med_float>::quiet_NaN();
+       }
+
+       /**
+        * Dumps any PointOfField to the given output stream.
+        * \param  pOs any output stream.
+        * \param  pP  any PointOfField.
+        * \return the output stream pOs.
+        */
+       friend std::ostream& operator<<(std::ostream& pOs, PointOfField& pP)
+       {
+               pOs << "[ " << pP.mXYZ[0] << " ; " << pP.mXYZ[1] << " ; " << pP.mXYZ[2] << "]: " << pP.mVal;
+               return pOs;
+       }
+
+public:
+
+       med_float  mXYZ[3];    /**< 3D-position. */
+       med_float  mVal;       /**< Value of the field on this point. */
+       
+}; // class PointOfField
+
+
+} // namespace multipr
+
+
+#endif // MULTIPR_FIELDPOINT_HXX 
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_Profil.cxx b/src/MULTIPR/MULTIPR_Profil.cxx
new file mode 100644 (file)
index 0000000..89dfea4
--- /dev/null
@@ -0,0 +1,160 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_Profil.cxx
+ *
+ * \brief   see MULTIPR_Profil.hxx
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+#include "MULTIPR_Profil.hxx"
+#include "MULTIPR_Exceptions.hxx"
+
+#include <iostream>
+
+using namespace std;
+
+
+namespace multipr
+{
+
+
+//*****************************************************************************
+// Class Profil implementation
+//*****************************************************************************
+
+Profil::Profil() 
+{
+       reset(); 
+}
+
+
+Profil::~Profil()  
+{ 
+       reset();  
+}
+
+
+void Profil::reset() 
+{ 
+       mName[0] = '\0'; 
+       mTable.clear(); 
+}
+
+
+void Profil::create(const char* pName)
+{
+       if (pName == NULL) throw NullArgumentException("", __FILE__, __LINE__);
+       
+       reset();
+       strcpy(mName, pName);
+}
+
+
+
+const char* Profil::getName() const
+{
+       return mName;
+}
+
+
+med_int Profil::get(med_int pIndex) const 
+{ 
+       if ((pIndex < 0) || (pIndex >= med_int(mTable.size()))) throw IndexOutOfBoundsException("", __FILE__, __LINE__);
+       
+       return mTable[pIndex]; 
+}
+
+
+void Profil::add(med_int pElt) 
+{
+       mTable.push_back(pElt); 
+}
+
+
+void Profil::readMED(med_idt pMEDfile, med_int pIndexProfil)
+{
+       if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
+       if (pIndexProfil < 1) throw IllegalArgumentException("", __FILE__, __LINE__);
+       
+       reset();
+
+       med_int numData;
+       med_err ret = MEDprofilInfo(
+               pMEDfile, 
+               pIndexProfil, 
+               mName, 
+               &numData);
+               
+       if (ret != 0) throw IOException("", __FILE__, __LINE__);
+       
+       med_int* dataTmp = new med_int[numData];
+       
+       ret = MEDprofilLire(
+               pMEDfile, 
+               dataTmp, 
+               mName);
+       
+       if (ret != 0) throw IOException("", __FILE__, __LINE__);
+       
+       for (int itData = 0 ; itData < numData ; itData++)
+       {
+               mTable.push_back(dataTmp[itData]);
+       }
+       
+       delete[] dataTmp;
+}
+
+
+void Profil::writeMED(med_idt pMEDfile)
+{
+       if (pMEDfile == 0) throw IOException("", __FILE__, __LINE__);
+       if (strlen(mName) > MED_TAILLE_NOM) throw IllegalStateException("", __FILE__, __LINE__);
+       if (mTable.size() == 0) throw IllegalStateException("", __FILE__, __LINE__);
+       
+       med_int* dataTmp = new med_int[mTable.size()];
+       for (unsigned itData = 0 ; itData < mTable.size() ; itData++)
+       {
+               dataTmp[itData] = mTable[itData];
+       }
+       
+       med_err ret = MEDprofilEcr(
+               pMEDfile,
+               dataTmp,
+               mTable.size(),
+               mName);
+               
+       if (ret != 0) throw IOException("", __FILE__, __LINE__);
+       
+       delete[] dataTmp;
+}
+
+
+ostream& operator<<(ostream& pOs, Profil& pP)
+{
+       pOs << "Profil:" << endl;
+       pOs << "    Name=|" << pP.mName << "|" << endl;
+       pOs << "    Size=" << pP.mTable.size() << endl;
+       
+       pOs << "    Entities=[";
+       for (unsigned itElt = 0; itElt < pP.mTable.size() ; itElt++)
+       {
+               pOs << pP.mTable[itElt] << " ";
+       }
+       pOs << "]";
+       
+       return pOs;
+}
+
+
+} // namespace  multipr
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_Profil.hxx b/src/MULTIPR/MULTIPR_Profil.hxx
new file mode 100644 (file)
index 0000000..6a12b25
--- /dev/null
@@ -0,0 +1,140 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_Profil.hxx
+ *
+ * \brief   Class Profil used to managed MED profil.
+ *          Profil is just a list of indices related to elements (NODES, CELLS).
+ *          !!! currently not used !!!
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#ifndef MULTIPR_PROFIL_HXX
+#define MULTIPR_PROFIL_HXX
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+extern "C"
+{
+       #include "med.h"
+}
+
+#include <vector>
+
+
+namespace multipr
+{
+
+
+//*****************************************************************************
+// Class Profil
+//*****************************************************************************
+
+class Profil
+{
+public:
+
+       /** 
+        * Builds an empty profil (default constructor).
+        */
+       Profil();
+       
+       /**
+        * Destructor. Removes everything.
+        */
+       ~Profil();
+       
+       /**
+        * Resets this object in its state by default (empty). Cleans memory.
+        */
+       void reset();
+       
+       /**
+        * Creates a profil from its name (reset before).
+        * \param  pName name of the profil to be created.
+        * \throw  NullArgumentException if pName is NULL.
+        */
+       void create(const char* pName);
+       
+       //---------------------------------------------------------------------
+       // Basic accessors/mutators
+       //---------------------------------------------------------------------
+       
+       /**
+        * Returns the name of this profil.
+        * \return the name of this profil.
+        */
+       const char* getName() const;
+       
+       /**
+        * Returns the nth elements of this profil.
+        * \param  pIndex index of the element to get; must be in [0..NUMBER_OF_ELEMENTS-1].
+        * \return the nth elements of this profil.
+        * \throw  IndexOutOfBoundsException if index is invalid.
+        */
+       med_int get(med_int pIndex) const;
+       
+       /**
+        * Adds a new element to this profil.
+        * \param  pElt element to be added; must be >= 1.
+        */
+       void add(med_int pElt);
+       
+       //---------------------------------------------------------------------
+       // I/O
+       //---------------------------------------------------------------------
+       
+       /**
+        * Reads a Profil from a MED file.
+        * \param  pMEDfile     any valid MED file opened for reading.
+        * \param  pIndexProfil index of the profil to be read; must be >= 1.
+        * \throw  IOException  if any i/o error occurs.
+        */
+       void readMED(med_idt pMEDfile, med_int pIndexProfil);
+       
+       /**
+        * Writes this profil to a MED file.
+        * \param  pMEDfile    any valid MED file opened for writing.
+        * \throw  IOException if any i/o error occurs.
+        */
+       void writeMED(med_idt pMEDfile);
+       
+       /**
+        * Dumps any Profil to the given output stream.
+        * \param  pOs any output stream.
+        * \param  pP  any Profil.
+        * \return the output stream pOs.
+        */
+       friend std::ostream& operator<<(std::ostream& pOs, Profil& pP);
+       
+private:
+       
+       char                  mName[MED_TAILLE_NOM + 1];  /**< Name of the profil. */
+       std::vector<med_int>  mTable;                     /**< Table of elements. */
+       
+private:
+
+       // do not allow copy constructor
+       Profil(const Profil&);
+       
+       // do not allow copy
+       Profil& operator=(const Profil&);
+       
+       // do not allow operator ==
+       bool operator==(const Profil&); 
+       
+}; // class Profil
+
+
+} // namespace MULTIPR
+
+
+#endif // MULTIPR_PROFIL_HXX
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_ProgressCallback.hxx b/src/MULTIPR/MULTIPR_ProgressCallback.hxx
new file mode 100644 (file)
index 0000000..f8e0ff6
--- /dev/null
@@ -0,0 +1,82 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_ProgressCallback.hxx
+ *
+ * \brief   Class MULTIPR_ProgressCallback
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#ifndef MULTIPR_PROGRESS_CALLBACK_HXX
+#define MULTIPR_PROGRESS_CALLBACK_HXX
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+
+//*****************************************************************************
+// Class MULTIPR_ProgressCallback
+// Used to provide feedback on the progress of a slow operation.
+//*****************************************************************************
+
+class MULTIPR_ProgressCallback
+{
+public:
+       
+       /**
+        * Builds a new MULTIPR_ProgressCallback (default constructor).
+        */
+       MULTIPR_ProgressCallback() { init(100); }
+       
+       /**
+        * Destructor. Removes everything.
+        */
+       ~MULTIPR_ProgressCallback() { /* do nothing */ }
+       
+       /**
+        * Starts to provide feedback on the progress of a slow operation.
+        * \param  pTaskTitle name of the task to be monitored.
+        * \param  pNumSteps  number of steps in the task.
+        */
+       virtual void start(const char* pTaskTitle, int pNumSteps) = 0;
+
+       /**
+        * Moves on the current amount of progress made.
+        */
+       void moveOn() { mCurrentStep++; float percent = float(mCurrentStep)/float(mTotalSteps)*100.0f; progress(percent); }
+       
+       /**
+        * Termines to provide feedback.
+        */
+       virtual void done() = 0;
+       
+protected:
+       
+       /**
+        * Resets this progress callback.
+        * \param  pNumSteps number of steps in the task to be monitored.
+        */
+       void init(int pNumSteps) { mCurrentStep = 0; mTotalSteps = pNumSteps; }
+       
+       /**
+        * Callback. Called on each progress.
+        * \param  pPercent percent accomplished.
+        */
+       virtual void progress(float pPercent) = 0;
+
+private:
+
+       int mCurrentStep;
+       int mTotalSteps;
+       
+}; // class MULTIPR_ProgressCallback
+
+
+#endif // MULTIPR_PROGRESS_CALLBACK_HXX
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_Utils.cxx b/src/MULTIPR/MULTIPR_Utils.cxx
new file mode 100644 (file)
index 0000000..ad6b01f
--- /dev/null
@@ -0,0 +1,226 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_Utils.cxx
+ *
+ * \brief   see MULTIPR_Utils.hxx
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+#include "MULTIPR_Utils.hxx"
+#include "MULTIPR_Exceptions.hxx"
+
+#include <iostream>
+
+using namespace std;
+
+
+//*****************************************************************************
+// Implementation
+//*****************************************************************************
+
+void multipr::trim(char* pStr, char pChar)
+{
+       int len = strlen(pStr) - 1;
+       int p = len;
+       while (pStr[p] == pChar)
+       {
+               p--;
+       }
+       if (p != len)
+       {
+               pStr[p + 1] = '\0';
+       }
+}
+
+
+string multipr::removeExtension(const char* pFilename, const char* pExtension)
+{
+       string strPrefix(pFilename); 
+       strPrefix.erase(strPrefix.rfind(pExtension), strlen(pExtension));
+       
+       return strPrefix;
+}
+
+
+void multipr::printArray2D(
+       const med_float* pData, 
+       const int        pNumElt,
+       const int        pDimElt,
+       const char*      pPrefix)
+{
+       for (int itElt = 0 ; itElt < pNumElt ; itElt++)
+       {
+               cout << pPrefix << " " << (itElt + 1) << ": ";
+               for (int itDim = 0 ; itDim < pDimElt ; itDim++)
+               {
+                       cout << pData[itElt * pDimElt + itDim] << " ";
+               }
+               cout << endl;
+       }
+}
+
+
+string multipr::realToString(med_float mV)
+{
+       char str[32];
+       sprintf(str, "%lf", mV);
+       trim(str, '0');
+       int len = strlen(str);
+       if (str[len - 1] == '.')
+       {
+               str[len] = '0';
+               str[len + 1] = '\0';
+       }
+       return string(str);
+}
+
+
+vector<string> multipr::getListMeshes(const char* pMEDfilename)
+{
+       if (pMEDfilename == NULL) throw multipr::NullArgumentException("", __FILE__, __LINE__);
+       
+       vector<string> res;
+       med_err ret;
+       
+       //---------------------------------------------------------------------
+       // Open MED file (READ_ONLY)
+       //---------------------------------------------------------------------
+       med_idt file = MEDouvrir(const_cast<char*>(pMEDfilename), MED_LECTURE); // open MED file for reading
+       if (file <= 0) throw multipr::IOException("MED file not found or not a sequential MED file", __FILE__, __LINE__);
+       
+       //---------------------------------------------------------------------
+       // Read name of meshes
+       //---------------------------------------------------------------------
+       med_int nbMeshes = MEDnMaa(file);
+       if (nbMeshes <= 0) throw multipr::IOException("i/o error while reading number of meshes in MED file", __FILE__, __LINE__);      
+       
+       // for each mesh in the file (warning: first mesh is number 1)
+       for (int itMesh = 1 ; itMesh <= nbMeshes ; itMesh++)
+       {
+               char meshName[MED_TAILLE_NOM + 1];
+               
+               int meshDim;
+               med_maillage meshType;
+               char meshDesc[MED_TAILLE_DESC + 1]; 
+               
+               ret = MEDmaaInfo(
+                       file, 
+                       itMesh, 
+                       meshName, 
+                       &meshDim, 
+                       &meshType, 
+                       meshDesc);
+                       
+               if (ret != 0) throw multipr::IOException("i/o error while reading mesh information in MED file", __FILE__, __LINE__);
+               
+               res.push_back(meshName);
+       }
+       
+       //---------------------------------------------------------------------
+       // Close the MED file
+       //---------------------------------------------------------------------
+       ret = MEDfermer(file);
+       if (ret != 0) throw multipr::IOException("i/o error while closing MED file", __FILE__, __LINE__);
+       
+       return res;
+}
+
+
+vector<pair<string,int> > multipr::getListFields(const char* pMEDfilename)
+{
+       if (pMEDfilename == NULL) throw multipr::NullArgumentException("", __FILE__, __LINE__);
+       
+       vector<pair<string, int> > res;
+       med_err ret;
+       
+       //---------------------------------------------------------------------
+       // Open MED file (READ_ONLY)
+       //---------------------------------------------------------------------
+       med_idt file = MEDouvrir(const_cast<char*>(pMEDfilename), MED_LECTURE); // open MED file for reading
+       if (file <= 0) throw multipr::IOException("MED file not found or not a sequential MED file", __FILE__, __LINE__);
+       
+       //---------------------------------------------------------------------
+       // Read number of fields
+       //---------------------------------------------------------------------
+       med_int numFields = MEDnChamp(file, 0);
+       if (numFields <= 0) throw IOException("", __FILE__, __LINE__);
+       
+       //---------------------------------------------------------------------
+       // For each field, read its name
+       //---------------------------------------------------------------------
+       for (int itField = 1 ; itField <= numFields ; itField++)
+       {
+               char           name[MED_TAILLE_NOM + 1];
+               med_type_champ type;
+               
+               med_int numComponents = MEDnChamp(file, itField);
+       
+               if (numComponents < 0) throw IOException("", __FILE__, __LINE__);
+               
+               // collect scalar field only (not vectorial fields)
+               if (numComponents != 1) 
+                       continue;
+               
+               char* strComponent = new char[numComponents * MED_TAILLE_PNOM + 1];
+               char* strUnit      = new char[numComponents * MED_TAILLE_PNOM + 1];
+               
+               strComponent[0] = '\0';
+               strUnit[0] = '\0';
+               
+               med_err ret = MEDchampInfo(
+                       file, 
+                       itField, 
+                       name, 
+                       &(type), 
+                       strComponent, 
+                       strUnit, 
+                       numComponents);
+               
+               if (ret != 0) throw IOException("", __FILE__, __LINE__);
+               
+               delete[] strUnit;
+               delete[] strComponent;
+               
+               med_int numTimeStep = MEDnPasdetemps(
+                       file, 
+                       name, 
+                       MED_NOEUD, 
+                       (med_geometrie_element) 0);
+               
+               if (numTimeStep < 0) throw IOException("", __FILE__, __LINE__);
+               
+               if (numTimeStep == 0)
+               {
+                       numTimeStep = MEDnPasdetemps(
+                               file, 
+                               name, 
+                               MED_MAILLE, 
+                               MED_TETRA10);
+               
+                       if (numTimeStep  < 0) throw IOException("", __FILE__, __LINE__);        
+                       
+               }
+               
+               res.push_back(make_pair(name, numTimeStep));
+       }
+       
+       //---------------------------------------------------------------------
+       // Close the MED file
+       //---------------------------------------------------------------------
+       ret = MEDfermer(file);
+       if (ret != 0) throw multipr::IOException("i/o error while closing MED file", __FILE__, __LINE__);
+       
+       return res;
+}
+
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_Utils.hxx b/src/MULTIPR/MULTIPR_Utils.hxx
new file mode 100644 (file)
index 0000000..01b5a73
--- /dev/null
@@ -0,0 +1,94 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_Utils.hxx
+ *
+ * \brief   Some useful miscellaneous tools.
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#ifndef MULTIPR_UTILS_HXX
+#define MULTIPR_UTILS_HXX
+
+extern "C"
+{
+       #include "med.h"
+}
+
+#include <string>
+#include <vector>
+
+
+namespace multipr
+{
+
+
+/**
+ * Removes all the pChar at the end of the string.
+ * \param  pStr  any valid C string ending with the char '\0'.
+ * \param  pChar any char; SPACE by default.
+ * \return the same string where the ending spaces have been removed.
+ */
+void trim(char* pStr, char pChar=' ');
+
+
+/**
+ * Removes the extension (suffix) of a filename.
+ * Example: removeExtension("agregat100grains_12pas.med", ".med") -> "agregat100grains_12pas"
+ * \param  pPilename  any valid C string ending with the char '\0'.
+ * \param  pExtension any valid C string ending with the char '\0'.
+ * \return the filename without extension.
+ */
+std::string removeExtension(const char* pFilename, const char* pExtension);
+
+
+/**
+ * Prints all the elements of a 2D array.
+ * \param  pData   all the data (should contain pNumberOfElements * pDimOfElements values)
+ * \param  pNumElt number of elements to display.
+ * \param  pDimElt Dimension of elements.
+ * \param  pPrefix string to display before each element.
+ */
+void printArray2D(
+       const med_float* pData, 
+       const int        pNumElt,
+       const int        pDimElt,
+       const char*      pPrefix);
+       
+
+/**
+ * Converts any float value to a string (remove unecessary 0).
+ * \param  mV any float value.
+ */
+std::string realToString(med_float mV);
+
+
+/**
+ * Returns the name of all meshes contained in a sequential MED file.
+ * \param  pMEDfilename name of any valid sequential MED file; must not be NULL.
+ * \return a list of mesh names.
+ * \throw  NullArgumentException if pMEDfilename is NULL.
+ * \throw  IOException if any other error occurs while reading MED file.
+ */
+ std::vector<std::string> getListMeshes(const char* pMEDfilename);
+
+ /**
+ * For each field in a sequential MED file, returns its name and the related number of iterations.
+ * \param  pMEDfilename name of any valid sequential MED file; must not be NULL.
+ * \return a list of (name, #iterations).
+ * \throw  NullArgumentException if pMEDfilename is NULL.
+ * \throw  IOException if any other error occurs while reading MED file.
+ */
+ std::vector<std::pair<std::string, int> > getListFields(const char* pMEDfilename);
+
+} // namespace MULTIPR
+
+
+#endif // MULTIPR_UTILS_HXX
+
+// EOF
diff --git a/src/MULTIPR/MULTIPR_i.cxx b/src/MULTIPR/MULTIPR_i.cxx
new file mode 100644 (file)
index 0000000..e9dd3a2
--- /dev/null
@@ -0,0 +1,485 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_i.cxx
+ *
+ * \brief   see MULTIPR_i.hxx
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+using namespace std;
+
+#include "MULTIPR_i.hxx"
+#include "utilities.h"
+
+#include <string>
+
+#include "MULTIPR_API.hxx"
+#include "MULTIPR_Exceptions.hxx"
+
+
+//*****************************************************************************
+// Class MULTIPR_Gen_i implementation
+//*****************************************************************************
+
+MULTIPR_Gen_i::MULTIPR_Gen_i(
+       CORBA::ORB_ptr orb,
+       PortableServer::POA_ptr poa,
+       PortableServer::ObjectId* contId, 
+       const char* instanceName, 
+       const char* interfaceName) :
+       Engines_Component_i(orb, poa, contId, instanceName, interfaceName)
+{
+       MESSAGE("activate object");
+       _thisObj = this ;
+       _id = _poa->activate_object(_thisObj);
+}
+
+
+MULTIPR_Gen_i::~MULTIPR_Gen_i()
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// High level API
+//-----------------------------------------------------------------------------
+
+char* MULTIPR_Gen_i::getVersion()
+       throw (SALOME::SALOME_Exception)
+{
+       return CORBA::string_dup(multipr::getVersion());
+}
+
+
+void MULTIPR_Gen_i::partitionneDomaine(
+       const char* medFilename, 
+       const char* meshName)
+       throw (SALOME::SALOME_Exception)
+{
+       try
+       {
+               multipr::partitionneDomaine(medFilename, meshName);
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               e.dump(cout);
+               THROW_SALOME_CORBA_EXCEPTION("partitionneDomaine() failed", SALOME::INTERNAL_ERROR);
+       }
+}
+
+
+void MULTIPR_Gen_i::partitionneGrain(
+       const char* medFilename, 
+       const char* partName, 
+       CORBA::Long nbParts, 
+       CORBA::Long partitionner)
+       throw (SALOME::SALOME_Exception)
+{
+       try
+       {
+               multipr::partitionneGrain(
+                       medFilename,
+                       partName,
+                       nbParts,
+                       partitionner);
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               e.dump(cout);
+               THROW_SALOME_CORBA_EXCEPTION("partitionneGrain() failed", SALOME::INTERNAL_ERROR);
+       }
+}
+
+
+void MULTIPR_Gen_i::decimePartition(
+       const char*   medFilename, 
+       const char*   partName, 
+       const char*   fieldName,
+       CORBA::Long   fieldIt,
+       const char*   filterName,
+       CORBA::Double tmed,
+       CORBA::Double tlow,
+       CORBA::Double radius,
+       CORBA::Long   boxing)
+       throw (SALOME::SALOME_Exception)
+{
+       /*
+       // debug
+       cout << "File  : " << medFilename << endl;
+       cout << "Part  : " << partName    << endl;
+       cout << "Field : " << fieldName   << endl;
+       cout << "It    : " << fieldIt     << endl;
+       cout << "Filter: " << filterName  << endl;
+       cout << "Med   : " << tmed        << endl;
+       cout << "Low   : " << tlow        << endl;
+       cout << "Rad   : " << radius      << endl;
+       cout << "Box   : " << boxing      << endl;
+       cout << endl;
+       */
+       
+       try
+       {
+               multipr::decimePartition(
+                       medFilename, 
+                       partName, 
+                       fieldName,
+                       fieldIt,
+                       filterName,
+                       tmed,
+                       tlow,
+                       radius,
+                       boxing);
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               e.dump(cout);
+               THROW_SALOME_CORBA_EXCEPTION("decimePartition() failed", SALOME::INTERNAL_ERROR);
+       }
+}
+
+
+//-----------------------------------------------------------------------------
+// Low level API
+//-----------------------------------------------------------------------------
+
+MULTIPR_ORB::MULTIPR_Obj_ptr MULTIPR_Gen_i::getObject(const char* medFilename)
+       throw (SALOME::SALOME_Exception)
+{
+    MULTIPR_Obj_i* obj = new MULTIPR_Obj_i(medFilename);
+       return obj->POA_MULTIPR_ORB::MULTIPR_Obj::_this();
+}
+
+
+MULTIPR_Obj_i::MULTIPR_Obj_i(const char* medFilename)
+       throw (SALOME::SALOME_Exception)
+{
+       mObj    = new multipr::Obj();
+       mBoxing = 100;
+       
+       try
+       {
+               cout << "Load " << medFilename << endl;
+               mObj->create(medFilename);
+               cout << endl;
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               delete mObj;
+               mObj = NULL;
+               e.dump(cout);
+               THROW_SALOME_CORBA_EXCEPTION("Unable to create object", SALOME::INTERNAL_ERROR);
+       }
+}
+
+
+MULTIPR_Obj_i::~MULTIPR_Obj_i()
+{
+       if (mObj != NULL)
+       {
+               delete mObj;
+               mObj = NULL;
+       }
+}
+
+
+CORBA::Boolean MULTIPR_Obj_i::isValidSequentialMEDFile()
+               throw (SALOME::SALOME_Exception)
+{
+       if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
+       
+       return mObj->isValidSequentialMEDFile();
+}
+
+
+CORBA::Boolean MULTIPR_Obj_i::isValidDistributedMEDFile()
+       throw (SALOME::SALOME_Exception)
+{
+       if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
+       
+       return mObj->isValidDistributedMEDFile();
+}
+
+
+void MULTIPR_Obj_i::setMesh(const char* meshName)
+               throw (SALOME::SALOME_Exception)
+{
+       if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
+       
+       try
+       {
+               mObj->setMesh(meshName);
+               
+               cout << "Set mesh OK" << endl << endl;
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               e.dump(cout);
+               THROW_SALOME_CORBA_EXCEPTION("Unable to set mesh", SALOME::INTERNAL_ERROR);
+       }
+}
+
+
+void MULTIPR_Obj_i::setBoxing(CORBA::Long pBoxing)
+       throw (SALOME::SALOME_Exception)
+{
+       if (mBoxing < 0) THROW_SALOME_CORBA_EXCEPTION("Invalid boxing parameter; should be >= 1", SALOME::INTERNAL_ERROR);
+       if (mBoxing > 200) THROW_SALOME_CORBA_EXCEPTION("Invalid boxing parameter; should be <= 200", SALOME::INTERNAL_ERROR);
+       
+       mBoxing = pBoxing;
+}
+
+
+MULTIPR_ORB::string_array* MULTIPR_Obj_i::getMeshes() 
+       throw (SALOME::SALOME_Exception)
+{
+       if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
+       
+       MULTIPR_ORB::string_array_var mySeq = new MULTIPR_ORB::string_array();
+       
+       try
+       {
+               std::vector<std::string> listMeshes = mObj->getMeshes();
+               mySeq->length(listMeshes.size());
+               
+               for (int i = 0 ; i < listMeshes.size() ; i++)
+        {
+               mySeq[i] = CORBA::string_dup(listMeshes[i].c_str());
+        }
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               e.dump(cout);
+               THROW_SALOME_CORBA_EXCEPTION("Unable to get meshes", SALOME::INTERNAL_ERROR);
+       }
+       
+    return mySeq._retn();
+}
+
+
+MULTIPR_ORB::string_array* MULTIPR_Obj_i::getFields() 
+       throw (SALOME::SALOME_Exception)
+{
+       if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
+       
+       MULTIPR_ORB::string_array_var mySeq = new MULTIPR_ORB::string_array();
+       
+       try
+       {
+               std::vector<std::string> listFields = mObj->getFields();
+               mySeq->length(listFields.size());
+               
+               for (int i = 0 ; i < listFields.size() ; i++)
+        {
+               mySeq[i] = CORBA::string_dup(listFields[i].c_str());
+        }
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               e.dump(cout);
+               THROW_SALOME_CORBA_EXCEPTION("Unable to get fields", SALOME::INTERNAL_ERROR);
+       }
+       
+    return mySeq._retn();
+}
+
+
+CORBA::Long MULTIPR_Obj_i::getTimeStamps(const char* fieldName)
+       throw (SALOME::SALOME_Exception)
+{
+       if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
+       
+       try
+       {
+               return mObj->getTimeStamps(fieldName);
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               e.dump(cout);
+               THROW_SALOME_CORBA_EXCEPTION("Unable to get time stamps", SALOME::INTERNAL_ERROR);
+       }
+}
+
+
+MULTIPR_ORB::string_array* MULTIPR_Obj_i::getParts()
+       throw (SALOME::SALOME_Exception)
+{
+       if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
+       
+       MULTIPR_ORB::string_array_var mySeq = new MULTIPR_ORB::string_array();
+       
+       try
+       {
+               std::vector<std::string> listParts = mObj->getParts();
+               mySeq->length(listParts.size());
+               
+               for (int i = 0 ; i < listParts.size() ; i++)
+        {
+               mySeq[i] = CORBA::string_dup(listParts[i].c_str());
+        }
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               e.dump(cout);
+               THROW_SALOME_CORBA_EXCEPTION("Unable to get parts", SALOME::INTERNAL_ERROR);
+       }
+       
+    return mySeq._retn();
+}
+
+
+char* MULTIPR_Obj_i::getPartInfo(const char* pPartName)
+               throw (SALOME::SALOME_Exception)
+{
+       if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
+       
+       return CORBA::string_dup(mObj->getPartInfo(pPartName).c_str());
+}
+
+
+MULTIPR_ORB::string_array* MULTIPR_Obj_i::partitionneDomaine()
+       throw (SALOME::SALOME_Exception)
+{
+       if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
+       
+       MULTIPR_ORB::string_array_var mySeq = new MULTIPR_ORB::string_array();
+       
+       try
+       {
+               std::vector<std::string> listParts = mObj->partitionneDomaine();
+               mySeq->length(listParts.size());
+               
+               for (int i = 0 ; i < listParts.size() ; i++)
+        {
+               mySeq[i] = CORBA::string_dup(listParts[i].c_str());
+        }
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               e.dump(cout);
+               THROW_SALOME_CORBA_EXCEPTION("Unable to partition mesh", SALOME::INTERNAL_ERROR);
+       }
+       
+    return mySeq._retn();
+}
+
+
+MULTIPR_ORB::string_array* MULTIPR_Obj_i::partitionneGrain(
+               const char* pPartName, 
+               CORBA::Long pNbParts, 
+               CORBA::Long pPartitionner)
+               throw (SALOME::SALOME_Exception)
+{
+       if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
+       
+       MULTIPR_ORB::string_array_var mySeq = new MULTIPR_ORB::string_array();
+       
+       try
+       {
+               std::vector<std::string> listParts = mObj->partitionneGrain(
+                       pPartName,
+                       pNbParts,
+                       pPartitionner);
+                       
+               mySeq->length(listParts.size());
+               
+               for (int i = 0 ; i < listParts.size() ; i++)
+        {
+               mySeq[i] = CORBA::string_dup(listParts[i].c_str());
+        }
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               e.dump(cout);
+               THROW_SALOME_CORBA_EXCEPTION("Unable to partition group", SALOME::INTERNAL_ERROR);
+       }
+       
+    return mySeq._retn();
+}
+
+
+MULTIPR_ORB::string_array* MULTIPR_Obj_i::decimePartition(
+               const char*   pPartName,
+               const char*   pFieldName,
+               CORBA::Long   pFieldIt,
+               const char*   pFilterName,
+               CORBA::Double pTmed,
+               CORBA::Double pTlow,
+               CORBA::Double pRadius)
+               throw (SALOME::SALOME_Exception)
+{
+       if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
+       
+       MULTIPR_ORB::string_array_var mySeq = new MULTIPR_ORB::string_array();
+       
+       try
+       {
+               std::vector<std::string> listParts = mObj->decimePartition(
+                       pPartName,
+                       pFieldName,
+                       pFieldIt,
+                       pFilterName,
+                       pTmed,
+                       pTlow,
+                       pRadius,
+                       mBoxing);
+               
+               mySeq->length(listParts.size());
+               
+               for (int i = 0 ; i < listParts.size() ; i++)
+        {
+               mySeq[i] = CORBA::string_dup(listParts[i].c_str());
+        }
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               e.dump(cout);
+               THROW_SALOME_CORBA_EXCEPTION("Unable to decimate", SALOME::INTERNAL_ERROR);
+       }
+       
+       return mySeq._retn();
+}
+
+
+void MULTIPR_Obj_i::save()
+       throw (SALOME::SALOME_Exception)
+{
+       if (mObj == NULL) THROW_SALOME_CORBA_EXCEPTION("No associated MED file", SALOME::INTERNAL_ERROR);
+       
+       try
+       {
+               mObj->save();
+               
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               e.dump(cout);
+               THROW_SALOME_CORBA_EXCEPTION("Unable to save MED file", SALOME::INTERNAL_ERROR);
+       }
+}
+
+
+extern "C"
+{
+       PortableServer::ObjectId* MULTIPREngine_factory(
+               CORBA::ORB_ptr orb,
+               PortableServer::POA_ptr poa, 
+               PortableServer::ObjectId * contId,
+               const char* instanceName, 
+               const char* interfaceName)
+       {
+               MESSAGE("PortableServer::ObjectId* MULTIPREngine_factory()");
+               SCRUTE(interfaceName);
+               MULTIPR_Gen_i* myMULTIPR = new MULTIPR_Gen_i(orb, poa, contId, instanceName, interfaceName);
+               return myMULTIPR->getId();
+       }
+}
diff --git a/src/MULTIPR/MULTIPR_i.hxx b/src/MULTIPR/MULTIPR_i.hxx
new file mode 100644 (file)
index 0000000..73bd6cf
--- /dev/null
@@ -0,0 +1,273 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_i.hxx
+ *
+ * \brief   C++ implementation of the CORBA interface of the MULTIPR module.
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+  
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+#ifndef __MULTIPR_IMPLEMENTATION_CORBA__
+#define __MULTIPR_IMPLEMENTATION_CORBA__
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(MULTIPR)
+#include "SALOME_Component_i.hxx"
+#include "Utils_CorbaException.hxx"
+
+#include "MULTIPR_Obj.hxx"
+
+
+//*****************************************************************************
+// Class MULTIPR_Obj_i
+// C++ implementation of the MULTIPR_Obj CORBA interface
+// This class is a wrapper to encapsulate MULTIPR_Obj
+//*****************************************************************************
+
+class MULTIPR_Obj_i :
+       public POA_MULTIPR_ORB::MULTIPR_Obj
+{
+
+public:
+
+       /**
+        * Constructor.
+        * Associate a MED file (sequential or distributed) with this object.
+        * \param  pMEDFilename MED file to be associated with this object.
+        */
+    MULTIPR_Obj_i(const char* pMEDFilename)
+               throw (SALOME::SALOME_Exception);
+           
+       /**
+        * Destructor.
+        */
+    virtual ~MULTIPR_Obj_i();
+       
+       //---------------------------------------------------------------------
+       // Basic accessors/mutators
+       //--------------------------------------------------------------------
+       
+       /**
+        * Returns true iff this obj represents a valid sequential MED file.
+        * \return true iff this obj represents a valid sequential MED file.
+        */
+       CORBA::Boolean isValidSequentialMEDFile()
+               throw (SALOME::SALOME_Exception);
+       
+       /**
+        * Returns true iff this obj represents a valid distributed MED file.
+        * \return true iff this obj represents a valid distributed  MED file.
+        */
+       CORBA::Boolean isValidDistributedMEDFile()
+               throw (SALOME::SALOME_Exception);
+       
+       /**
+        * Defines the mesh to be processed.
+        * \param  pMeshName name of the mesh to be partitionned.
+        */
+       void setMesh(const char* pMeshName)
+               throw (SALOME::SALOME_Exception);
+       
+       /**
+        * Sets boxing parameters for decimation (100 by default).
+        * \param  pBoxing number of cells along each axis of the grid (= acceleration structure) ; should be in [1..200].
+        */
+       void setBoxing(CORBA::Long pBoxing)
+               throw (SALOME::SALOME_Exception);
+
+       /**
+        * Returns the list of meshes contained in the sequential MED file.
+        * Assumes this object encapsulates a sequential MED file.
+        * \return the list of meshes contained in the sequential MED file.
+        */
+       MULTIPR_ORB::string_array* getMeshes() 
+               throw (SALOME::SALOME_Exception);
+
+       /**
+        * Returns the list of fields contained in the sequential MED file.
+        * Assumes this object encapsulates a sequential MED file.
+        * \return the list of fields contained in the sequential MED file.
+        */
+       MULTIPR_ORB::string_array* getFields() 
+               throw (SALOME::SALOME_Exception);
+       
+       /**
+        * Returns the number of timestamps for a given field.
+        * Assumes this object encapsulates a sequential MED file.
+        * \param  pFieldName name of any field.
+        * \return the number of timestamps for a given field; 0 if field not found.
+        */
+       CORBA::Long getTimeStamps(const char* pFieldName)
+               throw (SALOME::SALOME_Exception);
+       
+       /**
+        * Returns the name of all partitions.
+        * Assumes this object encapsulates a distributed MED file.
+        * \return the name of all partitions.
+        */
+       MULTIPR_ORB::string_array* getParts()
+               throw (SALOME::SALOME_Exception);
+
+       /**
+        * Returns all information abour a part.
+        * Assumes this object encapsulates a distributed MED file.
+        * \param  pPartName name of the part.
+        * \return information about a part.
+        */
+       char* getPartInfo(const char* pPartName)
+               throw (SALOME::SALOME_Exception);
+
+       //---------------------------------------------------------------------
+       // Algorithms
+       //---------------------------------------------------------------------
+       
+       /**
+        * Creates a distributed MED file (v2.3) by extracting all the groups from the current mesh of the current MED sequential MED file.
+        *         Assumes:
+        *         - the file is in MED format and can be read using MED file v2.3.
+        *         - the file is sequential (not a distributed MED).
+        *         - the file only contains TETRA10 elements (dimension of space and mesh is 3).
+        *         - the file have no profil.
+        * \return the name of each part.
+        */
+       MULTIPR_ORB::string_array* partitionneDomaine()
+               throw (SALOME::SALOME_Exception);
+       
+       /** 
+        * Creates a distributed MED file (V2.3) by splitting a group of a MED file previously created by partitionneDomaine.
+        *         Assumes:
+        *         - the file is a distributed MED file, previously created by partitionneDomaine()
+        *           (=> each part only contain 1 mesh, TETRA10 elements only)
+        *         - nbPart > 1
+        * \param  pPartName     name of the part to be splitted.
+        * \param  pNbParts      number of parts; must be > 1.
+        * \param  pPartitionner use value 0=MULTIPR_METIS for Metis or 1=MULTIPR_SCOTCH for Scotch.
+        * \return the name of each part.
+        */
+       MULTIPR_ORB::string_array* partitionneGrain(
+               const char* pPartName, 
+               CORBA::Long pNbParts, 
+               CORBA::Long pPartitionner)
+               throw (SALOME::SALOME_Exception);
+       
+       /**
+        * Creates 3 resolutions of the given part of a distributed MED file (V2.3).
+        *         Assumes:
+        *         - the file is a distributed MED file, previously created by partitionneDomaine() or partitionneGrain()
+        *           (=> each part only contain 1 mesh, TETRA10 elements only)
+        * \param  pPartName    name of the part to be decimated.
+        * \param  pFieldName   name of the field used for decimation.
+        * \param  pFieldIt     iteration (time step) of the field.
+        * \param  pFilterName  name of the filter to be used.
+        * \param  pTmed        threshold used for medium resolution.
+        * \param  pTlow        threshold used for low resolution; tmed must be less than tlow
+        * \param  pTadius      radius used to determine the neighbourhood.
+        * \return the name of each part.
+        */
+       MULTIPR_ORB::string_array* decimePartition(
+               const char*   pPartName,
+               const char*   pFieldName,
+               CORBA::Long   pFieldIt,
+               const char*   pFilterName,
+               CORBA::Double pTmed,
+               CORBA::Double pTlow,
+               CORBA::Double pRadius)
+               throw (SALOME::SALOME_Exception);
+
+       //---------------------------------------------------------------------
+       // I/O
+       //---------------------------------------------------------------------
+       
+       /**
+        * Saves the associated MED file if necessary.
+        */
+       void save()
+               throw (SALOME::SALOME_Exception);
+       
+private:
+
+       /**
+        * The associated MULTIPR object.
+        */
+       multipr::Obj* mObj;
+       
+       /**
+        * Boxing paremeter: number of cells along each axis.
+        * E.g. if mBoxing=10 then total number of cells = 10*10*10 = 1000.
+        * By default, mBoxing=100.
+        */
+       int mBoxing;
+       
+};
+
+
+//*****************************************************************************
+// Class MULTIPR_Gen_i
+// C++ implementation of the MULTIPR_Gen CORBA interface
+//*****************************************************************************
+
+class MULTIPR_Gen_i :
+       public POA_MULTIPR_ORB::MULTIPR_Gen,
+       public Engines_Component_i 
+{
+
+public:
+
+       MULTIPR_Gen_i(
+               CORBA::ORB_ptr orb,
+               PortableServer::POA_ptr poa,
+               PortableServer::ObjectId* contId, 
+               const char* instanceName, 
+               const char* interfaceName);
+       
+       virtual ~MULTIPR_Gen_i();
+       
+       char* getVersion()
+               throw (SALOME::SALOME_Exception);
+       
+       void partitionneDomaine(
+               const char* medFilename, 
+               const char* meshName)
+               throw (SALOME::SALOME_Exception);
+       
+       void partitionneGrain(
+               const char* medFilename, 
+               const char* partName, 
+               CORBA::Long nbParts, 
+               CORBA::Long partitionner)
+               throw (SALOME::SALOME_Exception);
+       
+       void decimePartition(
+               const char*   medFilename, 
+               const char*   partName, 
+               const char*   fieldName,
+               CORBA::Long   fieldIt,
+               const char*   filterName,
+               CORBA::Double tmed,
+               CORBA::Double tlow,
+               CORBA::Double radius,
+               CORBA::Long   boxing)
+               throw (SALOME::SALOME_Exception);
+       MULTIPR_ORB::MULTIPR_Obj_ptr getObject(const char* medFilename)
+               throw (SALOME::SALOME_Exception);
+};
+
+
+extern "C" PortableServer::ObjectId* MULTIPREngine_factory(
+       CORBA::ORB_ptr orb,
+       PortableServer::POA_ptr poa,
+       PortableServer::ObjectId * contId,
+       const char* instanceName,
+       const char* interfaceName);
+
+#endif // __MULTIPR_IMPLEMENTATION_CORBA__
diff --git a/src/MULTIPR/Makefile.in b/src/MULTIPR/Makefile.in
new file mode 100644 (file)
index 0000000..5599f79
--- /dev/null
@@ -0,0 +1,56 @@
+#  Copyright (C) 2005  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
+#
+
+# Source path
+
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@:@top_srcdir@/idl
+
+MACHINE=PCLINUX
+
+@COMMENCE@
+
+# Libraries targets
+
+LIB = libMULTIPREngine.la
+LIB_SRC = MULTIPR_i.cxx MULTIPR_API.cxx MULTIPR_Mesh.cxx MULTIPR_Profil.cxx MULTIPR_GaussLoc.cxx MULTIPR_Field.cxx MULTIPR_Nodes.cxx MULTIPR_Elements.cxx MULTIPR_Family.cxx MULTIPR_MeshDis.cxx MULTIPR_DecimationFilter.cxx MULTIPR_DecimationAccel.cxx MULTIPR_Utils.cxx MULTIPR_Obj.cxx
+LIB_SERVER_IDL = MULTIPR.idl 
+LIB_CLIENT_IDL = SALOME_Component.idl SALOME_Exception.idl SALOMEDS.idl SALOME_GenericObj.idl Logger.idl 
+
+EXPORT_HEADERS = MULTIPR_API.hxx MULTIPR_DecimationAccel.hxx MULTIPR_DecimationFilter.hxx MULTIPR_Elements.hxx MULTIPR_Exceptions.hxx MULTIPR_Family.hxx MULTIPR_Field.hxx MULTIPR_GaussLoc.hxx MULTIPR_Globals.hxx MULTIPR_MeshDis.hxx MULTIPR_Mesh.hxx MULTIPR_Nodes.hxx MULTIPR_PointOfField.hxx MULTIPR_Profil.hxx MULTIPR_Utils.hxx MULTIPR_Obj.hxx MULTIPR_ProgressCallback.hxx
+
+BIN = multipr
+BIN_SRC = 
+
+# additionnal information to compile and link file
+
+CPPFLAGS += $(KERNEL_CXXFLAGS) -Wno-deprecated -Wparentheses -Wreturn-type -pthread $(MED2_INCLUDES) $(HDF5_INCLUDES) -I$(MED_ROOT_DIR)/include/salome
+
+CPPFLAGSFORBIN=$(CPPFLAGS)
+
+LDFLAGS += $(KERNEL_LDFLAGS) -lSalomeContainer -lOpUtil -lm -lmed -lmedsplitter -lmedmem -lhdf5 -lmed_V2_1 -lSALOMELocalTrace $(MED2_LIBS) $(HDF5_LIBS) -L$(MED_ROOT_DIR)/lib/salome 
+
+LDFLAGSFORBIN=$(LDFLAGS)
+# Executables targets
+
+@CONCLUDE@
+
diff --git a/src/MULTIPR/multipr.cxx b/src/MULTIPR/multipr.cxx
new file mode 100644 (file)
index 0000000..ccdedb7
--- /dev/null
@@ -0,0 +1,703 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    multipr.cxx
+ *
+ * \brief   Standalone command line application of the MULTIPR component.
+ *          The application aims to reduce large data set to allow interactive visualization.
+ *          Its two main function are the following:
+ *          1. Splits any TETRA10 mesh contained in a MED file.
+ *             a. Builds a distributed MED file by extracting all the groups from a sequential MED file.
+ *             b. Splits a part of distributed MED file.
+ *          2. Decimates fields to produce multi-resolution data set.
+ *
+ *          Return 0 if application succeed, 1 otherwise (failure).
+ *
+ *          See http://www.salome-platform.org to learn more about Salome or MED.
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#include "MULTIPR_API.hxx"
+#include "MULTIPR_Obj.hxx"
+#include "MULTIPR_Mesh.hxx"
+#include "MULTIPR_Exceptions.hxx"
+#include "MULTIPR_Utils.hxx"
+
+#include <iostream>
+#include <vector>
+#include <string>
+
+using namespace std;
+
+
+// This command line application can use 2 differents API to do the same work.
+// If MULTIPR_USE_OBJ_API is defined then this command line application used the MULTIPR_Obj API;
+// otherwise, it uses the MULTIPR_API
+//#define MULTIPR_USE_OBJ_API
+
+
+const int MULTIPR_APP_OK     = 0;
+const int MULTIPR_APP_FAILED = 1;
+
+
+/**
+ * Enumerates all the usages of this application.
+ */
+enum Usage
+{
+       MULTIPR_USAGE_UNKNOWN,
+       MULTIPR_USAGE_DISPLAY_HELP,
+       MULTIPR_USAGE_AUTOTEST,
+       MULTIPR_USAGE_PARTITION1,
+       MULTIPR_USAGE_PARTITION2,
+       MULTIPR_USAGE_DECIMATION,
+       MULTIPR_USAGE_INFO
+};
+
+
+/**
+ * Enumerates all the possible errors.
+ */
+enum Error
+{
+       MULTIPR_APP_NO_ERROR,
+       MULTIPR_APP_UNKNOWN_USAGE,
+       MULTIPR_APP_WRONG_NUMBER_OF_ARGUMENTS,
+       MULTIPR_APP_ILLEGAL_ARGUMENT,
+       MULTIPR_APP_FILE_NOT_FOUND,
+       MULTIPR_APP_IO_ERROR,
+       MULTIPR_APP_UNDEFINED_ERROR
+};
+
+
+// global variables used to configure the application
+int   g_usage               = 0; 
+int   g_errorCode           = MULTIPR_APP_NO_ERROR;
+char* g_medFilename         = NULL;
+char* g_meshName            = NULL;
+char* g_partName            = NULL;
+int   g_nbParts             = 0;
+char* g_filterName          = NULL;
+char* g_fieldName           = NULL;
+int   g_fieldTimeStepIt     = 0;
+float g_decimThresholdMed   = 0.0f;
+float g_decimThresholdLow   = 0.0f;
+float g_decimRadius         = 0.0f;
+int   g_boxing              = 100;
+
+
+/**
+ * \fn     const char* getUsage(int usage)
+ * \brief  returns a string describing the usage of this application.
+ */
+const char* getUsage(int usage)
+{
+       switch(usage)
+       {
+               case MULTIPR_USAGE_DISPLAY_HELP:
+                       return "--help: display help";
+                       
+               case MULTIPR_USAGE_AUTOTEST:
+                       return "--auto: unit tests";
+
+               case MULTIPR_USAGE_PARTITION1:
+                       return "--part1: extract all groups of a sequential MED file";
+
+               case MULTIPR_USAGE_PARTITION2:
+                       return "--part2: split a part of a distributed MED file";
+
+               case MULTIPR_USAGE_DECIMATION:
+                       return "--decim: generated level of details of a part of a distributed MED file";
+                       
+               case MULTIPR_USAGE_INFO:
+                       return "--info: prints all infos about a mesh in a sequential MED file";
+
+               default:
+                       return "unknown";
+       }
+}
+
+
+/**
+ * \fn     void printDescription()
+ * \brief  prints a short description of this application.
+ */
+void printDescription()
+{
+       cout << "Keywords:" << endl;          
+       cout << "    Post-processing numerical simulation, Salome platform, " << endl;
+       cout << "    Large data set visualization, 3D meshes and fields" << endl;
+       cout << "Description:" << endl;
+       cout << "    multipr is a partitionning/decimation tool of MED files." << endl;
+       cout << "    See http://www.salome-platform.org for information about MED or Salome." << endl;
+       cout << "    Note: current version only accept TETRA10 meshes." << endl;
+}
+
+
+/**
+ * \fn     void printUsage()
+ * \brief  prints "how to use" manual of this tools.2NbPart
+ */
+void printUsage()
+{
+       cout << "Usages:" << endl;
+       cout << "    --auto   Autotest: performs some unit tests on the MULTIPR API" << endl;
+       cout << "                 * Usage: --auto path (path where to find test file \"agregat100grains_12pas.med\")" << endl;
+       cout << "    --part1  Extracts all groups from a sequential MED file (V2.2 or higher)" << endl;
+       cout << "                 * Usage: --part1 file.med meshName" << endl; 
+       cout << "    --part2  Split a group of a distributed MED file (V2.3) produced with --part1" << endl;
+       cout << "                 * Usage: --part2 file.med partName nbParts" << endl;
+       cout << "    --decim  Generates 3 level of details (full, medium and low) of a part" << endl;
+       cout << "             of a distributed MED file (V2.3)" << endl;     
+       cout << "                 * Usage: --decim file.med partName fieldName fieldIt filterName [...]" << endl;
+       cout << "                 * Only one filter is currently available: Filtre_GradientMoyen" << endl;
+       cout << "                 * Usage: --decim file.med partName fieldName fieldIt Filtre_GradientMoyen m l radius" << endl;
+       cout << "                   where m=threshold for medium res. and l=threshold for low res.; assume m < l" << endl;
+       cout << "    --info   Dumps all infos related to a mesh in a sequential MED file" << endl;
+       cout << "                 * Usage: --info file.med [meshName]" << endl;
+       cout << "    --help   Displays this help page" << endl;
+       cout << endl;
+}
+
+
+/**
+ * \fn     void printGlobals()
+ * \brief  print current state of all global variables.
+ */
+void printGlobals()
+{
+       cout << endl;
+       cout << "********************************************************************************" << endl;
+       cout << "CONFIGURATION" << endl;
+       cout << "--------------------------------------------------------------------------------" << endl;
+       cout << "Mode                        : " << getUsage(g_usage) << endl;
+       cout << "Med filename                : " << ((g_medFilename != NULL) ? g_medFilename : "UNDEFINED") << endl;
+       cout << "Mesh name                   : " << ((g_meshName != NULL) ? g_meshName : "UNDEFINED") << endl;
+       cout << "Part name                   : " << ((g_partName != NULL) ? g_partName : "UNDEFINED") << endl;
+       cout << "Nb parts                    : "  << g_nbParts << endl;
+       cout << "Decimation:" << endl;
+       cout << "    Field name              : " << ((g_fieldName != NULL) ? g_fieldName : "UNDEFINED") << endl;
+       cout << "    Time step iteration     : " << g_fieldTimeStepIt << endl;
+       cout << "    Filter name             : " << ((g_filterName != NULL) ? g_filterName : "UNDEFINED") << endl;
+       cout << "    Threshold for med. res. : " << g_decimThresholdMed << endl;
+       cout << "    Threshold for low res.  : " << g_decimThresholdLow << endl;
+       cout << "    Radius                  : " << g_decimRadius << endl;
+       cout << "    Boxing                  : " << g_boxing << endl;
+       cout << "********************************************************************************" << endl;
+       cout << endl;
+}
+
+
+/**
+ * \fn     const char* getErrorMsg()
+ * \brief  returns the error message corresponding to current error code.
+ * \return the current error message.
+ */
+const char* getErrorMsg()
+{
+       switch (g_errorCode)
+       {
+               case MULTIPR_APP_NO_ERROR:
+                       return "no error";
+               
+               case MULTIPR_APP_UNKNOWN_USAGE:
+                       return "unknown usage";
+                       
+               case MULTIPR_APP_WRONG_NUMBER_OF_ARGUMENTS:
+                       return "wrong number of arguments";
+               
+               case MULTIPR_APP_ILLEGAL_ARGUMENT:
+                       return "illegal argument";
+               
+               case MULTIPR_APP_FILE_NOT_FOUND:
+                       return "file not found";
+                       
+               case MULTIPR_APP_IO_ERROR:
+                       return "i/o error";
+                       
+               default:
+                       return "error (undefined)";
+       }
+}
+
+
+/**
+ * \fn     void parseCommandLine(int argc, char** argv)
+ * \brief  parses the command line and configure this application.
+ * \param  argc number of arguments.
+ * \param  argv array of arguments.
+ */
+void parseCommandLine(int argc, char** argv)
+{
+       if (argc == 1)
+       {
+               g_usage = MULTIPR_USAGE_UNKNOWN; 
+               return;
+       }
+       
+       if (strcmp(argv[1],"--help") == 0)
+       {
+               g_usage = MULTIPR_USAGE_DISPLAY_HELP;
+       }
+       else if (strcmp(argv[1],"--auto") == 0)
+       {
+               if (argc != 3)
+               {
+                       g_usage = MULTIPR_USAGE_UNKNOWN; 
+                       g_errorCode = MULTIPR_APP_WRONG_NUMBER_OF_ARGUMENTS;
+               }
+               else
+               {
+                       g_usage = MULTIPR_USAGE_AUTOTEST;
+                       g_medFilename = argv[2];
+               }
+       }
+       else if (strcmp(argv[1],"--part1") == 0)
+       {
+               if (argc != 4)
+               {
+                       g_usage = MULTIPR_USAGE_UNKNOWN; 
+                       g_errorCode = MULTIPR_APP_WRONG_NUMBER_OF_ARGUMENTS;
+               }
+               else
+               {
+                       g_usage       = MULTIPR_USAGE_PARTITION1;
+                       g_medFilename = argv[2];
+                       g_meshName    = argv[3];
+               }
+       }
+       else if (strcmp(argv[1],"--part2") == 0)
+       {
+               if (argc != 5)
+               {
+                       g_usage = MULTIPR_USAGE_UNKNOWN; 
+                       g_errorCode = MULTIPR_APP_WRONG_NUMBER_OF_ARGUMENTS;
+               }
+               else
+               {
+                       g_usage       = MULTIPR_USAGE_PARTITION2; 
+                       g_medFilename = argv[2];
+                       g_partName    = argv[3];
+                       g_nbParts     = atoi(argv[4]);
+               }
+       }
+       else if (strcmp(argv[1],"--decim") == 0)
+       {
+               if ((argc != 10) && (argc != 11))
+               {
+                       g_usage = MULTIPR_USAGE_UNKNOWN; 
+                       g_errorCode = MULTIPR_APP_WRONG_NUMBER_OF_ARGUMENTS;
+               }
+               else
+               {
+                       g_usage               = MULTIPR_USAGE_DECIMATION; 
+                       g_medFilename         = argv[2];
+                       g_partName            = argv[3];
+                       g_fieldName           = argv[4];
+                       g_fieldTimeStepIt     = atoi(argv[5]);
+                       g_filterName          = argv[6];
+                       g_decimThresholdMed   = atof(argv[7]);
+                       g_decimThresholdLow   = atof(argv[8]);
+                       g_decimRadius         = atof(argv[9]);
+                       
+                       if (argc == 11)
+                       {
+                               g_boxing      = atoi(argv[10]);
+                       }
+               }
+       }
+       else if (strcmp(argv[1],"--info") == 0)
+       {
+               if ((argc != 3) && (argc != 4))
+               {
+                       g_usage = MULTIPR_USAGE_UNKNOWN; 
+                       g_errorCode = MULTIPR_APP_WRONG_NUMBER_OF_ARGUMENTS;
+               }
+               else
+               {
+                       g_usage               = MULTIPR_USAGE_INFO; 
+                       g_medFilename         = argv[2];
+                       
+                       if (argc == 4)
+                       {
+                               g_meshName    = argv[3];
+                       }
+               }
+       }
+       else
+       {
+               g_usage = MULTIPR_USAGE_UNKNOWN;
+               g_errorCode = MULTIPR_APP_UNKNOWN_USAGE;
+       }
+}
+
+
+/**
+ * \fn     int runAutotest()
+ * \brief  performs some unit tests on the MULTIPR API. 
+ * \return MULTIPR_APP_OK if successful, MULTIPR_APP_FAILED if failure.
+ */
+int runAutotest()
+{
+       cout << "Start autotest..." << endl;
+       
+       int ret = MULTIPR_APP_OK;
+       try
+       {
+               string strMEDfilename = g_medFilename;
+               strMEDfilename += "/agregat100grains_12pas.med";
+               
+               cout << "Test file: " << strMEDfilename << endl << endl;
+               
+               //---------------------------------------------------------------------
+               // Test partionneDomaine() = extract groups from a sequential MED file
+               //---------------------------------------------------------------------
+               multipr::partitionneDomaine(strMEDfilename.c_str(), "MAIL"); 
+               
+               //---------------------------------------------------------------------
+               // Test partitionneGrain() = split a group from a distributed MED file
+               // using MEDSPLITTER (METIS)
+               //---------------------------------------------------------------------
+               string strDistributedMEDfilename = g_medFilename;
+               strDistributedMEDfilename += "/agregat100grains_12pas_grains_maitre.med";
+               
+               multipr::partitionneGrain(
+                       strDistributedMEDfilename.c_str(), 
+                       "MAIL_1", 
+                       4, 
+                       multipr::MULTIPR_SCOTCH);
+                       
+               multipr::partitionneGrain(
+                       strDistributedMEDfilename.c_str(), 
+                       "MAIL_97", 
+                       3, 
+                       multipr::MULTIPR_METIS);
+
+               //---------------------------------------------------------------------
+               // Test decimePartition() = generate 2 lower resolution of a mesh
+               // using decimation based on gradient
+               //---------------------------------------------------------------------
+               multipr::decimePartition(
+                       strDistributedMEDfilename.c_str(), 
+                       "MAIL_98",
+                       "SIG_____SIEF_ELGA_______________",
+                       12,
+                       "Filtre_GradientMoyen",
+                       10.0,
+                       25.0,
+                       0.3,
+                       100);
+                       
+               multipr::decimePartition(
+                       strDistributedMEDfilename.c_str(), 
+                       "MAIL_92",
+                       "SIG_____SIEF_ELGA_______________",
+                       11,
+                       "Filtre_GradientMoyen",
+                       10.0,
+                       25.0,
+                       0.5,
+                       10);
+               
+               multipr::decimePartition(
+                       strDistributedMEDfilename.c_str(), 
+                       "MAIL_97_2",
+                       "SIG_____SIEF_ELGA_______________",
+                       10,
+                       "Filtre_GradientMoyen",
+                       10.0,
+                       25.0,
+                       0.4,
+                       20);
+                       
+               //---------------------------------------------------------------------
+               // Test passed: OK!
+               //---------------------------------------------------------------------
+               cout << endl;
+               cout << "Test passed: everything seems to be OK" << endl;
+               cout << "OK" << endl << endl;
+               
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               e.dump(cout);
+               cout << endl;
+               cout << "Test failed" << endl;
+               cout << "Failure" << endl << endl;
+               ret = MULTIPR_APP_FAILED;
+       }
+       
+       return ret;
+}
+
+
+/**
+ * \fn     void runPartition1()
+ * \brief  builds a distributed MED file (v2.3) by extracting groups from a sequential MED file. 
+ * \return MULTIPR_APP_OK if successful, MULTIPR_APP_FAILED if failure.
+ */
+int runPartition1()
+{
+       int ret = MULTIPR_APP_OK;
+       try
+       {
+               multipr::partitionneDomaine(g_medFilename, g_meshName); 
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               e.dump(cout);
+               ret = MULTIPR_APP_FAILED;
+       }
+               
+       return ret;
+}
+
+
+/**
+ * \fn     void runPartition2()
+ * \brief  builds a distributed MED file (v2.3) by splitting a part of a distributed MED file generated by runPartition1().  
+ * \return MULTIPR_APP_OK if successful, MULTIPR_APP_FAILED if failure.
+ */
+int runPartition2()
+{      
+       int ret = MULTIPR_APP_OK;
+       try
+       {
+               multipr::partitionneGrain(
+                       g_medFilename, 
+                       g_partName, 
+                       g_nbParts, 
+                       multipr::MULTIPR_METIS);
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               e.dump(cout);
+               ret = MULTIPR_APP_FAILED;
+       }
+               
+       return ret;
+}
+
+
+/**
+ * \fn     int runDecimation()
+ * \brief  creates 3 resolutions of a part of a distributed MED file. 
+ * \return MULTIPR_APP_OK if successful, MULTIPR_APP_FAILED if failure.
+ */
+int runDecimation()
+{      
+       int ret = MULTIPR_APP_OK;
+       try
+       {
+               multipr::decimePartition(
+                       g_medFilename, 
+                       g_partName,
+                       g_fieldName,
+                       g_fieldTimeStepIt,
+                       g_filterName,
+                       g_decimThresholdMed,
+                       g_decimThresholdLow,
+                       g_decimRadius,
+                       g_boxing);
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               e.dump(cout);
+               ret = MULTIPR_APP_FAILED;
+       }
+               
+       return ret;
+}
+
+
+/**
+ * \fn     int runDumpMED()
+ * \brief  dumps info about a sequential MED file.
+ * \return MULTIPR_APP_OK if successful, MULTIPR_APP_FAILED if failure.
+ */
+int runDumpMED()
+{
+#ifdef MULTIPR_USE_OBJ_API
+       int ret = MULTIPR_APP_OK;
+       try
+       {
+               // if mesh is unknown, then list all the meshes in the given MED file
+               if (g_meshName == NULL)
+               {
+                       multipr::Obj obj;
+                       obj.create(g_medFilename);
+                       
+                       {
+                               // display list of meshes contained in the MED file
+                               vector<string> res = obj.getMeshes();
+                               cout << "List of meshes in this MED file:" << endl;
+                               for (unsigned i = 0 ; i < res.size() ; i++)
+                               {
+                                       cout << "Mesh " << (i + 1) << ": " << res[i] << endl;
+                               }
+                       }
+                       
+                       cout << endl;
+                       
+                       {
+                               // display list of fields contained in the MED file
+                               vector<string> names = obj.getFields();
+                               cout << "List of fields in this MED file:" << endl;
+                               for (unsigned i = 0 ; i < names.size() ; i++)
+                               {
+                                       cout << "Field " << (i + 1) << ": " << names[i] << " #it=" << obj.getTimeStamps(names[i].c_str()) << endl;
+                               }
+                       }
+               }
+               else
+               {
+                       // display all infos about one mesh in a MED file
+                       multipr::Mesh mesh;
+                       mesh.readSequentialMED(g_medFilename, g_meshName);
+                       mesh.setPrintAll(true);
+                       cout << mesh << endl;
+               }
+               cout << "OK" << endl;
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               e.dump(cout);
+               ret = MULTIPR_APP_FAILED;
+       }
+       
+       return ret;
+#else
+       int ret = MULTIPR_APP_OK;
+       try
+       {
+               // if mesh is unknown, then list all the meshes in the given MED file
+               if (g_meshName == NULL)
+               {
+                       {
+                               // display list of meshes contained in the MED file
+                               vector<string> res = multipr::getListMeshes(g_medFilename);
+                               cout << "List of meshes in this MED file:" << endl;
+                               for (unsigned i = 0 ; i < res.size() ; i++)
+                               {
+                                       cout << "Mesh " << (i + 1) << ": " << res[i] << endl;
+                               }
+                       }
+                       
+                       cout << endl;
+                       
+                       {
+                               // display list of fields contained in the MED file
+                               vector<pair<string,int> > res = multipr::getListFields(g_medFilename);
+                               cout << "List of fields in this MED file:" << endl;
+                               for (unsigned i = 0 ; i < res.size() ; i++)
+                               {
+                                       cout << "Field " << (i + 1) << ": " << res[i].first << " #it=" << res[i].second << endl;
+                               }
+                       }
+               }
+               else
+               {
+                       // display all infos about one mesh in a MED file
+                       multipr::Mesh mesh;
+                       mesh.readSequentialMED(g_medFilename, g_meshName);
+                       mesh.setPrintAll(true);
+                       cout << mesh << endl;
+               }
+               cout << "OK" << endl;
+       }
+       catch (multipr::RuntimeException& e)
+       {
+               e.dump(cout);
+               ret = MULTIPR_APP_FAILED;
+       }
+       
+       return ret;
+#endif
+}
+
+
+/**
+ * \fn     int run()
+ * \brief  applies partitioning/decimation according to global parameters.
+ * \return MULTIPR_APP_OK if successful, MULTIPR_APP_FAILED if failure.
+ */
+int run()
+{
+       printGlobals();
+
+       int ret = MULTIPR_APP_OK;
+       switch (g_usage)
+       {
+               case MULTIPR_USAGE_AUTOTEST:   ret = runAutotest();   break;
+               case MULTIPR_USAGE_PARTITION1: ret = runPartition1(); break;
+               case MULTIPR_USAGE_PARTITION2: ret = runPartition2(); break;
+               case MULTIPR_USAGE_DECIMATION: ret = runDecimation(); break;
+               case MULTIPR_USAGE_INFO:       ret = runDumpMED();    break;
+               default:
+                       cout << "ERROR: unknown usage" << endl;
+                       ret = MULTIPR_APP_FAILED;
+                       break;
+       }
+       
+       return ret;
+}
+
+
+/**
+ * \fn     int main(int argc, char** argv)
+ * \brief  entry point of the application.
+ * \param  argc number of arguments.
+ * \param  argv list of arguments.
+ * \return 0 if OK, 1 if failed.
+ */
+int main(int argc, char** argv)
+{
+       cout << "multipr v" << multipr::getVersion() << " - by EDF/CS - 01/2007" << endl;
+       cout << "==================================" << endl;
+       
+       #ifdef MULTIPR_USE_OBJ_API
+               cout << "Version MULTIPR_Obj" << endl;
+       #else
+               cout << "Version MULTIPR_API" << endl;
+       #endif   
+
+       parseCommandLine(argc, argv);
+
+       int ret = MULTIPR_APP_OK; // assume no error at the beginning
+       
+       if (g_usage == MULTIPR_USAGE_UNKNOWN)
+       {
+               if (argc != 1)
+               {
+                       // if usage is unknown and there are some arguments, print an error message 
+                       cout << "ERROR: " << getErrorMsg() << endl;
+                       cout << endl;
+                       ret = MULTIPR_APP_FAILED;
+               }
+               else
+               {
+                       // if no argument, print a description of this application
+                       printDescription();
+               }
+
+               printUsage();
+       }
+       else if (g_usage == MULTIPR_USAGE_DISPLAY_HELP)
+       {
+               printDescription();
+               printUsage();
+       }
+       else
+       {
+               // the application seems to be configured properly: it can be executed
+               ret = run();
+       }
+       
+       return ret;
+}
+
+// EOF
diff --git a/src/MULTIPRGUI/MULTIPR_GUI.cxx b/src/MULTIPRGUI/MULTIPR_GUI.cxx
new file mode 100644 (file)
index 0000000..650b930
--- /dev/null
@@ -0,0 +1,747 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_GUI.cxx
+ *
+ * \brief   see MULTIPR_GUI.h
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+  
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+// MULTIPR Includes
+#include "MULTIPR_GUI.h"
+#include "MULTIPR_GUI_Dlg.h"
+
+// Salome Includes
+#include <SUIT_MessageBox.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
+#include <SalomeApp_Application.h>
+#include <SalomeApp_DataModel.h>
+#include <SalomeApp_Study.h>
+#include <SalomeApp_CheckFileDlg.h>
+#include <LightApp_Study.h>
+#include <LightApp_DataModel.h>
+#include <LightApp_DataOwner.h>
+#include <LightApp_SelectionMgr.h>
+#include <CAM_DataModel.h>
+#include <CAM_Module.h>
+
+#include <SALOME_LifeCycleCORBA.hxx>
+
+#include <QtxPopupMgr.h>
+
+// QT Includes
+#include <qapplication.h>
+#include <qinputdialog.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qgroupbox.h>
+#include <qvbox.h>
+#include <qbuttongroup.h>
+#include <qlabel.h>
+#include <qcombobox.h>
+#include <qvariant.h>
+#include <qlineedit.h>
+#include <qspinbox.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qimage.h>
+#include <qpixmap.h>
+
+
+using namespace std;
+
+
+//*****************************************************************************
+// Global variable
+//*****************************************************************************
+
+namespace multipr
+{
+       // progress callback used by the MULTIPR library
+       extern MULTIPR_ProgressCallback* gProgressCallback;
+}
+
+
+//*****************************************************************************
+// Class MULTIPR_GUI implementation
+//*****************************************************************************
+
+MULTIPR_GUI::MULTIPR_GUI() : SalomeApp_Module("MULTIPR")
+{
+       mMEDFileName = "";
+       mMULTIPRObj = NULL;
+}
+
+
+MULTIPR_ORB::MULTIPR_Obj_ptr MULTIPR_GUI::getMULTIPRObj()
+{
+       return mMULTIPRObj;
+}
+
+
+SalomeApp_Application* MULTIPR_GUI::getAppli() const
+{
+       return getApp();
+}
+
+
+MULTIPR_ORB::MULTIPR_Gen_ptr MULTIPR_GUI::InitMULTIPRGen(SalomeApp_Application* app)
+{
+       Engines::Component_var comp = app->lcc()->FindOrLoad_Component("FactoryServer", "MULTIPR");
+       MULTIPR_ORB::MULTIPR_Gen_ptr clr = MULTIPR_ORB::MULTIPR_Gen::_narrow(comp);
+       ASSERT(!CORBA::is_nil(clr));
+       return clr;
+}
+
+
+void MULTIPR_GUI::initialize(CAM_Application* app)
+{
+       SalomeApp_Module::initialize(app);
+       
+       InitMULTIPRGen(dynamic_cast<SalomeApp_Application*>(app));
+       
+       QWidget* aParent = app->desktop();
+       SUIT_ResourceMgr* aResourceMgr = app->resourceMgr();
+       
+       //-------------------------------------------------------------------------
+       // create actions
+       //-------------------------------------------------------------------------     
+       QPixmap aPixmapImportFromMEDFile = aResourceMgr->loadPixmap("MULTIPR", tr("ICON_IMPORT_MED"));
+       
+       createAction( 
+               ACTION_IMPORT_MED, 
+               tr("TLT_IMPORT_FROM_MED_FILE"), 
+               QIconSet(aPixmapImportFromMEDFile), 
+               tr("MEN_IMPORT_FROM_MED_FILE"), 
+               tr("STS_IMPORT_FROM_MED_FILE"), 
+               (CTRL + Key_I),
+               aParent, 
+               false,
+               this, 
+               SLOT(OnImportFromMEDFile()));
+               
+       createAction( 
+               ACTION_SPLIT, 
+               tr("TLT_SPLIT"), 
+               QIconSet(), 
+               tr("MEN_SPLIT"), 
+               tr("STS_SPLIT"), 
+               0,
+               aParent, 
+               false,
+               this, 
+               SLOT(OnPartition2()));
+       
+       createAction( 
+               ACTION_DECIMATE, 
+               tr("TLT_DECIMATE"), 
+               QIconSet(), 
+               tr("MEN_DECIMATE"), 
+               tr("STS_DECIMATE"), 
+               0,
+               aParent, 
+               false,
+               this, 
+               SLOT(OnDecimate()));
+               
+       QPixmap aPixmapSaveMEDFile = aResourceMgr->loadPixmap("MULTIPR", tr("ICON_SAVE_MED"));
+       
+       createAction( 
+               ACTION_SAVE, 
+               tr("TLT_SAVE"), 
+               QIconSet(aPixmapSaveMEDFile), 
+               tr("MEN_SAVE"), 
+               tr("STS_SAVE"), 
+               0,
+               aParent, 
+               false,
+               this, 
+               SLOT(OnSave()));
+       
+       //-------------------------------------------------------------------------
+       // create menus
+       //-------------------------------------------------------------------------
+       int aMenuId;
+       aMenuId = createMenu(tr("MEN_FILE"), -1, -1);
+       createMenu(separator(), aMenuId, -1, 10);
+       aMenuId = createMenu(tr("MEN_FILE_MULTIPR"), aMenuId, -1, 10);
+       createMenu(ACTION_IMPORT_MED, aMenuId);
+       
+       aMenuId = createMenu(tr("MEN_MULTIPR"), -1, -1, 30);
+       createMenu(ACTION_IMPORT_MED, aMenuId, 10);
+       createMenu(ACTION_SAVE, aMenuId, 10);
+       createMenu(ACTION_SPLIT, aMenuId, 10);
+       createMenu(ACTION_DECIMATE, aMenuId, 10);
+       
+       //-------------------------------------------------------------------------
+       // create toolbars
+       //-------------------------------------------------------------------------
+       int aToolId = createTool(tr("TOOL_MULTIPR"));
+       createTool(ACTION_IMPORT_MED, aToolId);
+       createTool(ACTION_SAVE, aToolId);
+       
+       //-------------------------------------------------------------------------
+       // create popup menus
+       //-------------------------------------------------------------------------
+       QtxPopupMgr* mgr = popupMgr();
+       mgr->insert( action(ACTION_SPLIT), -1, -1, -1 );
+       mgr->insert( action(ACTION_DECIMATE), -1, -1, -1 );
+       mgr->insert( action(ACTION_SAVE), -1, -1, -1 );
+       
+       QString aRule = "client='ObjectBrowser' and selcount>=1"; // $type in {'VISU::TMESH'}";
+       mgr->setRule(action(ACTION_SPLIT), aRule, true);
+       mgr->setRule(action(ACTION_DECIMATE), aRule, true);
+       mgr->setRule(action(ACTION_SAVE), aRule, true);
+       
+       //-------------------------------------------------------------------------
+       // set progress dialog
+       //-------------------------------------------------------------------------
+       MULTIPR_GUI_ProgressCallbackDlg* progressDlg = new MULTIPR_GUI_ProgressCallbackDlg(application()->desktop());
+       multipr::gProgressCallback = progressDlg;
+}
+
+
+CAM_DataModel* MULTIPR_GUI::createDataModel()
+{
+       return new MULTIPR_GUI_DataModel(this);
+}
+
+
+QString MULTIPR_GUI::engineIOR() const
+{
+       CORBA::String_var anIOR = getApp()->orb()->object_to_string(InitMULTIPRGen(getApp()));
+       return QString(anIOR.in());
+}
+
+
+bool MULTIPR_GUI::activateModule(SUIT_Study* theStudy)
+{
+       bool bOk = SalomeApp_Module::activateModule(theStudy);
+       
+       setMenuShown(true);
+       setToolShown(true);
+       
+       return bOk;
+}
+
+
+bool MULTIPR_GUI::deactivateModule(SUIT_Study* theStudy)
+{
+       setMenuShown(false);
+       setToolShown(false);
+       
+       return SalomeApp_Module::deactivateModule(theStudy);
+}
+
+
+void MULTIPR_GUI::windows(QMap<int, int>& theMap) const
+{
+       theMap.clear();
+       theMap.insert(SalomeApp_Application::WT_ObjectBrowser, Qt::DockLeft);
+       theMap.insert(SalomeApp_Application::WT_PyConsole,     Qt::DockBottom);
+}
+
+
+void MULTIPR_GUI::selected(QStringList& entries, const bool multiple)
+{
+       LightApp_SelectionMgr* mgr = getApp()->selectionMgr();
+       
+       if(!mgr) return;
+       
+       SUIT_DataOwnerPtrList anOwnersList;
+       mgr->selected(anOwnersList);
+       
+       for (int i = 0 ; i < anOwnersList.size() ; i++)
+       {
+               const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>(anOwnersList[i].get());
+               
+               if (!entries.contains(owner->entry()))
+               {
+                       entries.append(owner->entry());
+               }
+                       
+               if (!multiple)
+                       break;
+       }
+}
+
+
+void MULTIPR_GUI::OnImportFromMEDFile()
+{
+       // Get file name
+       QStringList aFilter;
+       aFilter.append(tr("FLT_MED_FILES"));
+       aFilter.append(tr("FLT_ALL_FILES"));
+       
+       SalomeApp_CheckFileDlg* fd = new SalomeApp_CheckFileDlg(
+               this->application()->desktop(), 
+               true, 
+               tr("USE_BUILD_PROGRESS") );
+       fd->setCaption(tr("MEN_IMPORT_FROM_MED_FILE"));
+       fd->setFilters(aFilter);
+       fd->exec();
+       QFileInfo aFileInfo(fd->selectedFile());
+       delete fd;
+       
+       // Check the file name
+       if (!aFileInfo.exists())
+               return;
+               
+       mMEDFileName = aFileInfo.filePath();
+       
+       QApplication::setOverrideCursor(Qt::waitCursor);
+       
+       try
+       {
+               MULTIPR_ORB::MULTIPR_Gen_ptr multiprgen = MULTIPR_GUI::InitMULTIPRGen(getApp());
+               mMULTIPRObj = multiprgen->getObject(mMEDFileName.latin1());
+       }
+       catch(...)
+       {
+               SUIT_MessageBox::error1( 
+                       getApp()->desktop(),
+                       "Import MED file error", 
+                       "Invalid MED file (not recognized by MULTIPR)", 
+                       tr("OK") );
+       }
+       QApplication::restoreOverrideCursor();
+       
+       try
+       {
+               if (mMULTIPRObj->isValidSequentialMEDFile())
+               {
+                       OnPartition1();
+               }
+       }
+       catch (...)
+       {
+       }
+}
+
+
+void MULTIPR_GUI::OnPartition1()
+{
+       MULTIPR_GUI_Partition1Dlg* dialog = new MULTIPR_GUI_Partition1Dlg(this);
+       dialog->exec();
+       delete dialog;
+}
+
+
+void MULTIPR_GUI::OnPartition2()
+{
+       retrieveSelectedParts();
+       
+       if (mSelectedParts.count() == 0)
+       {
+               SUIT_MessageBox::warn1( 
+                       getApp()->desktop(),
+                       "Split warning", 
+                       "No parts selected", 
+                       tr("OK") );
+               return;
+       }
+       
+       MULTIPR_GUI_Partition2Dlg* dialog = new MULTIPR_GUI_Partition2Dlg(this);
+       dialog->exec();
+       delete dialog;
+       getApp()->updateObjectBrowser();
+}
+
+
+void MULTIPR_GUI::OnDecimate()
+{
+       retrieveSelectedParts();
+       
+       if (mSelectedParts.count() == 0)
+       {
+               SUIT_MessageBox::warn1( 
+                       getApp()->desktop(),
+                       "Decimation warning", 
+                       "No parts selected", 
+                       tr("OK") );
+               return;
+       }
+       
+       MULTIPR_GUI_DecimateDlg* dialog = new MULTIPR_GUI_DecimateDlg(this);
+       dialog->exec();
+       delete dialog;
+       getApp()->updateObjectBrowser();
+}
+
+
+void MULTIPR_GUI::OnSave()
+{
+       QApplication::setOverrideCursor(Qt::waitCursor);
+       
+       try
+       {
+               mMULTIPRObj->save();
+               getApp()->updateObjectBrowser();
+       }
+       catch(...)
+       {
+               SUIT_MessageBox::error1( 
+                       getApp()->desktop(),
+                       "Save distributed MED file error", 
+                       "Error while writing distributed MED file", 
+                       tr("OK") );
+       }
+       
+       QApplication::restoreOverrideCursor();
+}
+
+
+
+void MULTIPR_GUI::retrieveSelectedParts()
+{
+       mSelectedParts.clear();
+
+       QStringList userSelection;      
+       selected(userSelection, true);
+       for (QStringList::const_iterator it = userSelection.begin(), last = userSelection.end(); it != last; it++)
+       {
+               const QString& str = (*it);
+               QStringList words = QStringList::split(":", str);
+               if (words.count() == 2)
+               {
+                       if (words[0] == "MULTIPR_PART")
+                       {
+                               mSelectedParts.push_back(words[1]);
+                       }
+               }
+    }
+}
+
+
+//*****************************************************************************
+// Super class Data Object implementation
+//*****************************************************************************
+
+MULTIPR_GUI_DataObject::MULTIPR_GUI_DataObject(SUIT_DataObject* parent, const char* name) : 
+       LightApp_DataObject(parent),
+       CAM_DataObject(parent)
+{
+       mName = name;
+}
+
+
+MULTIPR_GUI_DataObject::~MULTIPR_GUI_DataObject()
+{
+       // do nothing!
+}
+
+
+QString MULTIPR_GUI_DataObject::entry() const
+{
+       return QString("MULTIPR_OBJECT");
+}
+
+
+QString MULTIPR_GUI_DataObject::name() const
+{
+  return mName;
+}
+
+
+QPixmap MULTIPR_GUI_DataObject::icon() const
+{
+       //static QPixmap icon = SUIT_Session::session()->resourceMgr()->loadPixmap("MULTIPR", QObject::tr("ICON_IMPORT_MED"), false);
+       return QPixmap();
+       
+}
+
+
+QString MULTIPR_GUI_DataObject::toolTip() const
+{
+       // default behaviour: return an empty string
+       return "";
+}
+
+
+//*****************************************************************************
+// Class Data Object Module implementation
+//*****************************************************************************
+
+MULTIPR_GUI_DataObject_Module::MULTIPR_GUI_DataObject_Module(CAM_DataModel* dm, SUIT_DataObject* parent, const char* name) : 
+       MULTIPR_GUI_DataObject(parent, name),
+       LightApp_ModuleObject(dm, parent),
+       CAM_DataObject(parent)
+{
+       // do nothing!
+}
+
+
+MULTIPR_GUI_DataObject_Module::~MULTIPR_GUI_DataObject_Module()
+{
+       // do nothing!
+}
+
+
+QString MULTIPR_GUI_DataObject_Module::entry() const
+{
+       return QString("MULTIPR_MODULE:" + mName);
+}
+
+
+QString MULTIPR_GUI_DataObject_Module::name() const
+{
+  return CAM_RootObject::name();
+}
+
+
+QPixmap MULTIPR_GUI_DataObject_Module::icon() const
+{
+       return QPixmap();
+}
+
+
+QString MULTIPR_GUI_DataObject_Module::toolTip() const
+{
+       return QString("Module MULTIPR");
+}
+
+
+//*****************************************************************************
+// Class Data Object Mesh implementation
+//*****************************************************************************
+
+MULTIPR_GUI_DataObject_Mesh::MULTIPR_GUI_DataObject_Mesh(SUIT_DataObject* parent, const char* name) : 
+       MULTIPR_GUI_DataObject(parent, name),
+       CAM_DataObject(parent)
+{
+       // do nothing!
+}
+
+
+MULTIPR_GUI_DataObject_Mesh::~MULTIPR_GUI_DataObject_Mesh()
+{
+       // do nothing!
+}
+
+
+QString MULTIPR_GUI_DataObject_Mesh::entry() const
+{
+       return QString("MULTIPR_MESH:") + mName;
+}
+
+
+QPixmap MULTIPR_GUI_DataObject_Mesh::icon() const
+{
+       return QPixmap();
+}
+
+
+QString MULTIPR_GUI_DataObject_Mesh::toolTip() const
+{
+       return QString("Original mesh");
+}
+
+
+//*****************************************************************************
+// Class Data Object Part implementation
+//*****************************************************************************
+
+MULTIPR_GUI_DataObject_Part::MULTIPR_GUI_DataObject_Part(SUIT_DataObject* parent, const char* name, const char* info) : 
+       MULTIPR_GUI_DataObject(parent, name),
+       CAM_DataObject(parent)
+{
+       mMeshName    = "";
+       mId          = 0;
+       mPath        = "";
+       mMEDFileName = "";
+       
+       mTooltip = info;
+       
+       // parse info to retrieve all the fields
+       char   lMeshName[256];
+       int    lId;
+       char   lPartName[256];
+       char   lPath[256];
+       char   lMEDFileName[256];
+       
+       int ret = sscanf(info, "%s %d %s %s %s", 
+                               lMeshName,
+                               &lId,
+                               lPartName,
+                               lPath,
+                               lMEDFileName);
+                               
+       // number of read parameters should be 5
+       if (ret != 5) return;
+       
+       mMeshName    = lMeshName;
+       mId          = lId;
+       mPath        = lPath;
+       mMEDFileName = lMEDFileName;
+}
+
+
+MULTIPR_GUI_DataObject_Part::~MULTIPR_GUI_DataObject_Part()
+{
+       // do nothing!
+}
+
+
+QString MULTIPR_GUI_DataObject_Part::entry() const
+{
+       return QString("MULTIPR_PART:") + mName;
+}
+
+
+QPixmap MULTIPR_GUI_DataObject_Part::icon() const
+{
+       return QPixmap();
+}
+
+
+QString MULTIPR_GUI_DataObject_Part::toolTip() const
+{
+       return mTooltip;
+}
+
+
+//*****************************************************************************
+// Class Data Object Resolution implementation
+//*****************************************************************************
+
+MULTIPR_GUI_DataObject_Resolution::MULTIPR_GUI_DataObject_Resolution(SUIT_DataObject* parent, const char* name, const char* info) : 
+       MULTIPR_GUI_DataObject_Part(parent, name, info),
+       CAM_DataObject(parent)
+{
+       // do nothing!
+}
+
+
+MULTIPR_GUI_DataObject_Resolution::~MULTIPR_GUI_DataObject_Resolution()
+{
+       // do nothing!
+}
+
+
+QString MULTIPR_GUI_DataObject_Resolution::entry() const
+{
+       return QString("MULTIPR_RESOLUTION:") + mName;
+}
+
+
+QPixmap MULTIPR_GUI_DataObject_Resolution::icon() const
+{
+       return QPixmap();
+}
+
+
+QString MULTIPR_GUI_DataObject_Resolution::toolTip() const
+{
+       return mTooltip;
+}
+
+
+//*****************************************************************************
+// Data Model
+//*****************************************************************************
+
+MULTIPR_GUI_DataModel::MULTIPR_GUI_DataModel(CAM_Module* module) : 
+       LightApp_DataModel(module)
+{
+       mMULTIPR_GUI = dynamic_cast<MULTIPR_GUI*>(module);
+}
+
+
+MULTIPR_GUI_DataModel::~MULTIPR_GUI_DataModel()
+{
+       // do nothing!
+}
+
+
+void MULTIPR_GUI_DataModel::build()
+{
+       MULTIPR_GUI_DataObject_Module* modelRoot = dynamic_cast<MULTIPR_GUI_DataObject_Module*>(root());
+       
+       if (!modelRoot)  
+       {  
+               // root is not set yet
+               modelRoot = new MULTIPR_GUI_DataObject_Module(this, NULL, "MULTIPR");
+               setRoot(modelRoot);
+       }
+       
+       MULTIPR_ORB::MULTIPR_Obj_ptr obj = mMULTIPR_GUI->getMULTIPRObj();
+       
+       if (obj != NULL)
+       {
+               MULTIPR_ORB::string_array* listParts = obj->getParts();
+               
+               if (listParts->length() >= 1)
+               {
+                       const char* strPartName0 = (*listParts)[0];
+                       char* strPartInfo0 = obj->getPartInfo(strPartName0);
+                       
+                       char   lMeshName[256];
+                       int    lId;
+                       char   lPartName[256];
+                       char   lPath[256];
+                       char   lMEDFileName[256];       
+                       
+                       // parse infos
+                       int ret = sscanf(strPartInfo0, "%s %d %s %s %s", 
+                               lMeshName,
+                               &lId,
+                               lPartName,
+                               lPath,
+                               lMEDFileName);
+                               
+                       if (ret != 5) return;
+                       
+                       MULTIPR_GUI_DataObject_Mesh* dataObjectMesh = new MULTIPR_GUI_DataObject_Mesh(modelRoot, lMeshName);
+                       
+                       MULTIPR_GUI_DataObject_Part* dataObjectPart_prev = NULL;
+                       
+                       for (int i = 0 ; i < listParts->length() ; i++)
+                       {
+                               const char* strItem = (*listParts)[i];
+                               char* strPartInfo = obj->getPartInfo(strItem);
+                               
+                               // parse infos
+                               int ret = sscanf(strPartInfo, "%s %d %s %s %s", 
+                                       lMeshName,
+                                       &lId,
+                                       lPartName,
+                                       lPath,
+                                       lMEDFileName);
+                               
+                               if (ret != 5) return;
+                       
+                               //cout << "Part : " << lPartName << endl;
+                               if ((strstr(lPartName,"_MED") != NULL) || (strstr(lPartName,"_LOW") != NULL))
+                               {
+                                       //cout << "Found MED/LOW" << endl;
+                                       new MULTIPR_GUI_DataObject_Resolution(dataObjectPart_prev, strItem, strPartInfo);
+                               }
+                               else
+                               {
+                                       dataObjectPart_prev = new MULTIPR_GUI_DataObject_Part(dataObjectMesh, strItem, strPartInfo);
+                               }
+                       }
+               }
+       }
+}
+
+
+extern "C" 
+{
+       CAM_Module* createModule()
+       {
+               return new MULTIPR_GUI();
+       }
+}
+
+
+// EOF
diff --git a/src/MULTIPRGUI/MULTIPR_GUI.h b/src/MULTIPRGUI/MULTIPR_GUI.h
new file mode 100644 (file)
index 0000000..aa929e2
--- /dev/null
@@ -0,0 +1,235 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_GUI.h
+ *
+ * \brief   MULTIPR GUI (QT)
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#ifndef __MULTIPR_GUI__
+#define __MULTIPR_GUI__
+
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+#include <SalomeApp_Module.h>
+#include <LightApp_DataObject.h>
+#include <LightApp_DataModel.h>
+#include <LightApp_RootObject.h>
+
+#include <SALOMEconfig.h>
+#include CORBA_CLIENT_HEADER(MULTIPR)
+
+#include <qdialog.h>
+#include <qprogressdialog.h>
+#include <qstring.h>
+#include <qvariant.h>
+
+#include "MULTIPR_ProgressCallback.hxx"
+
+
+//*****************************************************************************
+// Pre-declaration
+//*****************************************************************************
+
+class SalomeApp_Application;
+class CAM_Module;
+
+class QVBoxLayout;
+class QHBoxLayout;
+class QGridLayout;
+class QSpacerItem;
+class QButtonGroup;
+class QLabel;
+class QComboBox;
+class QLineEdit;
+class QSpinBox;
+class QPushButton;
+
+
+//*****************************************************************************
+// Class MULTIPR_GUI
+// Salome Application
+//*****************************************************************************
+
+class MULTIPR_GUI: public SalomeApp_Module
+{
+       Q_OBJECT
+
+public:
+       MULTIPR_GUI();
+       
+       void    initialize(CAM_Application*);
+       QString engineIOR() const;
+       void    windows(QMap<int, int>&) const;
+       
+       MULTIPR_ORB::MULTIPR_Obj_ptr getMULTIPRObj();
+       SalomeApp_Application* getAppli() const;
+       void selected(QStringList&, const bool);
+       
+       static MULTIPR_ORB::MULTIPR_Gen_ptr InitMULTIPRGen(SalomeApp_Application*);
+       
+       const QStringList& getSelectedParts() const { return mSelectedParts; }
+
+public slots:
+       bool deactivateModule(SUIT_Study*);
+       bool activateModule(SUIT_Study*);
+
+protected slots:
+       void OnImportFromMEDFile();
+       void OnPartition1();
+       void OnPartition2();
+       void OnDecimate();
+       void OnSave();
+       
+       void retrieveSelectedParts();
+       
+protected:
+       virtual CAM_DataModel* createDataModel();
+       
+protected:
+
+       enum 
+       { 
+               ACTION_IMPORT_MED = 190,
+               ACTION_SAVE,
+               ACTION_SPLIT,
+               ACTION_DECIMATE
+       };
+       
+private:
+       QString                      mMEDFileName;
+       QStringList                  mSelectedParts;
+       MULTIPR_ORB::MULTIPR_Obj_ptr mMULTIPRObj;
+  
+}; // class MULTIPR_GUI
+
+
+//*****************************************************************************
+// Class MULTIPR_GUI_DataObject
+//*****************************************************************************
+
+class MULTIPR_GUI_DataObject : public LightApp_DataObject
+{
+public:
+       MULTIPR_GUI_DataObject(SUIT_DataObject* parent, const char* name);
+       virtual ~MULTIPR_GUI_DataObject();
+       
+       virtual QString entry()   const;
+       virtual QString name()    const;
+       virtual QPixmap icon()    const;
+       virtual QString toolTip() const;
+
+protected:
+       QString mName;
+};
+
+
+//*****************************************************************************
+// Class MULTIPR_GUI_DataObject_Module
+//*****************************************************************************
+
+class MULTIPR_GUI_DataObject_Module : public MULTIPR_GUI_DataObject, public LightApp_ModuleObject
+{
+public:
+       MULTIPR_GUI_DataObject_Module(CAM_DataModel* dm, SUIT_DataObject* parent, const char* name);
+       virtual ~MULTIPR_GUI_DataObject_Module();
+       
+       virtual QString entry()   const;
+       virtual QString name()    const;
+       virtual QPixmap icon()    const;
+       virtual QString toolTip() const;
+
+private:
+};
+
+
+//*****************************************************************************
+// Class MULTIPR_GUI_DataObject_Mesh
+//*****************************************************************************
+
+class MULTIPR_GUI_DataObject_Mesh : public MULTIPR_GUI_DataObject
+{
+public:
+       MULTIPR_GUI_DataObject_Mesh(SUIT_DataObject* parent, const char* name);
+       virtual ~MULTIPR_GUI_DataObject_Mesh();
+       
+       virtual QString entry()   const;
+       virtual QPixmap icon()    const;
+       virtual QString toolTip() const;
+
+private:
+};
+
+
+//*****************************************************************************
+// Class MULTIPR_GUI_DataObject_Part
+//*****************************************************************************
+
+class MULTIPR_GUI_DataObject_Part : public MULTIPR_GUI_DataObject
+{
+public:
+       MULTIPR_GUI_DataObject_Part(SUIT_DataObject* parent, const char* name, const char* info);
+       virtual ~MULTIPR_GUI_DataObject_Part();
+       
+       virtual QString entry()   const;
+       virtual QPixmap icon()    const;
+       virtual QString toolTip() const;
+
+protected:
+       QString mMeshName;
+       int     mId;
+       QString mPath;
+       QString mMEDFileName;
+       QString mTooltip;
+};
+
+
+//*****************************************************************************
+// Class MULTIPR_GUI_DataObject_Resolution
+//*****************************************************************************
+
+class MULTIPR_GUI_DataObject_Resolution : public MULTIPR_GUI_DataObject_Part
+{
+public:
+       MULTIPR_GUI_DataObject_Resolution(SUIT_DataObject* parent, const char* name, const char* info);
+       virtual ~MULTIPR_GUI_DataObject_Resolution();
+       
+       virtual QString entry()   const;
+       virtual QPixmap icon()    const;
+       virtual QString toolTip() const;
+
+private:
+};
+
+
+//*****************************************************************************
+// Class MULTIPR_GUI_DataModel
+//*****************************************************************************
+
+class MULTIPR_GUI_DataModel : public LightApp_DataModel
+{
+public:
+       MULTIPR_GUI_DataModel(CAM_Module*);
+       virtual ~MULTIPR_GUI_DataModel();
+
+protected:
+       virtual void build();
+       
+private:
+       MULTIPR_GUI* mMULTIPR_GUI;
+};
+
+
+#endif // __MULTIPR_GUI__
+
+
+// EOF
+
diff --git a/src/MULTIPRGUI/MULTIPR_GUI_Dlg.cxx b/src/MULTIPRGUI/MULTIPR_GUI_Dlg.cxx
new file mode 100644 (file)
index 0000000..be2a2fd
--- /dev/null
@@ -0,0 +1,651 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_GUI_Dlg.cxx
+ *
+ * \brief   see MULTIPR_GUI_Dlg.h
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+  
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+#include "MULTIPR_GUI_Dlg.h"
+#include "MULTIPR_GUI.h"
+#include "MULTIPR_Mesh.hxx"
+#include "MULTIPR_DecimationFilter.hxx"
+
+// Salome Includes
+#include <SUIT_MessageBox.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
+#include <SalomeApp_Application.h>
+#include <SalomeApp_DataModel.h>
+#include <SalomeApp_Study.h>
+#include <SalomeApp_CheckFileDlg.h>
+#include <LightApp_Study.h>
+#include <LightApp_DataModel.h>
+#include <LightApp_DataOwner.h>
+#include <LightApp_SelectionMgr.h>
+#include <CAM_DataModel.h>
+#include <CAM_Module.h>
+
+#include <SALOME_LifeCycleCORBA.hxx>
+
+#include <QtxPopupMgr.h>
+
+// QT Includes
+#include <qapplication.h>
+#include <qinputdialog.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qgroupbox.h>
+#include <qvbox.h>
+#include <qbuttongroup.h>
+#include <qlabel.h>
+#include <qcombobox.h>
+#include <qvariant.h>
+#include <qlineedit.h>
+#include <qspinbox.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qimage.h>
+#include <qpixmap.h>
+
+
+using namespace std;
+
+
+MULTIPR_GUI_Partition1Dlg::MULTIPR_GUI_Partition1Dlg(MULTIPR_GUI* theModule) : 
+       QDialog( theModule->application()->desktop(), 0, false, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
+{
+       mModule = theModule;
+       
+    buttonGroupProcess = new QButtonGroup( this, "buttonGroupProcess" );
+    buttonGroupProcess->setGeometry( QRect( 10, 110, 450, 60 ) );
+
+    pushButtonCancel = new QPushButton( buttonGroupProcess, "pushButtonCancel" );
+    pushButtonCancel->setGeometry( QRect( 321, 10, 110, 41 ) );
+
+    pushButtonOK = new QPushButton( buttonGroupProcess, "pushButtonOK" );
+    pushButtonOK->setGeometry( QRect( 10, 10, 110, 41 ) );
+
+    buttonGroupSelectMesh = new QButtonGroup( this, "buttonGroupSelectMesh" );
+    buttonGroupSelectMesh->setGeometry( QRect( 10, 10, 450, 91 ) );
+
+    comboBoxSelectMesh = new QComboBox( FALSE, buttonGroupSelectMesh, "comboBoxSelectMesh" );
+    comboBoxSelectMesh->setGeometry( QRect( 160, 30, 280, 40 ) );
+       MULTIPR_ORB::string_array* listMeshes = theModule->getMULTIPRObj()->getMeshes();
+       for (int i=0; i<listMeshes->length() ; i++)
+       {
+               const char* strItem = (*listMeshes)[i];
+               comboBoxSelectMesh->insertItem(strItem);
+       }
+       comboBoxSelectMesh->setEditable(false);
+
+    textLabelSelectMesh = new QLabel( buttonGroupSelectMesh, "textLabelSelectMesh" );
+    textLabelSelectMesh->setGeometry( QRect( 20, 30, 110, 40 ) );
+    
+       setCaption( tr( "Extract groups from sequential MED file" ) );
+    buttonGroupProcess->setTitle( QString::null );
+    pushButtonCancel->setText( tr( "Cancel" ) );
+    pushButtonOK->setText( tr("OK") );
+    buttonGroupSelectMesh->setTitle( tr( "Select mesh" ) );
+    textLabelSelectMesh->setText( tr( "Mesh name" ) );
+       
+    resize( QSize(471, 185).expandedTo(minimumSizeHint()) );
+    clearWState( WState_Polished );
+       
+       connect(pushButtonOK,     SIGNAL(clicked()), this, SLOT(accept()));
+       connect(pushButtonCancel, SIGNAL(clicked()), this, SLOT(reject()));
+}
+
+
+/*
+ *  Destroys the object and frees any allocated resources
+ */
+MULTIPR_GUI_Partition1Dlg::~MULTIPR_GUI_Partition1Dlg()
+{
+    // no need to delete child widgets, Qt does it all for us
+}
+
+
+void MULTIPR_GUI_Partition1Dlg::accept()
+{
+       const char* meshName = comboBoxSelectMesh->currentText().latin1();
+       
+       try
+       {
+               mModule->getMULTIPRObj()->setMesh(meshName);
+               
+               QApplication::setOverrideCursor(Qt::waitCursor);
+               mModule->getMULTIPRObj()->partitionneDomaine();
+               QApplication::restoreOverrideCursor();
+               
+       }
+       catch(...)
+       {
+               SUIT_MessageBox::error1( 
+                       mModule->getAppli()->desktop(),
+                       "Import MED file error", 
+                       "Unable to set mesh", 
+                       tr("OK") );
+       }
+
+       QDialog::accept();
+       mModule->getAppli()->updateObjectBrowser();
+}
+
+
+void MULTIPR_GUI_Partition1Dlg::reject()
+{
+       QDialog::reject();
+}
+
+
+MULTIPR_GUI_Partition2Dlg::MULTIPR_GUI_Partition2Dlg(MULTIPR_GUI* theModule) : 
+       QDialog( theModule->application()->desktop(), 0, false, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
+{
+       mModule = theModule;
+       
+    buttonGroupSplitParameters = new QButtonGroup( this, "buttonGroupSplitParameters" );
+    buttonGroupSplitParameters->setGeometry( QRect( 10, 10, 380, 140 ) );
+
+    textLabelSelectNbParts = new QLabel( buttonGroupSplitParameters, "textLabelSelectNbParts" );
+    textLabelSelectNbParts->setGeometry( QRect( 30, 30, 160, 31 ) );
+
+    textLabelSelectSplitter = new QLabel( buttonGroupSplitParameters, "textLabelSelectSplitter" );
+    textLabelSelectSplitter->setGeometry( QRect( 30, 80, 111, 31 ) );
+
+    comboBoxSelectSplitter = new QComboBox( FALSE, buttonGroupSplitParameters, "comboBoxSelectSplitter" );
+    comboBoxSelectSplitter->setGeometry( QRect( 210, 80, 150, 40 ) );
+       comboBoxSelectSplitter->insertItem("METIS");
+       comboBoxSelectSplitter->insertItem("SCOTCH");
+       comboBoxSelectSplitter->setEditable(false);
+
+    spinBoxNbParts = new QSpinBox( buttonGroupSplitParameters, "spinBoxNbParts" );
+    spinBoxNbParts->setGeometry( QRect( 210, 30, 150, 30 ) );
+    spinBoxNbParts->setMaxValue( 1000 );
+    spinBoxNbParts->setMinValue( 2 );
+    spinBoxNbParts->setValue( 2 );
+
+    buttonGroupProcess = new QButtonGroup( this, "buttonGroupProcess" );
+    buttonGroupProcess->setGeometry( QRect( 10, 160, 380, 60 ) );
+
+    pushButtonOK = new QPushButton( buttonGroupProcess, "pushButtonOK" );
+    pushButtonOK->setGeometry( QRect( 10, 10, 110, 41 ) );
+
+    pushButtonCancel = new QPushButton( buttonGroupProcess, "pushButtonCancel" );
+    pushButtonCancel->setGeometry( QRect( 250, 10, 110, 41 ) );
+    
+       setCaption( tr( "Split selected part" ) );
+    buttonGroupSplitParameters->setTitle( tr( "Split parameters" ) );
+    textLabelSelectNbParts->setText( tr( "Number of sub-parts" ) );
+    textLabelSelectSplitter->setText( tr( "Splitter" ) );
+    buttonGroupProcess->setTitle( QString::null );
+    pushButtonOK->setText( tr("OK") );
+    pushButtonCancel->setText( tr( "Cancel" ) );
+       
+    resize( QSize(403, 234).expandedTo(minimumSizeHint()) );
+    clearWState( WState_Polished );
+       
+       connect(pushButtonOK,     SIGNAL(clicked()), this, SLOT(accept()));
+       connect(pushButtonCancel, SIGNAL(clicked()), this, SLOT(reject()));
+}
+
+/*
+ *  Destroys the object and frees any allocated resources
+ */
+MULTIPR_GUI_Partition2Dlg::~MULTIPR_GUI_Partition2Dlg()
+{
+    // no need to delete child widgets, Qt does it all for us
+}
+
+
+void MULTIPR_GUI_Partition2Dlg::accept()
+{
+       const char* strSplitter = comboBoxSelectSplitter->currentText().latin1();
+       int nbParts = spinBoxNbParts->value();
+       int partitionner = -1;
+       if (strcmp(strSplitter, "METIS") == 0)
+       {
+               partitionner = 0;
+       }
+       else if (strcmp(strSplitter, "SCOTCH") == 0)
+       {
+               partitionner = 1;
+       }
+       
+       QApplication::setOverrideCursor(Qt::waitCursor);
+       
+       try
+       {
+               const QStringList& partsList = mModule->getSelectedParts();
+               for (QStringList::const_iterator it = partsList.begin(), last = partsList.end(); it != last; it++)
+               {
+                       const QString& partName = (*it);
+                       cout << "Split " << partName.latin1() << " #parts=" << nbParts << " splitter=" << strSplitter;
+                       mModule->getMULTIPRObj()->partitionneGrain(partName.latin1(), nbParts, partitionner);
+               }
+               
+       }
+       catch(...)
+       {
+               SUIT_MessageBox::error1( 
+                       mModule->getAppli()->desktop(),
+                       "Split error", 
+                       "Error while splitting selected part(s)", 
+                       tr("OK") );
+       }
+       
+       QApplication::restoreOverrideCursor();
+       QDialog::accept();
+}
+
+
+void MULTIPR_GUI_Partition2Dlg::reject()
+{
+       QDialog::reject();
+}
+
+
+MULTIPR_GUI_DecimateDlg::MULTIPR_GUI_DecimateDlg(MULTIPR_GUI* theModule) :
+       QDialog( theModule->application()->desktop(), 0, false, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
+{
+       mModule = theModule;
+       
+    buttonGroupSelectField = new QButtonGroup( this, "buttonGroupSelectField" );
+    buttonGroupSelectField->setGeometry( QRect( 10, 10, 450, 140 ) );
+
+    textLabelSelectFieldName = new QLabel( buttonGroupSelectField, "textLabelSelectFieldName" );
+    textLabelSelectFieldName->setGeometry( QRect( 30, 30, 141, 31 ) );
+
+    textLabelSelectFieldIteration = new QLabel( buttonGroupSelectField, "textLabelSelectFieldIteration" );
+    textLabelSelectFieldIteration->setGeometry( QRect( 30, 80, 111, 31 ) );
+
+       MULTIPR_ORB::string_array* listFields = theModule->getMULTIPRObj()->getFields();
+       int maxIteration = 0;
+       for (int i=0 ; i<listFields->length() ; i++)
+       {
+               const char* strItem = (*listFields)[i];
+               CORBA::Long nbIteration = theModule->getMULTIPRObj()->getTimeStamps(strItem);
+               if (nbIteration > maxIteration) 
+               {
+                       maxIteration = nbIteration;
+               }
+       }
+       
+    comboBoxSelectFieldIteration = new QComboBox( FALSE, buttonGroupSelectField, "comboBoxSelectFieldIteration" );
+    comboBoxSelectFieldIteration->setGeometry( QRect( 150, 80, 280, 40 ) );
+       for (int i=1 ; i<=maxIteration ; i++)
+       {
+               comboBoxSelectFieldIteration->insertItem(QString::number(i));
+       }
+
+    comboBoxSelectFieldName = new QComboBox( FALSE, buttonGroupSelectField, "comboBoxSelectFieldName" );
+    comboBoxSelectFieldName->setGeometry( QRect( 150, 30, 280, 40 ) );
+       for (int i=0 ; i<listFields->length() ; i++)
+       {
+               const char* strItem = (*listFields)[i];
+               comboBoxSelectFieldName->insertItem(strItem);
+       }
+       comboBoxSelectFieldName->setEditable(false);
+       QToolTip::add( comboBoxSelectFieldName, tr( "only scalar fields are listed (multi-component fields are not displayed)" ) );
+
+    buttonGroupSelectFilter = new QButtonGroup( this, "buttonGroupSelectFilter" );
+    buttonGroupSelectFilter->setGeometry( QRect( 10, 160, 450, 90 ) );
+
+    textLabelSelectFilter = new QLabel( buttonGroupSelectFilter, "textLabelSelectFilter" );
+    textLabelSelectFilter->setGeometry( QRect( 30, 30, 101, 31 ) );
+
+    comboBoxSelectFilter = new QComboBox( FALSE, buttonGroupSelectFilter, "comboBoxSelectFilter" );
+    comboBoxSelectFilter->setGeometry( QRect( 150, 30, 280, 40 ) );
+       comboBoxSelectFilter->insertItem("Filtre_GradientMoyen");
+
+    buttonGroupParameters = new QButtonGroup( this, "buttonGroupParameters" );
+    buttonGroupParameters->setGeometry( QRect( 10, 260, 450, 210 ) );
+
+    textLabelTMed = new QLabel( buttonGroupParameters, "textLabelTMed" );
+    textLabelTMed->setGeometry( QRect( 20, 40, 242, 30 ) );
+
+    textLabelTLow = new QLabel( buttonGroupParameters, "textLabelTLow" );
+    textLabelTLow->setGeometry( QRect( 20, 80, 208, 30 ) );
+
+    textLabelRadius = new QLabel( buttonGroupParameters, "textLabelRadius" );
+    textLabelRadius->setGeometry( QRect( 20, 120, 211, 30 ) );
+
+    textLabelBoxing = new QLabel( buttonGroupParameters, "textLabelBoxing" );
+    textLabelBoxing->setGeometry( QRect( 20, 160, 241, 30 ) );
+
+    lineEditTMed = new QLineEdit( buttonGroupParameters, "lineEditTMed" );
+    lineEditTMed->setGeometry( QRect( 320, 40, 111, 30 ) );
+
+    lineEditTLow = new QLineEdit( buttonGroupParameters, "lineEditTLow" );
+    lineEditTLow->setGeometry( QRect( 320, 80, 111, 30 ) );
+
+    lineEditRadius = new QLineEdit( buttonGroupParameters, "lineEditRadius" );
+    lineEditRadius->setGeometry( QRect( 320, 120, 111, 30 ) );
+
+    spinBoxBoxing = new QSpinBox( buttonGroupParameters, "spinBoxBoxing" );
+    spinBoxBoxing->setGeometry( QRect( 320, 160, 111, 30 ) );
+    spinBoxBoxing->setMaxValue( 200 );
+    spinBoxBoxing->setMinValue( 2 );
+    spinBoxBoxing->setValue( 100 );
+
+    buttonGroupProcess = new QButtonGroup( this, "buttonGroupProcess" );
+    buttonGroupProcess->setGeometry( QRect( 10, 480, 450, 60 ) );
+
+    pushButtonCancel = new QPushButton( buttonGroupProcess, "pushButtonCancel" );
+    pushButtonCancel->setGeometry( QRect( 321, 10, 110, 41 ) );
+
+    pushButtonOK = new QPushButton( buttonGroupProcess, "pushButtonOK" );
+    pushButtonOK->setGeometry( QRect( 10, 10, 110, 41 ) );
+    
+       setCaption( tr( "Decimation" ) );
+    buttonGroupSelectField->setTitle( tr( "Select field" ) );
+    textLabelSelectFieldName->setText( tr( "Field name" ) );
+    textLabelSelectFieldIteration->setText( tr( "Iteration" ) );
+    buttonGroupSelectFilter->setTitle( tr( "Select filter" ) );
+    textLabelSelectFilter->setText( tr( "Filter name" ) );
+    buttonGroupParameters->setTitle( tr( "Set parameters" ) );
+    textLabelTMed->setText( tr( "Threshold for medium resolution" ) );
+    textLabelTLow->setText( tr( "Threshold for low resolution" ) );
+    textLabelRadius->setText( tr( "Radius (neighborhood)" ) );
+    textLabelBoxing->setText( tr( "Boxing parameter" ) );
+    lineEditTMed->setText( tr( "0.1" ) );
+    lineEditTLow->setText( tr( "0.2" ) );
+
+       float defaultRadius = 0.5f;
+    lineEditRadius->setText( QString::number(defaultRadius) );
+    buttonGroupProcess->setTitle( QString::null );
+    pushButtonCancel->setText( tr( "Cancel" ) );
+    pushButtonOK->setText( tr("OK") );
+       
+       pushButtonThresholdAuto = new QPushButton( buttonGroupParameters, "pushButtonThresholdAuto" );
+    pushButtonThresholdAuto->setGeometry( QRect( 260, 80, 50, 30 ) );
+    QFont pushButtonThresholdAuto_font(  pushButtonThresholdAuto->font() );
+    pushButtonThresholdAuto_font.setPointSize( 11 );
+    pushButtonThresholdAuto->setFont( pushButtonThresholdAuto_font ); 
+       pushButtonThresholdAuto->setText( tr( "auto" ) );
+    QToolTip::add( pushButtonThresholdAuto, tr( "compute extremum for gradient (set medium=MIN and low=MAX)" ) );
+
+    pushButtonRadiusAuto = new QPushButton( buttonGroupParameters, "pushButtonRadiusAuto" );
+    pushButtonRadiusAuto->setGeometry( QRect( 260, 120, 50, 30 ) );
+    QFont pushButtonRadiusAuto_font(  pushButtonRadiusAuto->font() );
+    pushButtonRadiusAuto_font.setPointSize( 11 );
+    pushButtonRadiusAuto->setFont( pushButtonRadiusAuto_font ); 
+    pushButtonRadiusAuto->setText( tr( "auto" ) );
+    QToolTip::add( pushButtonRadiusAuto, tr( "set radius automatically (average #neighbours equal to 8)" ) );
+       
+    resize( QSize(470, 554).expandedTo(minimumSizeHint()) );
+    clearWState( WState_Polished );
+       
+       connect(pushButtonOK,            SIGNAL(clicked()), this, SLOT(accept()));
+       connect(pushButtonCancel,        SIGNAL(clicked()), this, SLOT(reject()));
+       connect(pushButtonRadiusAuto,    SIGNAL(clicked()), this, SLOT(OnRadiusAuto()));
+       connect(pushButtonThresholdAuto, SIGNAL(clicked()), this, SLOT(OnThresholdAuto()));
+}
+
+
+/*
+ *  Destroys the object and frees any allocated resources
+ */
+MULTIPR_GUI_DecimateDlg::~MULTIPR_GUI_DecimateDlg()
+{
+    // no need to delete child widgets, Qt does it all for us
+}
+
+
+void MULTIPR_GUI_DecimateDlg::accept()
+{      
+       const char* strFieldName = comboBoxSelectFieldName->currentText().latin1();
+       const char* strFieldIt   = comboBoxSelectFieldIteration->currentText().latin1();
+       int fieldIteration = atoi(strFieldIt);
+       
+       double thresholdMed;
+       int ret = sscanf(lineEditTMed->text().latin1(), "%lf", &thresholdMed);
+       if ((ret != 1) || (thresholdMed <= 0.0f))
+       {
+               SUIT_MessageBox::error1( 
+                       mModule->getAppli()->desktop(),
+                       "Decimation parameters error", 
+                       "Invalid medium threshold (should be > 0.0)", 
+                       tr("OK") );
+                       
+               return;
+       }
+
+       double thresholdLow;
+       ret = sscanf(lineEditTLow->text().latin1(), "%lf", &thresholdLow);
+       if ((ret != 1) || (thresholdLow <= 0.0f))
+       {
+               SUIT_MessageBox::error1( 
+                       mModule->getAppli()->desktop(),
+                       "Decimation parameters error", 
+                       "Invalid low threshold (should be > 0.0)", 
+                       tr("OK") );
+                       
+               return;
+       }
+       
+       if (thresholdMed >= thresholdLow)
+       {
+               SUIT_MessageBox::error1( 
+                       mModule->getAppli()->desktop(),
+                       "Decimation parameters error", 
+                       "Medium threshold must be < low threshold", 
+                       tr("OK") );
+                       
+               return;
+       }
+
+       double radius;
+       ret = sscanf(lineEditRadius->text().latin1(), "%lf", &radius);
+       if ((ret != 1) || (radius <= 0.0f))
+       {
+               SUIT_MessageBox::error1( 
+                       mModule->getAppli()->desktop(),
+                       "Decimation parameters error", 
+                       "Invalid radius (should be > 0.0)", 
+                       tr("OK") );
+                       
+               return;
+       }
+       
+       QApplication::setOverrideCursor(Qt::waitCursor);
+       
+       try
+       {
+               const QStringList& partsList = mModule->getSelectedParts();
+               for (QStringList::const_iterator it = partsList.begin(), last = partsList.end(); it != last; it++)
+               {
+                       const QString& partName = (*it);
+                       
+                       mModule->getMULTIPRObj()->setBoxing(spinBoxBoxing->value());
+                       
+                       mModule->getMULTIPRObj()->decimePartition(
+                               partName.latin1(),
+                               strFieldName,
+                               fieldIteration,
+                               comboBoxSelectFilter->currentText().latin1(),
+                               thresholdMed,
+                               thresholdLow,
+                               radius);
+               }
+       }
+       catch(...)
+       {
+               SUIT_MessageBox::error1( 
+                       mModule->getAppli()->desktop(),
+                       "Decimation error", 
+                       "Error while decimating selected part(s)", 
+                       tr("OK") );
+       }
+       
+       QApplication::restoreOverrideCursor();
+       QDialog::accept();
+}
+
+
+void MULTIPR_GUI_DecimateDlg::reject()
+{
+       QDialog::reject();
+}
+
+
+void MULTIPR_GUI_DecimateDlg::OnRadiusAuto()
+{
+       // evaluates default radius for the first selected part
+       const QStringList& partsList = mModule->getSelectedParts();
+       char* strPartInfo0 = mModule->getMULTIPRObj()->getPartInfo(partsList[0].latin1());
+       
+       char   lMeshName[256];
+       int    lId;
+       char   lPartName[256];
+       char   lPath[256];
+       char   lMEDFileName[256];
+       
+       // parse infos
+       int ret = sscanf(strPartInfo0, "%s %d %s %s %s", 
+               lMeshName,
+               &lId,
+               lPartName,
+               lPath,
+               lMEDFileName);
+       
+       QApplication::setOverrideCursor(Qt::waitCursor);
+       float defaultRadius = 0.5f;
+       try
+       {
+               multipr::Mesh* mesh = new multipr::Mesh();
+               mesh->readSequentialMED(lMEDFileName, lMeshName);
+               const int averageNumberOfNeighbours = 8;
+               defaultRadius = mesh->evalDefaultRadius(averageNumberOfNeighbours);
+               delete mesh;
+       }
+       catch (...)
+       {
+       }
+       QApplication::restoreOverrideCursor();
+       
+    lineEditRadius->setText( QString::number(defaultRadius) );
+}
+
+
+void MULTIPR_GUI_DecimateDlg::OnThresholdAuto()
+{
+       // evaluates default radius for the first selected part
+       const QStringList& partsList = mModule->getSelectedParts();
+       char* strPartInfo0 = mModule->getMULTIPRObj()->getPartInfo(partsList[0].latin1());
+       
+       char   lMeshName[256];
+       int    lId;
+       char   lPartName[256];
+       char   lPath[256];
+       char   lMEDFileName[256];
+       
+       // parse infos
+       int ret = sscanf(strPartInfo0, "%s %d %s %s %s", 
+               lMeshName,
+               &lId,
+               lPartName,
+               lPath,
+               lMEDFileName);
+       
+       QApplication::setOverrideCursor(Qt::waitCursor);
+       float defaultRadius = 0.5f;
+       try
+       {
+               multipr::Mesh* mesh = new multipr::Mesh();
+               mesh->readSequentialMED(lMEDFileName, lMeshName);
+               
+               multipr::DecimationFilter* filter =
+                       multipr::DecimationFilter::create(comboBoxSelectFilter->currentText().latin1());
+               
+               double gradMin = 0.1, gradAvg = 0.15, gradMax = 0.2;
+               
+               multipr::DecimationFilterGradAvg* filterGrad = dynamic_cast<multipr::DecimationFilterGradAvg*>(filter);
+               if (filterGrad)
+               {
+                       const char* strFieldIt   = comboBoxSelectFieldIteration->currentText().latin1();
+                       int fieldIteration = atoi(strFieldIt);
+                       
+                       double radius;
+                       ret = sscanf(lineEditRadius->text().latin1(), "%lf", &radius);
+                       if ((ret != 1) || (radius <= 0.0f))
+                       {
+                               SUIT_MessageBox::error1( 
+                                       mModule->getAppli()->desktop(),
+                                       "Decimation parameters error", 
+                                       "Invalid radius (should be > 0.0)", 
+                                       tr("OK") );
+                                       
+                               return;
+                       }
+                       
+                       filterGrad->getGradientInfo(
+                               mesh,
+                               comboBoxSelectFieldName->currentText().latin1(),
+                               fieldIteration,
+                               radius,
+                               spinBoxBoxing->value(),
+                               &gradMin,
+                               &gradAvg,
+                               &gradMax);
+               }
+               
+               delete filter;
+               delete mesh;
+               
+               lineEditTMed->setText( QString::number(gradMin) );
+               lineEditTLow->setText( QString::number(gradMax) );
+       }
+       catch (...)
+       {
+       }
+       QApplication::restoreOverrideCursor();
+}
+
+
+//*****************************************************************************
+// MULTIPR_GUI_ProgressCallbackDlg
+//*****************************************************************************
+
+MULTIPR_GUI_ProgressCallbackDlg::MULTIPR_GUI_ProgressCallbackDlg(QWidget* parent) :
+       QProgressDialog(parent, 0, false, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu)
+{
+       setLabel(new QLabel(this, "Please wait"));
+       setLabelText("Please wait");
+       setTotalSteps(100);
+}
+
+
+MULTIPR_GUI_ProgressCallbackDlg::~MULTIPR_GUI_ProgressCallbackDlg()
+{
+}
+
+
+void MULTIPR_GUI_ProgressCallbackDlg::start(const char* pTaskTitle, int pNumStep)
+{
+       setCaption(pTaskTitle);
+       MULTIPR_ProgressCallback::init(pNumStep);
+}
+
+
+void MULTIPR_GUI_ProgressCallbackDlg::done()
+{
+       setProgress(100);
+}
+
+       
+void MULTIPR_GUI_ProgressCallbackDlg::progress(float pPercent)
+{
+       setProgress(int(pPercent));
+}
+
+// EOF
diff --git a/src/MULTIPRGUI/MULTIPR_GUI_Dlg.h b/src/MULTIPRGUI/MULTIPR_GUI_Dlg.h
new file mode 100644 (file)
index 0000000..c43df01
--- /dev/null
@@ -0,0 +1,202 @@
+// Project MULTIPR, IOLS WP1.2.1 - EDF/CS
+// Partitioning/decimation module for the SALOME v3.2 platform
+
+/**
+ * \file    MULTIPR_GUI_Dlg.h
+ *
+ * \brief   MULTIPR GUI Dialog (QT)
+ *
+ * \author  Olivier LE ROUX - CS, Virtual Reality Dpt
+ * 
+ * \date    01/2007
+ */
+
+#ifndef __MULTIPR_GUI_DLG__
+#define __MULTIPR_GUI_DLG__
+
+
+//*****************************************************************************
+// Includes section
+//*****************************************************************************
+
+#include <SalomeApp_Module.h>
+#include <LightApp_DataObject.h>
+#include <LightApp_DataModel.h>
+#include <LightApp_RootObject.h>
+
+#include <SALOMEconfig.h>
+#include CORBA_CLIENT_HEADER(MULTIPR)
+
+#include <qdialog.h>
+#include <qprogressdialog.h>
+#include <qstring.h>
+#include <qvariant.h>
+
+#include "MULTIPR_ProgressCallback.hxx"
+
+
+//*****************************************************************************
+// Pre-declaration
+//*****************************************************************************
+
+class SalomeApp_Application;
+class CAM_Module;
+
+class QVBoxLayout;
+class QHBoxLayout;
+class QGridLayout;
+class QSpacerItem;
+class QButtonGroup;
+class QLabel;
+class QComboBox;
+class QLineEdit;
+class QSpinBox;
+class QPushButton;
+
+class MULTIPR_GUI;
+
+
+
+//*****************************************************************************
+// Class MULTIPR_GUI_Partition1Dlg
+// Dialog box used for extracting groups from sequential MED file
+//*****************************************************************************
+
+class MULTIPR_GUI_Partition1Dlg : public QDialog
+{
+    Q_OBJECT
+
+public:
+    MULTIPR_GUI_Partition1Dlg(MULTIPR_GUI* theModule);
+    ~MULTIPR_GUI_Partition1Dlg();
+
+    QButtonGroup* buttonGroupProcess;
+    QPushButton* pushButtonCancel;
+    QPushButton* pushButtonOK;
+    QButtonGroup* buttonGroupSelectMesh;
+    QComboBox* comboBoxSelectMesh;
+    QLabel* textLabelSelectMesh;
+
+protected slots:
+       void accept();
+       void reject();
+       
+private:
+       MULTIPR_GUI* mModule;
+
+};
+
+
+//*****************************************************************************
+// Class MULTIPR_GUI_Partition2Dlg
+// Dialog box used for splitting a group (use MEDSPLITTER)
+//*****************************************************************************
+
+class MULTIPR_GUI_Partition2Dlg : public QDialog
+{
+    Q_OBJECT
+
+public:
+    MULTIPR_GUI_Partition2Dlg(MULTIPR_GUI* theModule);
+    ~MULTIPR_GUI_Partition2Dlg();
+
+    QButtonGroup* buttonGroupSplitParameters;
+    QLabel* textLabelSelectNbParts;
+    QLabel* textLabelSelectSplitter;
+    QComboBox* comboBoxSelectSplitter;
+    QSpinBox* spinBoxNbParts;
+    QButtonGroup* buttonGroupProcess;
+    QPushButton* pushButtonOK;
+    QPushButton* pushButtonCancel;
+
+protected slots:
+       void accept();
+       void reject();
+
+private:
+       MULTIPR_GUI* mModule;
+};
+
+
+//*****************************************************************************
+// Class MULTIPR_GUI_DecimateDlg
+// Dialog box used for decimating mesh (compute 2 lower resolution: medium and low)
+//*****************************************************************************
+
+class MULTIPR_GUI_DecimateDlg : public QDialog
+{
+    Q_OBJECT
+
+public:
+    MULTIPR_GUI_DecimateDlg(MULTIPR_GUI* theModule);
+    ~MULTIPR_GUI_DecimateDlg();
+
+    QButtonGroup* buttonGroupSelectField;
+    QLabel* textLabelSelectFieldName;
+    QLabel* textLabelSelectFieldIteration;
+    QComboBox* comboBoxSelectFieldIteration;
+    QComboBox* comboBoxSelectFieldName;
+    QButtonGroup* buttonGroupSelectFilter;
+    QLabel* textLabelSelectFilter;
+    QComboBox* comboBoxSelectFilter;
+    QButtonGroup* buttonGroupParameters;
+    QLabel* textLabelTMed;
+    QLabel* textLabelTLow;
+    QLabel* textLabelRadius;
+    QLabel* textLabelBoxing;
+    QLineEdit* lineEditTMed;
+    QLineEdit* lineEditTLow;
+    QLineEdit* lineEditRadius;
+    QSpinBox* spinBoxBoxing;
+    QButtonGroup* buttonGroupProcess;
+    QPushButton* pushButtonCancel;
+    QPushButton* pushButtonOK;
+       QPushButton* pushButtonThresholdAuto;
+    QPushButton* pushButtonRadiusAuto;
+
+protected:
+
+protected slots:
+       void accept();
+       void reject();
+       void OnRadiusAuto();
+       void OnThresholdAuto();
+
+private:
+       MULTIPR_GUI* mModule;
+
+};
+
+
+//*****************************************************************************
+// Class MULTIPR_GUI_ProgressCallbackDlg
+//*****************************************************************************
+
+class MULTIPR_GUI_ProgressCallbackDlg : 
+       public QProgressDialog,
+       public MULTIPR_ProgressCallback
+       
+{
+       Q_OBJECT
+       
+public:
+
+       MULTIPR_GUI_ProgressCallbackDlg(QWidget* parent);
+       
+       ~MULTIPR_GUI_ProgressCallbackDlg();
+       
+       virtual void start(const char* pTaskTitle, int pNumStep);
+       
+       virtual void done();
+       
+protected:
+       
+       virtual void progress(float pPercent);
+};
+
+
+#endif // __MULTIPR_GUI_DLG__
+
+
+// EOF
+
diff --git a/src/MULTIPRGUI/MULTIPR_icons.po b/src/MULTIPRGUI/MULTIPR_icons.po
new file mode 100644 (file)
index 0000000..e7a6c52
--- /dev/null
@@ -0,0 +1,37 @@
+#  Copyright (C) 2005  CEA/DEN, EDF R&D
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# This is a Qt message file in .po format.  Each msgid starts with
+# a scope.  This scope should *NOT* be translated - eg. "Foo::Bar"
+# would be translated to "Pub", not "Foo::Pub".
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2002-05-28 10:57:43 AM CEST\n"
+"PO-Revision-Date: YYYY-MM-DD\n"
+"Last-Translator: FULLNAME <EMAIL@ADDRESS>\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+
+msgid "ICON_GET_BANNER"
+msgstr "ExecMULTIPR.png"
+
+msgid "ICON_IMPORT_MED"
+msgstr "MULTIPR_import_med.png"
+
+msgid "ICON_SAVE_MED"
+msgstr "MULTIPR_save_med.png"
diff --git a/src/MULTIPRGUI/MULTIPR_msg_en.po b/src/MULTIPRGUI/MULTIPR_msg_en.po
new file mode 100644 (file)
index 0000000..e85b5fc
--- /dev/null
@@ -0,0 +1,92 @@
+#  Copyright (C) 2005  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 MULTIPR_GUI ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# This is a Qt message file in .po format.  Each msgid starts with
+# a scope.  This scope should *NOT* be translated - eg. translating
+# from French to English, "Foo::Bar" would be translated to "Pub",
+# not "Foo::Pub".
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2003-11-19 03:10:19 PM CET\n"
+"PO-Revision-Date: YYYY-MM-DD\n"
+"Last-Translator: FULLNAME <EMAIL@ADDRESS>\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+
+msgid "MULTIPR_GUI::BUT_OK"
+msgstr "OKO"
+
+msgid "MULTIPR_GUI::BUT_CANCEL"
+msgstr "Cancel"
+
+msgid "TLT_IMPORT_FROM_MED_FILE"
+msgstr "Import from MED file"
+
+msgid "MEN_IMPORT_FROM_MED_FILE"
+msgstr "Import from MED file"
+
+msgid "STS_IMPORT_FROM_MED_FILE"
+msgstr "Call import from sequential or distributed MED file"
+
+msgid "TLT_SPLIT"
+msgstr "Split part"
+
+msgid "MEN_SPLIT"
+msgstr "Split part"
+
+msgid "STS_SPLIT"
+msgstr "Split selected parts of the current distributed mesh"
+
+msgid "TLT_DECIMATE"
+msgstr "Decimate"
+
+msgid "MEN_DECIMATE"
+msgstr "Decimate"
+
+msgid "STS_DECIMATE"
+msgstr "Decimate selected parts (build two new meshes at lower resolution)"
+
+msgid "TLT_SAVE"
+msgstr "Save distributed mesh"
+
+msgid "MEN_SAVE"
+msgstr "Save distributed mesh"
+
+msgid "STS_SAVE"
+msgstr "Save the current distributed MED file"
+
+msgid "MEN_FILE"
+msgstr "&File"
+
+msgid "MEN_FILE_MULTIPR"
+msgstr "Multipr"
+
+msgid "MEN_MULTIPR"
+msgstr "Multipr"
+
+msgid "TOOL_MULTIPR"
+msgstr "MULTIPR"
+
+msgid "FLT_ALL_FILES"
+msgstr "All Files (*.*)"
+
+msgid "FLT_MED_FILES"
+msgstr "MED Files (*.med)"
+
+msgid "USE_BUILD_PROGRESS"
+msgstr "Use build progress"
diff --git a/src/MULTIPRGUI/MULTIPR_msg_fr.po b/src/MULTIPRGUI/MULTIPR_msg_fr.po
new file mode 100644 (file)
index 0000000..3722623
--- /dev/null
@@ -0,0 +1,80 @@
+#  Copyright (C) 2005  CEA/DEN, EDF R&D
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# This is a Qt message file in .po format.  Each msgid starts with
+# a scope.  This scope should *NOT* be translated - eg. translating
+# from French to English, "Foo::Bar" would be translated to "Pub",
+# not "Foo::Pub".
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2003-11-19 03:10:25 PM CET\n"
+"PO-Revision-Date: YYYY-MM-DD\n"
+"Last-Translator: FULLNAME <EMAIL@ADDRESS>\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+
+#: MULTIPR_GUI.cxx:76
+msgid "MULTIPR_GUI::BUT_OK"
+msgstr "OK"
+
+#: MULTIPR_GUI.cxx:76
+msgid "MULTIPR_GUI::INF_MULTIPR_BANNER"
+msgstr "Information MULTIPR"
+
+#: MULTIPR_GUI.cxx:76
+msgid "MULTIPR_GUI::INF_MULTIPR_MENU"
+msgstr "Ceci est un simple test"
+
+#: MULTIPR_GUI.cxx:57
+msgid "MULTIPR_GUI::QUE_MULTIPR_LABEL"
+msgstr "Import Prénom"
+
+#: MULTIPR_GUI.cxx:57
+msgid "MULTIPR_GUI::QUE_MULTIPR_NAME"
+msgstr "Entrez votre prénom, s'il vous plait"
+
+msgid "TLT_MY_NEW_ITEM"
+msgstr "My menu item"
+
+msgid "MEN_MY_NEW_ITEM"
+msgstr "My menu item"
+
+msgid "STS_MY_NEW_ITEM"
+msgstr "Call my menu item"
+
+msgid "TLT_GET_BANNER"
+msgstr "Get MULTIPR banner"
+
+msgid "MEN_GET_BANNER"
+msgstr "Get banner"
+
+msgid "STS_GET_BANNER"
+msgstr "Get MULTIPR banner"
+
+msgid "MEN_FILE"
+msgstr "&File"
+
+msgid "MEN_FILE_MULTIPR"
+msgstr "Multipr"
+
+msgid "MEN_MULTIPR"
+msgstr "MULTIPR"
+
+msgid "TOOL_MULTIPR"
+msgstr "MULTIPR"
+
diff --git a/src/MULTIPRGUI/Makefile.in b/src/MULTIPRGUI/Makefile.in
new file mode 100644 (file)
index 0000000..212cb33
--- /dev/null
@@ -0,0 +1,51 @@
+#  Copyright (C) 2005  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
+#
+# source path
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@:@top_srcdir@/idl:$(top_builddir)/idl:${KERNEL_ROOT_DIR}/idl/salome
+
+@COMMENCE@
+
+# header files
+EXPORT_HEADERS=
+
+# .po files to transform in .qm
+PO_FILES =  MULTIPR_msg_en.po MULTIPR_msg_fr.po MULTIPR_icons.po
+
+# Libraries targets
+LIB = libMULTIPR.la
+LIB_SRC = MULTIPR_GUI.cxx MULTIPR_GUI_Dlg.cxx
+LIB_MOC = MULTIPR_GUI.h MULTIPR_GUI_Dlg.h
+
+
+LIB_CLIENT_IDL = SALOMEDS.idl SALOME_Exception.idl SALOME_ModuleCatalog.idl SALOMEDS_Attributes.idl SALOME_Component.idl SALOME_GenericObj.idl MULTIPR.idl Logger.idl
+
+LIB_SERVER_IDL =
+
+# additionnal information to compil and link file
+
+CPPFLAGS += $(QT_INCLUDES) $(OCC_INCLUDES) $(PYTHON_INCLUDES) $(BOOST_CPPFLAGS) $(KERNEL_CXXFLAGS) $(GUI_CXXFLAGS) $(MED2_INCLUDES) $(HDF5_INCLUDES) -I$(MED_ROOT_DIR)/include/salome
+CXXFLAGS += $(KERNEL_CXXFLAGS) $(GUI_CXXFLAGS)
+LDFLAGS += -lSalomeApp -lMULTIPREngine $(KERNEL_LDFLAGS) $(GUI_LDFLAGS) -lmed -lmedsplitter -lmedmem -lhdf5 -lmed_V2_1 -lSALOMELocalTrace $(MED2_LIBS) $(HDF5_LIBS) -L$(MED_ROOT_DIR)/lib/salome 
+
+
+
+@CONCLUDE@
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644 (file)
index 0000000..c8862d4
--- /dev/null
@@ -0,0 +1,35 @@
+#  Copyright (C) 2005  CEA/DEN, EDF R&D
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+#==============================================================================
+#  File      : Makefile.in
+#  Author    : O. LE ROUX, CS
+#  Project   : SALOME
+#==============================================================================
+
+# source path
+top_srcdir=@top_srcdir@
+top_builddir=..
+srcdir=@srcdir@
+VPATH=.:@srcdir@
+
+@COMMENCE@
+
+SUBDIRS = MULTIPR MULTIPRGUI
+
+@MODULE@