]> SALOME platform Git repositories - modules/smesh.git/commitdiff
Salome HOME
This commit was generated by cvs2git to create branch 'BR-D5-38-2003'.
authoradmin <salome-admin@opencascade.com>
Tue, 13 Sep 2005 11:31:53 +0000 (11:31 +0000)
committeradmin <salome-admin@opencascade.com>
Tue, 13 Sep 2005 11:31:53 +0000 (11:31 +0000)
Cherrypick from master 2005-09-13 11:31:52 UTC jfa <jfa@opencascade.com> 'Rool-back bad changes to the script':
    idl/SMESH_Hypothesis.idl
    resources/mesh_hypo_edit.png
    resources/mesh_merge_elements.png
    src/Driver/Driver_Mesh.h
    src/Driver/Driver_SMESHDS_Mesh.h
    src/DriverMED/DriverMED_Family.cxx
    src/SMDS/SMDS_EdgePosition.hxx
    src/SMDS/SMDS_FacePosition.hxx
    src/SMDS/SMDS_Mesh.cxx
    src/SMDS/SMDS_Mesh.hxx
    src/SMDS/SMDS_MeshElement.hxx
    src/SMDS/SMDS_MeshGroup.hxx
    src/SMDS/SMDS_MeshNode.hxx
    src/SMDS/SMDS_MeshObject.hxx
    src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx
    src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx
    src/SMDS/SMDS_Position.hxx
    src/SMDS/SMDS_SpacePosition.hxx
    src/SMDS/SMDS_VertexPosition.hxx
    src/SMESH/SMESH_HypoFilter.cxx
    src/SMESH/SMESH_HypoFilter.hxx
    src/SMESHDS/SMESHDS_Mesh.cxx
    src/SMESHDS/SMESHDS_SubMesh.cxx
    src/SMESHDS/SMESHDS_SubMesh.hxx
    src/SMESHGUI/SMESHGUI.cxx
    src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx
    src/SMESHGUI/SMESHGUI_GroupDlg.cxx
    src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx
    src/SMESHGUI/SMESHGUI_Selection.cxx
    src/SMESHGUI/SMESHGUI_VTKUtils.cxx
    src/SMESH_I/SMESH_1D_Algo_i.cxx
    src/SMESH_I/SMESH_1D_Algo_i.hxx
    src/SMESH_I/SMESH_2D_Algo_i.cxx
    src/SMESH_I/SMESH_2D_Algo_i.hxx
    src/SMESH_I/SMESH_3D_Algo_i.cxx
    src/SMESH_I/SMESH_3D_Algo_i.hxx
    src/SMESH_I/SMESH_Mesh_i.hxx
    src/SMESH_I/SMESH_subMesh_i.cxx
    src/SMESH_I/SMESH_subMesh_i.hxx
    src/SMESH_SWIG/Makefile.in
    src/SMESH_SWIG/SMESH_test.py
    src/StdMeshers/StdMeshers_Hexa_3D.cxx
    src/StdMeshers/StdMeshers_MEFISTO_2D.cxx
    src/StdMeshers/StdMeshers_Penta_3D.cxx
    src/StdMeshers_I/StdMeshers_Arithmetic1D_i.hxx
    src/StdMeshers_I/StdMeshers_Deflection1D_i.hxx
    src/StdMeshers_I/StdMeshers_LengthFromEdges_i.cxx
    src/StdMeshers_I/StdMeshers_LengthFromEdges_i.hxx
    src/StdMeshers_I/StdMeshers_LocalLength_i.hxx
    src/StdMeshers_I/StdMeshers_MaxElementArea_i.hxx
    src/StdMeshers_I/StdMeshers_MaxElementVolume_i.hxx
    src/StdMeshers_I/StdMeshers_NotConformAllowed_i.cxx
    src/StdMeshers_I/StdMeshers_NotConformAllowed_i.hxx
    src/StdMeshers_I/StdMeshers_Propagation_i.cxx
    src/StdMeshers_I/StdMeshers_Propagation_i.hxx
    src/StdMeshers_I/StdMeshers_StartEndLength_i.hxx

56 files changed:
idl/SMESH_Hypothesis.idl [new file with mode: 0644]
resources/mesh_hypo_edit.png [new file with mode: 0644]
resources/mesh_merge_elements.png [new file with mode: 0644]
src/Driver/Driver_Mesh.h [new file with mode: 0644]
src/Driver/Driver_SMESHDS_Mesh.h [new file with mode: 0644]
src/DriverMED/DriverMED_Family.cxx [new file with mode: 0644]
src/SMDS/SMDS_EdgePosition.hxx [new file with mode: 0644]
src/SMDS/SMDS_FacePosition.hxx [new file with mode: 0644]
src/SMDS/SMDS_Mesh.cxx [new file with mode: 0644]
src/SMDS/SMDS_Mesh.hxx [new file with mode: 0644]
src/SMDS/SMDS_MeshElement.hxx [new file with mode: 0644]
src/SMDS/SMDS_MeshGroup.hxx [new file with mode: 0644]
src/SMDS/SMDS_MeshNode.hxx [new file with mode: 0644]
src/SMDS/SMDS_MeshObject.hxx [new file with mode: 0644]
src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx [new file with mode: 0644]
src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx [new file with mode: 0644]
src/SMDS/SMDS_Position.hxx [new file with mode: 0644]
src/SMDS/SMDS_SpacePosition.hxx [new file with mode: 0644]
src/SMDS/SMDS_VertexPosition.hxx [new file with mode: 0644]
src/SMESH/SMESH_HypoFilter.cxx [new file with mode: 0644]
src/SMESH/SMESH_HypoFilter.hxx [new file with mode: 0644]
src/SMESHDS/SMESHDS_Mesh.cxx [new file with mode: 0644]
src/SMESHDS/SMESHDS_SubMesh.cxx [new file with mode: 0644]
src/SMESHDS/SMESHDS_SubMesh.hxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_GroupDlg.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx [new file with mode: 0755]
src/SMESHGUI/SMESHGUI_Selection.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_VTKUtils.cxx [new file with mode: 0644]
src/SMESH_I/SMESH_1D_Algo_i.cxx [new file with mode: 0644]
src/SMESH_I/SMESH_1D_Algo_i.hxx [new file with mode: 0644]
src/SMESH_I/SMESH_2D_Algo_i.cxx [new file with mode: 0644]
src/SMESH_I/SMESH_2D_Algo_i.hxx [new file with mode: 0644]
src/SMESH_I/SMESH_3D_Algo_i.cxx [new file with mode: 0644]
src/SMESH_I/SMESH_3D_Algo_i.hxx [new file with mode: 0644]
src/SMESH_I/SMESH_Mesh_i.hxx [new file with mode: 0644]
src/SMESH_I/SMESH_subMesh_i.cxx [new file with mode: 0644]
src/SMESH_I/SMESH_subMesh_i.hxx [new file with mode: 0644]
src/SMESH_SWIG/Makefile.in [new file with mode: 0644]
src/SMESH_SWIG/SMESH_test.py [new file with mode: 0644]
src/StdMeshers/StdMeshers_Hexa_3D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_MEFISTO_2D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Penta_3D.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Arithmetic1D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Deflection1D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_LengthFromEdges_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_LengthFromEdges_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_LocalLength_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_MaxElementArea_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_MaxElementVolume_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_NotConformAllowed_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_NotConformAllowed_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Propagation_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Propagation_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_StartEndLength_i.hxx [new file with mode: 0644]

diff --git a/idl/SMESH_Hypothesis.idl b/idl/SMESH_Hypothesis.idl
new file mode 100644 (file)
index 0000000..69832b9
--- /dev/null
@@ -0,0 +1,102 @@
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESH_Hypothesis.idl
+//  Author : Paul RASCLE, EDF
+//  $Header$
+
+#ifndef _SMESH_HYPOTHESIS_IDL_
+#define _SMESH_HYPOTHESIS_IDL_
+
+#include "SALOME_Exception.idl"
+#include "SALOME_GenericObj.idl"
+
+module SMESH
+{
+  enum Dimension
+  {
+    DIM_1D,
+    DIM_2D,
+    DIM_3D
+  };
+  
+  interface SMESH_Hypothesis : SALOME::GenericObj
+  {
+    /*!
+     * Get the Hypothesis typeName 
+     */
+    string GetName();
+
+    /*!
+     * Get the Hypothesis plugin library Name 
+     */
+    string GetLibName();
+
+    /*!
+     * Get the internal Id 
+     */
+    long GetId();
+    
+    /*!
+     * Verify whether hypothesis supports given entity type 
+     */
+    boolean IsDimSupported( in Dimension type );
+  };
+
+  typedef sequence<string> ListOfHypothesisName;
+
+  interface SMESH_Algo : SMESH_Hypothesis
+  {
+    /*!
+     * Get list of hypothesis that can be used with this algorithm
+     */
+    ListOfHypothesisName GetCompatibleHypothesis();
+
+  };
+
+  interface SMESH_1D_Algo : SMESH_Algo
+  {
+    /*!
+     * 
+     */
+  };
+
+  interface SMESH_2D_Algo : SMESH_Algo
+  {
+    /*!
+     * 
+     */
+  };
+
+  interface SMESH_3D_Algo : SMESH_Algo
+  {
+    /*!
+     * 
+     */
+  };
+};
+
+  // -----------------------------------------------------------------
+  // Specific Algorithms in separate idl file
+  // -----------------------------------------------------------------
+
+
+#endif
diff --git a/resources/mesh_hypo_edit.png b/resources/mesh_hypo_edit.png
new file mode 100644 (file)
index 0000000..8f61dea
Binary files /dev/null and b/resources/mesh_hypo_edit.png differ
diff --git a/resources/mesh_merge_elements.png b/resources/mesh_merge_elements.png
new file mode 100644 (file)
index 0000000..3bc292f
Binary files /dev/null and b/resources/mesh_merge_elements.png differ
diff --git a/src/Driver/Driver_Mesh.h b/src/Driver/Driver_Mesh.h
new file mode 100644 (file)
index 0000000..14ca22f
--- /dev/null
@@ -0,0 +1,63 @@
+//  SMESH Driver : implementaion of driver for reading and writing  
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : Mesh_Reader.h
+//  Module : SMESH
+
+#ifndef _INCLUDE_DRIVER_MESH
+#define _INCLUDE_DRIVER_MESH
+
+#include <string>
+
+#if defined WNT && defined WIN32 && defined DRIVER_EXPORTS
+#define DRIVER_WNT_EXPORT __declspec( dllexport )
+#else
+#define DRIVER_WNT_EXPORT
+#endif
+
+class DRIVER_WNT_EXPORT Driver_Mesh
+{
+ public:
+  Driver_Mesh();
+  virtual ~Driver_Mesh(){}
+
+  enum Status {
+    DRS_OK,
+    DRS_EMPTY,          // a file contains no mesh with the given name
+    DRS_WARN_RENUMBER,  // a file has overlapped ranges of element numbers,
+                        // so the numbers from the file are ignored
+    DRS_WARN_SKIP_ELEM, // some elements were skipped due to incorrect file data
+    DRS_FAIL            // general failure (exception etc.)
+  };
+
+  virtual Status Perform() = 0;
+  void SetMeshId(int theMeshId);
+  void SetFile(const std::string& theFileName);
+
+ protected:
+  std::string myFile;
+  int myMeshId;
+
+};
+
+#endif
diff --git a/src/Driver/Driver_SMESHDS_Mesh.h b/src/Driver/Driver_SMESHDS_Mesh.h
new file mode 100644 (file)
index 0000000..30e0595
--- /dev/null
@@ -0,0 +1,44 @@
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+
+#ifndef _INCLUDE_DRIVER_SMESHDS_MESH
+#define _INCLUDE_DRIVER_SMESHDS_MESH
+
+#include "Driver_Mesh.h"
+
+class SMESHDS_Mesh;
+
+#if defined WNT && defined WIN32 && defined DRIVER_EXPORTS
+#define DRIVER_WNT_EXPORT __declspec( dllexport )
+#else
+#define DRIVER_WNT_EXPORT
+#endif
+
+class DRIVER_WNT_EXPORT Driver_SMESHDS_Mesh: public Driver_Mesh
+{
+ public:
+  Driver_SMESHDS_Mesh();
+  void SetMesh(SMESHDS_Mesh *theMesh);
+  
+ protected:
+  SMESHDS_Mesh *myMesh;
+
+};
+
+#endif
diff --git a/src/DriverMED/DriverMED_Family.cxx b/src/DriverMED/DriverMED_Family.cxx
new file mode 100644 (file)
index 0000000..47a923d
--- /dev/null
@@ -0,0 +1,390 @@
+//  SMESH DriverMED : tool to split groups on families
+//
+//  Copyright (C) 2003  CEA
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+//  File   : DriverMED_Family.cxx
+//  Author : Julia DOROVSKIKH
+//  Module : SMESH
+//  $Header$
+
+#include "DriverMED_Family.h"
+#include "MED_Factory.hxx"
+
+#include <sstream>     
+
+using namespace std;
+
+//=============================================================================
+/*!
+ *  Split each group from list <aGroups> on some parts (families)
+ *  on the basis of the elements membership in other groups from this list.
+ *  Resulting families have no common elements.
+ */
+//=============================================================================
+list<DriverMED_FamilyPtr> DriverMED_Family::MakeFamilies
+                         (const map <int, SMESHDS_SubMesh*>& theSubMeshes,
+                          const list<SMESHDS_GroupBase*>& theGroups,
+                          const bool doGroupOfNodes,
+                          const bool doGroupOfEdges,
+                          const bool doGroupOfFaces,
+                          const bool doGroupOfVolumes)
+{
+  list<DriverMED_FamilyPtr> aFamilies;
+
+  string anAllNodesGroupName = "Group_Of_All_Nodes";
+  string anAllEdgesGroupName = "Group_Of_All_Edges";
+  string anAllFacesGroupName = "Group_Of_All_Faces";
+  string anAllVolumesGroupName = "Group_Of_All_Volumes";
+
+  // Reserve four ids for families of free elements
+  // (1 - nodes, -1 - edges, -2 - faces, -3 - volumes).
+  // 'Free' means here not belonging to any group.
+  int aNodeFamId = FIRST_NODE_FAMILY;
+  int aElemFamId = FIRST_ELEM_FAMILY;
+
+  // Process sub-meshes
+  map<int, SMESHDS_SubMesh*>::const_iterator aSMIter = theSubMeshes.begin();
+  for (; aSMIter != theSubMeshes.end(); aSMIter++)
+  {
+    if ( aSMIter->second->IsComplexSubmesh() )
+      continue; // submesh containing other submeshs
+    list<DriverMED_FamilyPtr> aSMFams = SplitByType((*aSMIter).second, (*aSMIter).first);
+    list<DriverMED_FamilyPtr>::iterator aSMFamsIter = aSMFams.begin();
+    for (; aSMFamsIter != aSMFams.end(); aSMFamsIter++)
+    {
+      DriverMED_FamilyPtr aFam2 = (*aSMFamsIter);
+
+      list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
+      while (aFamsIter != aFamilies.end())
+      {
+        DriverMED_FamilyPtr aFam1 = *aFamsIter;
+        list<DriverMED_FamilyPtr>::iterator aCurrIter = aFamsIter++;
+        if (aFam1->myType == aFam2->myType)
+        {
+          DriverMED_FamilyPtr aCommon (new DriverMED_Family);
+          aFam1->Split(aFam2, aCommon);
+          if (!aCommon->IsEmpty())
+          {
+            aFamilies.push_back(aCommon);
+          }
+          if (aFam1->IsEmpty())
+          {
+            aFamilies.erase(aCurrIter);
+          }
+          if (aFam2->IsEmpty()) break;
+        }
+      }
+      // The rest elements of family
+      if (!aFam2->IsEmpty())
+      {
+        aFamilies.push_back(aFam2);
+      }
+    }
+  }
+
+  // Process groups
+  list<SMESHDS_GroupBase*>::const_iterator aGroupsIter = theGroups.begin();
+  for (; aGroupsIter != theGroups.end(); aGroupsIter++)
+  {
+    DriverMED_FamilyPtr aFam2 (new DriverMED_Family);
+    aFam2->Init(*aGroupsIter);
+
+    list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
+    while (aFamsIter != aFamilies.end())
+    {
+      DriverMED_FamilyPtr aFam1 = *aFamsIter;
+      list<DriverMED_FamilyPtr>::iterator aCurrIter = aFamsIter++;
+      if (aFam1->myType == aFam2->myType)
+      {
+        DriverMED_FamilyPtr aCommon (new DriverMED_Family);
+        aFam1->Split(aFam2, aCommon);
+        if (!aCommon->IsEmpty())
+        {
+          aFamilies.push_back(aCommon);
+        }
+        if (aFam1->IsEmpty())
+        {
+          aFamilies.erase(aCurrIter);
+        }
+        if (aFam2->IsEmpty()) break;
+      }
+    }
+    // The rest elements of group
+    if (!aFam2->IsEmpty())
+    {
+      aFamilies.push_back(aFam2);
+    }
+  }
+
+  list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
+  for (; aFamsIter != aFamilies.end(); aFamsIter++)
+  {
+    DriverMED_FamilyPtr aFam = *aFamsIter;
+    if (aFam->myType == SMDSAbs_Node) {
+      aFam->SetId(aNodeFamId++);
+      if (doGroupOfNodes) aFam->myGroupNames.insert(anAllNodesGroupName);
+    }
+    else {
+      aFam->SetId(aElemFamId--);
+      if (aFam->myType == SMDSAbs_Edge) {
+        if (doGroupOfEdges) aFam->myGroupNames.insert(anAllEdgesGroupName);
+      }
+      else if (aFam->myType == SMDSAbs_Face) {
+        if (doGroupOfFaces) aFam->myGroupNames.insert(anAllFacesGroupName);
+      }
+      else if (aFam->myType == SMDSAbs_Volume) {
+        if (doGroupOfVolumes) aFam->myGroupNames.insert(anAllVolumesGroupName);
+      }
+    }
+  }
+
+  // Create families for elements, not belonging to any group
+  if (doGroupOfNodes)
+  {
+    DriverMED_FamilyPtr aFreeNodesFam (new DriverMED_Family);
+    aFreeNodesFam->SetId(REST_NODES_FAMILY);
+    aFreeNodesFam->myType = SMDSAbs_Node;
+    aFreeNodesFam->myGroupNames.insert(anAllNodesGroupName);
+    aFamilies.push_back(aFreeNodesFam);
+  }
+
+  if (doGroupOfEdges)
+  {
+    DriverMED_FamilyPtr aFreeEdgesFam (new DriverMED_Family);
+    aFreeEdgesFam->SetId(REST_EDGES_FAMILY);
+    aFreeEdgesFam->myType = SMDSAbs_Edge;
+    aFreeEdgesFam->myGroupNames.insert(anAllEdgesGroupName);
+    aFamilies.push_back(aFreeEdgesFam);
+  }
+
+  if (doGroupOfFaces)
+  {
+    DriverMED_FamilyPtr aFreeFacesFam (new DriverMED_Family);
+    aFreeFacesFam->SetId(REST_FACES_FAMILY);
+    aFreeFacesFam->myType = SMDSAbs_Face;
+    aFreeFacesFam->myGroupNames.insert(anAllFacesGroupName);
+    aFamilies.push_back(aFreeFacesFam);
+  }
+
+  if (doGroupOfVolumes)
+  {
+    DriverMED_FamilyPtr aFreeVolumesFam (new DriverMED_Family);
+    aFreeVolumesFam->SetId(REST_VOLUMES_FAMILY);
+    aFreeVolumesFam->myType = SMDSAbs_Volume;
+    aFreeVolumesFam->myGroupNames.insert(anAllVolumesGroupName);
+    aFamilies.push_back(aFreeVolumesFam);
+  }
+
+  DriverMED_FamilyPtr aNullFam (new DriverMED_Family);
+  aNullFam->SetId(0);
+  aNullFam->myType = SMDSAbs_All;
+  aFamilies.push_back(aNullFam);
+
+  return aFamilies;
+}
+
+//=============================================================================
+/*!
+ *  Create TFamilyInfo for this family
+ */
+//=============================================================================
+MED::PFamilyInfo 
+DriverMED_Family::GetFamilyInfo(const MED::PWrapper& theWrapper, 
+                               const MED::PMeshInfo& theMeshInfo) const
+{
+  string aValue;
+
+  ostringstream aStr;
+
+  aStr << "FAM_" << myId;
+  set<string>::const_iterator aGrIter = myGroupNames.begin();
+  for (; aGrIter != myGroupNames.end(); aGrIter++)
+  {
+    aStr << "_" << *aGrIter;
+  }
+
+  aValue = aStr.str();
+  /*
+  MED::TStringVector anAttrDescs (1, "");  // 1 attribute with empty description,
+  MED::TIntVector anAttrIds (1, myId);        // Id=0,
+  MED::TIntVector anAttrVals (1, myId);       // Value=0
+  */
+  
+  MED::PFamilyInfo anInfo = theWrapper->CrFamilyInfo(theMeshInfo,
+                                                    aValue,
+                                                    myId,
+                                                    myGroupNames);
+/*                                                  
+                                                   anAttrDescs,
+                                                   anAttrIds,
+                                                   anAttrVals);
+*/
+
+//  cout << endl;
+//  cout << "Groups: ";
+//  set<string>::iterator aGrIter = myGroupNames.begin();
+//  for (; aGrIter != myGroupNames.end(); aGrIter++)
+//  {
+//    cout << " " << *aGrIter;
+//  }
+//  cout << endl;
+//
+//  cout << "Elements: ";
+//  set<const SMDS_MeshElement *>::iterator anIter = myElements.begin();
+//  for (; anIter != myElements.end(); anIter++)
+//  {
+//    cout << " " << (*anIter)->GetID();
+//  }
+//  cout << endl;
+
+  return anInfo;
+}
+
+//=============================================================================
+/*!
+ *  Initialize the tool by SMESHDS_GroupBase
+ */
+//=============================================================================
+void DriverMED_Family::Init (SMESHDS_GroupBase* theGroup)
+{
+  // Elements
+  myElements.clear();
+  SMDS_ElemIteratorPtr elemIt = theGroup->GetElements();
+  while (elemIt->more())
+  {
+    myElements.insert(elemIt->next());
+  }
+
+  // Type
+  myType = theGroup->GetType();
+
+  // Groups list
+  myGroupNames.clear();
+  myGroupNames.insert(string(theGroup->GetStoreName()));
+}
+
+//=============================================================================
+/*!
+ *  Split <theSubMesh> on some parts (families)
+ *  on the basis of the elements type.
+ */
+//=============================================================================
+list<DriverMED_FamilyPtr> DriverMED_Family::SplitByType (SMESHDS_SubMesh* theSubMesh,
+                                                         const int        theId)
+{
+  list<DriverMED_FamilyPtr> aFamilies;
+  DriverMED_FamilyPtr aNodesFamily   (new DriverMED_Family);
+  DriverMED_FamilyPtr anEdgesFamily  (new DriverMED_Family);
+  DriverMED_FamilyPtr aFacesFamily   (new DriverMED_Family);
+  DriverMED_FamilyPtr aVolumesFamily (new DriverMED_Family);
+
+  char submeshGrpName[ 30 ];
+  sprintf( submeshGrpName, "SubMesh %d", theId );
+
+  SMDS_NodeIteratorPtr aNodesIter = theSubMesh->GetNodes();
+  while (aNodesIter->more())
+  {
+    const SMDS_MeshNode* aNode = aNodesIter->next();
+    aNodesFamily->AddElement(aNode);
+  }
+
+  SMDS_ElemIteratorPtr anElemsIter = theSubMesh->GetElements();
+  while (anElemsIter->more())
+  {
+    const SMDS_MeshElement* anElem = anElemsIter->next();
+    switch (anElem->GetType())
+    {
+    case SMDSAbs_Edge:
+      anEdgesFamily->AddElement(anElem);
+      break;
+    case SMDSAbs_Face:
+      aFacesFamily->AddElement(anElem);
+      break;
+    case SMDSAbs_Volume:
+      aVolumesFamily->AddElement(anElem);
+      break;
+    default:
+      break;
+    }
+  }
+
+  if (!aNodesFamily->IsEmpty()) {
+    aNodesFamily->SetType(SMDSAbs_Node);
+    aNodesFamily->AddGroupName(submeshGrpName);
+    aFamilies.push_back(aNodesFamily);
+  }
+  if (!anEdgesFamily->IsEmpty()) {
+    anEdgesFamily->SetType(SMDSAbs_Edge);
+    anEdgesFamily->AddGroupName(submeshGrpName);
+    aFamilies.push_back(anEdgesFamily);
+  }
+  if (!aFacesFamily->IsEmpty()) {
+    aFacesFamily->SetType(SMDSAbs_Face);
+    aFacesFamily->AddGroupName(submeshGrpName);
+    aFamilies.push_back(aFacesFamily);
+  }
+  if (!aVolumesFamily->IsEmpty()) {
+    aVolumesFamily->SetType(SMDSAbs_Volume);
+    aVolumesFamily->AddGroupName(submeshGrpName);
+    aFamilies.push_back(aVolumesFamily);
+  }
+
+  return aFamilies;
+}
+
+//=============================================================================
+/*!
+ *  Remove from <myElements> elements, common with <by>,
+ *  Remove from <by> elements, common with <myElements>,
+ *  Create family <common> from common elements, with combined groups list.
+ */
+//=============================================================================
+void DriverMED_Family::Split (DriverMED_FamilyPtr by,
+                              DriverMED_FamilyPtr common)
+{
+  // Elements
+  set<const SMDS_MeshElement *>::iterator anIter = by->myElements.begin();
+  while ( anIter != by->myElements.end())
+  {
+    if (myElements.find(*anIter) != myElements.end())
+    {
+      common->myElements.insert(*anIter);
+      myElements.erase(*anIter);
+      by->myElements.erase(anIter++);
+    }
+    else
+      anIter++;
+  }
+
+  if (!common->IsEmpty())
+  {
+    // Groups list
+    common->myGroupNames = myGroupNames;
+    set<string>::iterator aGrNamesIter = by->myGroupNames.begin();
+    for (; aGrNamesIter != by->myGroupNames.end(); aGrNamesIter++)
+    {
+      common->myGroupNames.insert(*aGrNamesIter);
+    }
+
+    // Type
+    common->myType = myType;
+  }
+}
diff --git a/src/SMDS/SMDS_EdgePosition.hxx b/src/SMDS/SMDS_EdgePosition.hxx
new file mode 100644 (file)
index 0000000..fd297d3
--- /dev/null
@@ -0,0 +1,60 @@
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMDS_EdgePosition.hxx
+//  Module : SMESH
+
+#ifndef _SMDS_EdgePosition_HeaderFile
+#define _SMDS_EdgePosition_HeaderFile
+
+#include "SMDS_Position.hxx"
+
+//#ifdef WNT
+//#include <SALOME_WNT.hxx>
+//#else
+//#define SALOME_WNT_EXPORT
+//#endif
+
+#if defined WNT && defined WIN32 && defined SMDS_EXPORTS
+#define SMDS_WNT_EXPORT __declspec( dllexport )
+#else
+#define SMDS_WNT_EXPORT
+#endif
+
+class SMDS_WNT_EXPORT SMDS_EdgePosition:public SMDS_Position
+{
+
+  public:
+       SMDS_EdgePosition(const int aEdgeId=0, const double aUParam=0);
+       const virtual double * Coords() const;
+       SMDS_TypeOfPosition GetTypeOfPosition() const;
+       void SetUParameter(double aUparam);
+       double GetUParameter() const;
+
+  private:
+
+       double myUParameter;
+
+};
+
+#endif
diff --git a/src/SMDS/SMDS_FacePosition.hxx b/src/SMDS/SMDS_FacePosition.hxx
new file mode 100644 (file)
index 0000000..8ca7413
--- /dev/null
@@ -0,0 +1,61 @@
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMDS_FacePosition.hxx
+//  Module : SMESH
+
+#ifndef _SMDS_FacePosition_HeaderFile
+#define _SMDS_FacePosition_HeaderFile
+
+#include "SMDS_Position.hxx"
+
+//#ifdef WNT
+//#include <SALOME_WNT.hxx>
+//#else
+//#define SALOME_WNT_EXPORT
+//#endif
+
+#if defined WNT && defined WIN32 && defined SMDS_EXPORTS
+#define SMDS_WNT_EXPORT __declspec( dllexport )
+#else
+#define SMDS_WNT_EXPORT
+#endif
+
+class SMDS_WNT_EXPORT SMDS_FacePosition:public SMDS_Position
+{
+
+  public:
+       SMDS_FacePosition(int aFaceId=0, double aUParam=0,
+               double aVParam=0);
+       const virtual double * Coords() const;
+       SMDS_TypeOfPosition GetTypeOfPosition() const;
+       void SetUParameter(double aUparam);
+       void SetVParameter(double aVparam);
+       double GetUParameter() const;
+       double GetVParameter() const;
+
+  private:
+       double myUParameter;
+       double myVParameter;
+};
+#endif
diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx
new file mode 100644 (file)
index 0000000..6381e54
--- /dev/null
@@ -0,0 +1,2203 @@
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+
+#ifdef _MSC_VER
+#pragma warning(disable:4786)
+#endif
+
+#include "utilities.h"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_VolumeOfNodes.hxx"
+#include "SMDS_VolumeOfFaces.hxx"
+#include "SMDS_FaceOfNodes.hxx"
+#include "SMDS_FaceOfEdges.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_PolygonalFaceOfNodes.hxx"
+
+#include <algorithm>
+#include <map>
+using namespace std;
+
+///////////////////////////////////////////////////////////////////////////////
+/// Create a new mesh object
+///////////////////////////////////////////////////////////////////////////////
+SMDS_Mesh::SMDS_Mesh()
+       :myParent(NULL),
+        myNodeIDFactory(new SMDS_MeshElementIDFactory()),
+       myElementIDFactory(new SMDS_MeshElementIDFactory()),
+       myHasConstructionEdges(false), myHasConstructionFaces(false),
+       myHasInverseElements(true)
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Create a new child mesh
+/// Note that the tree structure of SMDS_Mesh seems to be unused in this version
+/// (2003-09-08) of SMESH
+///////////////////////////////////////////////////////////////////////////////
+SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
+       :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
+       myElementIDFactory(parent->myElementIDFactory),
+       myHasConstructionEdges(false), myHasConstructionFaces(false),
+       myHasInverseElements(true)
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a submesh and add it to the current mesh
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_Mesh *SMDS_Mesh::AddSubMesh()
+{
+       SMDS_Mesh *submesh = new SMDS_Mesh(this);
+       myChildren.insert(myChildren.end(), submesh);
+       return submesh;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///create a MeshNode and add it to the current Mesh
+///An ID is automatically assigned to the node.
+///@return : The created node
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshNode * SMDS_Mesh::AddNode(double x, double y, double z)
+{
+  return SMDS_Mesh::AddNodeWithID(x,y,z,myNodeIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///create a MeshNode and add it to the current Mesh
+///@param ID : The ID of the MeshNode to create
+///@return : The created node or NULL if a node with this ID already exists
+///////////////////////////////////////////////////////////////////////////////
+SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
+{
+  // find the MeshNode corresponding to ID
+  const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
+  if(!node){
+    SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
+    myNodes.Add(node);
+    myNodeIDFactory->BindID(ID,node);
+    return node;
+  }else
+    return NULL;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// create a MeshEdge and add it to the current Mesh
+/// @return : The created MeshEdge
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(int idnode1, int idnode2, int ID) 
+{
+  SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
+  SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
+  if(!node1 || !node2) return NULL;
+  return SMDS_Mesh::AddEdgeWithID(node1, node2, ID);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// create a MeshEdge and add it to the current Mesh
+/// @return : The created MeshEdge
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshEdge* SMDS_Mesh::AddEdge(const SMDS_MeshNode * node1,
+                                 const SMDS_MeshNode * node2)
+{
+  return SMDS_Mesh::AddEdgeWithID(node1, node2, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Create a new edge and at it to the mesh
+/// @param idnode1 ID of the first node
+/// @param idnode2 ID of the second node
+/// @param ID ID of the edge to create
+/// @return The created edge or NULL if an element with this ID already exists or
+/// if input nodes are not found.
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
+                                       const SMDS_MeshNode * n2, 
+                                       int ID)
+{
+  SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
+  if(myElementIDFactory->BindID(ID, edge)) {
+    SMDS_MeshNode *node1,*node2;
+    node1=const_cast<SMDS_MeshNode*>(n1);
+    node2=const_cast<SMDS_MeshNode*>(n2);
+    node1->AddInverseElement(edge);
+    node2->AddInverseElement(edge);            
+    myEdges.Add(edge);
+    return edge;
+  } 
+  else {
+    delete edge;
+    return NULL;
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a triangle defined by its nodes. An ID is automatically affected to the
+/// Created face
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
+                                 const SMDS_MeshNode * n2,
+                                 const SMDS_MeshNode * n3)
+{
+  return SMDS_Mesh::AddFaceWithID(n1,n2,n3, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a triangle defined by its nodes IDs
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, int idnode2, int idnode3, int ID)
+{
+  SMDS_MeshNode * node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
+  SMDS_MeshNode * node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
+  SMDS_MeshNode * node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
+  if(!node1 || !node2 || !node3) return NULL;
+  return SMDS_Mesh::AddFaceWithID(node1, node2, node3, ID);    
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a triangle defined by its nodes
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
+                                        const SMDS_MeshNode * n2,
+                                        const SMDS_MeshNode * n3,
+                                        int ID)
+{
+  SMDS_MeshFace * face=createTriangle(n1, n2, n3);
+
+  if (!registerElement(ID, face)) {
+    RemoveElement(face, false);
+    face = NULL;
+  }
+  return face;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a quadrangle defined by its nodes. An ID is automatically affected to the
+/// created face
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshNode * n1,
+                                 const SMDS_MeshNode * n2,
+                                 const SMDS_MeshNode * n3,
+                                 const SMDS_MeshNode * n4)
+{
+  return SMDS_Mesh::AddFaceWithID(n1,n2,n3, n4, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a quadrangle defined by its nodes IDs
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(int idnode1, 
+                                       int idnode2, 
+                                       int idnode3,
+                                       int idnode4, 
+                                       int ID)
+{
+  SMDS_MeshNode *node1, *node2, *node3, *node4;
+  node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
+  node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
+  node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
+  node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
+  if(!node1 || !node2 || !node3 || !node4) return NULL;
+  return SMDS_Mesh::AddFaceWithID(node1, node2, node3, node4, ID);     
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a quadrangle defined by its nodes
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
+                                        const SMDS_MeshNode * n2,
+                                        const SMDS_MeshNode * n3,
+                                        const SMDS_MeshNode * n4,
+                                        int ID)
+{
+  SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4);
+
+  if (!registerElement(ID, face)) {
+    RemoveElement(face, false);
+    face = NULL;
+  }
+  return face;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a triangle defined by its edges. An ID is automatically assigned to the
+/// Created face
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
+                                  const SMDS_MeshEdge * e2,
+                                  const SMDS_MeshEdge * e3)
+{
+  if (!hasConstructionEdges())
+    return NULL;
+  return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a triangle defined by its edges
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
+                                        const SMDS_MeshEdge * e2,
+                                        const SMDS_MeshEdge * e3,
+                                        int ID)
+{
+  if (!hasConstructionEdges())
+    return NULL;
+  SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
+  myFaces.Add(face);
+
+  if (!registerElement(ID, face)) {
+    RemoveElement(face, false);
+    face = NULL;
+  }
+  return face;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a quadrangle defined by its edges. An ID is automatically assigned to the
+/// Created face
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
+                                  const SMDS_MeshEdge * e2,
+                                  const SMDS_MeshEdge * e3,
+                                  const SMDS_MeshEdge * e4)
+{
+  if (!hasConstructionEdges())
+    return NULL;
+  return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a quadrangle defined by its edges
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
+                                        const SMDS_MeshEdge * e2,
+                                        const SMDS_MeshEdge * e3,
+                                        const SMDS_MeshEdge * e4,
+                                        int ID)
+{
+  if (!hasConstructionEdges())
+    return NULL;
+  SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
+  myFaces.Add(face);
+
+  if (!registerElement(ID, face))
+  {
+    RemoveElement(face, false);
+    face = NULL;
+  }
+  return face;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new tetrahedron and add it to the mesh. 
+///@return The created tetrahedron 
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                     const SMDS_MeshNode * n2, 
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4)
+{
+  int ID = myElementIDFactory->GetFreeID();
+  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
+  if(v==NULL) myElementIDFactory->ReleaseID(ID);
+  return v;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new tetrahedron and add it to the mesh. 
+///@param ID The ID of the new volume
+///@return The created tetrahedron or NULL if an element with this ID already exists
+///or if input nodes are not found.
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, 
+                                            int idnode2,
+                                            int idnode3, 
+                                            int idnode4, 
+                                            int ID)
+{
+  SMDS_MeshNode *node1, *node2, *node3, *node4;
+  node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
+  node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
+  node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
+  node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
+  if(!node1 || !node2 || !node3 || !node4) return NULL;
+  return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, ID);
+}
+       
+///////////////////////////////////////////////////////////////////////////////
+///Create a new tetrahedron and add it to the mesh. 
+///@param ID The ID of the new volume
+///@return The created tetrahedron 
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                            const SMDS_MeshNode * n2,
+                                            const SMDS_MeshNode * n3,
+                                            const SMDS_MeshNode * n4,
+                                            int ID)
+{
+  SMDS_MeshVolume* volume;
+  if(hasConstructionFaces()) {
+    SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
+    SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
+    SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
+    SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
+    volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
+    myVolumes.Add(volume);
+  }
+  else if(hasConstructionEdges()) {
+    MESSAGE("Error : Not implemented");
+    return NULL;
+  }
+  else {
+    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
+    myVolumes.Add(volume);
+  }
+
+  if (!registerElement(ID, volume)) {
+    RemoveElement(volume, false);
+    volume = NULL;
+  }
+  return volume;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new pyramid and add it to the mesh. 
+///Nodes 1,2,3 and 4 define the base of the pyramid
+///@return The created pyramid 
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                     const SMDS_MeshNode * n2, 
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4, 
+                                     const SMDS_MeshNode * n5)
+{
+  int ID = myElementIDFactory->GetFreeID();
+  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
+  if(v==NULL) myElementIDFactory->ReleaseID(ID);
+  return v;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new pyramid and add it to the mesh. 
+///Nodes 1,2,3 and 4 define the base of the pyramid
+///@param ID The ID of the new volume
+///@return The created pyramid or NULL if an element with this ID already exists
+///or if input nodes are not found.
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, 
+                                            int idnode2,
+                                            int idnode3, 
+                                            int idnode4, 
+                                            int idnode5, 
+                                            int ID)
+{
+  SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
+  node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
+  node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
+  node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
+  node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
+  node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
+  if(!node1 || !node2 || !node3 || !node4 || !node5) return NULL;
+  return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, ID);
+}
+       
+///////////////////////////////////////////////////////////////////////////////
+///Create a new pyramid and add it to the mesh.
+///Nodes 1,2,3 and 4 define the base of the pyramid
+///@param ID The ID of the new volume
+///@return The created pyramid
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                            const SMDS_MeshNode * n2,
+                                            const SMDS_MeshNode * n3,
+                                            const SMDS_MeshNode * n4,
+                                            const SMDS_MeshNode * n5,
+                                            int ID)
+{
+  SMDS_MeshVolume* volume;
+  if(hasConstructionFaces()) {
+    SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
+    SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
+    SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
+    SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
+    volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
+    myVolumes.Add(volume);
+  }
+  else if(hasConstructionEdges()) {
+    MESSAGE("Error : Not implemented");
+    return NULL;
+  }
+  else {
+    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
+    myVolumes.Add(volume);
+  }
+
+  if (!registerElement(ID, volume)) {
+    RemoveElement(volume, false);
+    volume = NULL;
+  }
+  return volume;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new prism and add it to the mesh. 
+///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
+///@return The created prism 
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                     const SMDS_MeshNode * n2, 
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4, 
+                                     const SMDS_MeshNode * n5,
+                                     const SMDS_MeshNode * n6)
+{
+  int ID = myElementIDFactory->GetFreeID();
+  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
+  if(v==NULL) myElementIDFactory->ReleaseID(ID);
+  return v;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new prism and add it to the mesh. 
+///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
+///@param ID The ID of the new volume
+///@return The created prism or NULL if an element with this ID already exists
+///or if input nodes are not found.
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, 
+                                            int idnode2,
+                                            int idnode3, 
+                                            int idnode4, 
+                                            int idnode5, 
+                                            int idnode6, 
+                                            int ID)
+{
+  SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
+  node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
+  node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
+  node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
+  node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
+  node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
+  node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
+  if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6) return NULL;
+  return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6, ID);
+}
+       
+///////////////////////////////////////////////////////////////////////////////
+///Create a new prism and add it to the mesh.
+///Nodes 1,2,3 is a triangle and 1,2,5,4 a quadrangle.
+///@param ID The ID of the new volume
+///@return The created prism
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                            const SMDS_MeshNode * n2,
+                                            const SMDS_MeshNode * n3,
+                                            const SMDS_MeshNode * n4,
+                                            const SMDS_MeshNode * n5,
+                                            const SMDS_MeshNode * n6,
+                                            int ID)
+{
+  SMDS_MeshVolume* volume;
+  if(hasConstructionFaces()) {
+    SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
+    SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
+    SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n5,n2);
+    SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
+    SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
+    volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
+    myVolumes.Add(volume);
+  }
+  else if(hasConstructionEdges()) {
+    MESSAGE("Error : Not implemented");
+    return NULL;
+  }
+  else {
+    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
+    myVolumes.Add(volume);
+  }
+
+  if (!registerElement(ID, volume)) {
+    RemoveElement(volume, false);
+    volume = NULL;
+  }
+  return volume;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new hexahedron and add it to the mesh. 
+///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
+///@return The created hexahedron 
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                     const SMDS_MeshNode * n2, 
+                                     const SMDS_MeshNode * n3,
+                                     const SMDS_MeshNode * n4, 
+                                     const SMDS_MeshNode * n5,
+                                     const SMDS_MeshNode * n6, 
+                                     const SMDS_MeshNode * n7,
+                                     const SMDS_MeshNode * n8)
+{
+  int ID = myElementIDFactory->GetFreeID();
+  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
+  if(v==NULL) myElementIDFactory->ReleaseID(ID);
+  return v;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new hexahedron and add it to the mesh. 
+///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
+///@param ID The ID of the new volume
+///@return The created hexahedron or NULL if an element with this ID already
+///exists or if input nodes are not found.
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1, 
+                                            int idnode2,
+                                            int idnode3, 
+                                            int idnode4, 
+                                            int idnode5, 
+                                            int idnode6, 
+                                            int idnode7,
+                                            int idnode8, 
+                                            int ID)
+{
+  SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
+  node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
+  node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
+  node3 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode3);
+  node4 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode4);
+  node5 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode5);
+  node6 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode6);
+  node7 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode7);
+  node8 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode8);
+  if(!node1 || !node2 || !node3 || !node4 || !node5 || !node6 || !node7 || !node8)
+    return NULL;
+  return SMDS_Mesh::AddVolumeWithID(node1, node2, node3, node4, node5, node6,
+                                    node7, node8, ID);
+}
+       
+///////////////////////////////////////////////////////////////////////////////
+///Create a new hexahedron and add it to the mesh.
+///Nodes 1,2,3,4 and 5,6,7,8 are quadrangle and 5,1 and 7,3 are an edges.
+///@param ID The ID of the new volume
+///@return The created prism or NULL if an element with this ID already exists
+///or if input nodes are not found.
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                            const SMDS_MeshNode * n2,
+                                            const SMDS_MeshNode * n3,
+                                            const SMDS_MeshNode * n4,
+                                            const SMDS_MeshNode * n5,
+                                            const SMDS_MeshNode * n6,
+                                            const SMDS_MeshNode * n7,
+                                            const SMDS_MeshNode * n8,
+                                            int ID)
+{
+  SMDS_MeshVolume* volume;
+  if(hasConstructionFaces()) {
+    SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
+    SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
+    SMDS_MeshFace * f3=FindFaceOrCreate(n1,n4,n8,n5);
+    SMDS_MeshFace * f4=FindFaceOrCreate(n1,n2,n6,n5);
+    SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
+    SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
+    volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
+    myVolumes.Add(volume);
+  }
+  else if(hasConstructionEdges()) {
+    MESSAGE("Error : Not implemented");
+    return NULL;
+  }
+  else {
+//    volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
+    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
+    myVolumes.Add(volume);
+  }
+
+  if (!registerElement(ID, volume)) {
+    RemoveElement(volume, false);
+    volume = NULL;
+  }
+  return volume;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new tetrahedron defined by its faces and add it to the mesh.
+///@return The created tetrahedron
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
+                                      const SMDS_MeshFace * f2,
+                                      const SMDS_MeshFace * f3,
+                                      const SMDS_MeshFace * f4)
+{
+  if (!hasConstructionFaces())
+    return NULL;
+  return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new tetrahedron defined by its faces and add it to the mesh.
+///@param ID The ID of the new volume
+///@return The created tetrahedron 
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
+                                            const SMDS_MeshFace * f2,
+                                            const SMDS_MeshFace * f3,
+                                            const SMDS_MeshFace * f4,
+                                            int ID)
+{
+  if (!hasConstructionFaces())
+    return NULL;
+  SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
+  myVolumes.Add(volume);
+
+  if (!registerElement(ID, volume)) {
+    RemoveElement(volume, false);
+    volume = NULL;
+  }
+  return volume;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new pyramid defined by its faces and add it to the mesh.
+///@return The created pyramid
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
+                                      const SMDS_MeshFace * f2,
+                                      const SMDS_MeshFace * f3,
+                                      const SMDS_MeshFace * f4,
+                                      const SMDS_MeshFace * f5)
+{
+  if (!hasConstructionFaces())
+    return NULL;
+  return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new pyramid defined by its faces and add it to the mesh.
+///@param ID The ID of the new volume
+///@return The created pyramid 
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
+                                            const SMDS_MeshFace * f2,
+                                            const SMDS_MeshFace * f3,
+                                            const SMDS_MeshFace * f4,
+                                            const SMDS_MeshFace * f5,
+                                            int ID)
+{
+  if (!hasConstructionFaces())
+    return NULL;
+  SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
+  myVolumes.Add(volume);
+
+  if (!registerElement(ID, volume)) {
+    RemoveElement(volume, false);
+    volume = NULL;
+  }
+  return volume;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new prism defined by its faces and add it to the mesh.
+///@return The created prism
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
+                                      const SMDS_MeshFace * f2,
+                                      const SMDS_MeshFace * f3,
+                                      const SMDS_MeshFace * f4,
+                                      const SMDS_MeshFace * f5,
+                                      const SMDS_MeshFace * f6)
+{
+  if (!hasConstructionFaces())
+    return NULL;
+  return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a new prism defined by its faces and add it to the mesh.
+///@param ID The ID of the new volume
+///@return The created prism 
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
+                                            const SMDS_MeshFace * f2,
+                                            const SMDS_MeshFace * f3,
+                                            const SMDS_MeshFace * f4,
+                                            const SMDS_MeshFace * f5,
+                                            const SMDS_MeshFace * f6,
+                                            int ID)
+{
+  if (!hasConstructionFaces())
+    return NULL;
+  SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
+  myVolumes.Add(volume);
+
+  if (!registerElement(ID, volume)) {
+    RemoveElement(volume, false);
+    volume = NULL;
+  }
+  return volume;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a polygon defined by its nodes IDs
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
+                                                  const int        ID)
+{
+  int nbNodes = nodes_ids.size();
+  std::vector<const SMDS_MeshNode*> nodes (nbNodes);
+  for (int i = 0; i < nbNodes; i++) {
+    nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
+    if (!nodes[i]) return NULL;
+  }
+  return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID); 
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a polygon defined by its nodes
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
+                          (std::vector<const SMDS_MeshNode*> nodes,
+                           const int                         ID)
+{
+  SMDS_MeshFace * face;
+
+  if (hasConstructionEdges())
+  {
+    MESSAGE("Error : Not implemented");
+    return NULL;
+  }
+  else
+  {
+    face = new SMDS_PolygonalFaceOfNodes(nodes);
+    myFaces.Add(face);
+  }
+
+  if (!registerElement(ID, face)) {
+    RemoveElement(face, false);
+    face = NULL;
+  }
+  return face;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a polygon defined by its nodes.
+/// An ID is automatically affected to the created face.
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes)
+{
+  return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Create a new polyhedral volume and add it to the mesh. 
+/// @param ID The ID of the new volume
+/// @return The created volume or NULL if an element with this ID already exists
+/// or if input nodes are not found.
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
+                             (std::vector<int> nodes_ids,
+                              std::vector<int> quantities,
+                              const int        ID)
+{
+  int nbNodes = nodes_ids.size();
+  std::vector<const SMDS_MeshNode*> nodes (nbNodes);
+  for (int i = 0; i < nbNodes; i++) {
+    nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
+    if (!nodes[i]) return NULL;
+  }
+  return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Create a new polyhedral volume and add it to the mesh. 
+/// @param ID The ID of the new volume
+/// @return The created  volume
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
+                            (std::vector<const SMDS_MeshNode*> nodes,
+                             std::vector<int>                  quantities,
+                             const int                         ID)
+{
+  SMDS_MeshVolume* volume;
+  if (hasConstructionFaces()) {
+    MESSAGE("Error : Not implemented");
+    return NULL;
+  } else if (hasConstructionEdges()) {
+    MESSAGE("Error : Not implemented");
+    return NULL;
+  } else {
+    volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
+    myVolumes.Add(volume);
+  }
+
+  if (!registerElement(ID, volume)) {
+    RemoveElement(volume, false);
+    volume = NULL;
+  }
+  return volume;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Create a new polyhedral volume and add it to the mesh. 
+/// @return The created  volume
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
+                            (std::vector<const SMDS_MeshNode*> nodes,
+                             std::vector<int>                  quantities)
+{
+  int ID = myElementIDFactory->GetFreeID();
+  SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
+  if (v == NULL) myElementIDFactory->ReleaseID(ID);
+  return v;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Registers element with the given ID, maintains inverse connections
+///////////////////////////////////////////////////////////////////////////////
+bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
+{
+  if (myElementIDFactory->BindID(ID, element)) {
+    SMDS_ElemIteratorPtr it = element->nodesIterator();
+    while (it->more()) {
+      SMDS_MeshNode *node = static_cast<SMDS_MeshNode*>
+        (const_cast<SMDS_MeshElement*>(it->next()));
+      node->AddInverseElement(element);
+    }
+    return true;
+  }
+  return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the node whose ID is 'ID'.
+///////////////////////////////////////////////////////////////////////////////
+const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
+{
+  return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a triangle and add it to the current mesh. This methode do not bind a
+///ID to the create triangle.
+///////////////////////////////////////////////////////////////////////////////
+SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
+                                          const SMDS_MeshNode * node2,
+                                          const SMDS_MeshNode * node3)
+{
+       if(hasConstructionEdges())
+       {
+               SMDS_MeshEdge *edge1, *edge2, *edge3;
+               edge1=FindEdgeOrCreate(node1,node2);
+               edge2=FindEdgeOrCreate(node2,node3);
+               edge3=FindEdgeOrCreate(node3,node1);
+
+               SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
+               myFaces.Add(face);
+               return face;
+       }
+       else
+       {
+               SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
+               myFaces.Add(face);
+               return face;
+       }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a quadrangle and add it to the current mesh. This methode do not bind
+///a ID to the create triangle.
+///////////////////////////////////////////////////////////////////////////////
+SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
+                                           const SMDS_MeshNode * node2,
+                                           const SMDS_MeshNode * node3,
+                                           const SMDS_MeshNode * node4)
+{
+       if(hasConstructionEdges())
+       {
+               SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
+               edge1=FindEdgeOrCreate(node1,node2);
+               edge2=FindEdgeOrCreate(node2,node3);
+               edge3=FindEdgeOrCreate(node3,node4);
+               edge4=FindEdgeOrCreate(node4,node1);
+
+               SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
+               myFaces.Add(face);
+               return face;
+       }
+       else
+       {
+               SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
+               myFaces.Add(face);
+               return face;
+       }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Remove a node and all the elements which own this node
+///////////////////////////////////////////////////////////////////////////////
+
+void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
+{
+       RemoveElement(node, true);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Remove an edge and all the elements which own this edge
+///////////////////////////////////////////////////////////////////////////////
+
+void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
+{
+       RemoveElement(edge,true);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Remove an face and all the elements which own this face
+///////////////////////////////////////////////////////////////////////////////
+
+void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
+{
+       RemoveElement(face, true);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Remove a volume
+///////////////////////////////////////////////////////////////////////////////
+
+void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
+{
+       RemoveElement(volume, true);
+}
+
+//=======================================================================
+//function : RemoveFromParent
+//purpose  :
+//=======================================================================
+
+bool SMDS_Mesh::RemoveFromParent()
+{
+       if (myParent==NULL) return false;
+       else return (myParent->RemoveSubMesh(this));
+}
+
+//=======================================================================
+//function : RemoveSubMesh
+//purpose  :
+//=======================================================================
+
+bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
+{
+       bool found = false;
+
+       list<SMDS_Mesh *>::iterator itmsh=myChildren.begin();
+       for (; itmsh!=myChildren.end() && !found; itmsh++)
+       {
+               SMDS_Mesh * submesh = *itmsh;
+               if (submesh == aMesh)
+               {
+                       found = true;
+                       myChildren.erase(itmsh);
+               }
+       }
+
+       return found;
+}
+
+//=======================================================================
+//function : ChangeElementNodes
+//purpose  : 
+//=======================================================================
+
+bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
+                                   const SMDS_MeshNode    * nodes[],
+                                   const int                nbnodes)
+{
+  // keep current nodes of elem
+  set<const SMDS_MeshElement*> oldNodes;
+  SMDS_ElemIteratorPtr itn = elem->nodesIterator();
+  while(itn->more())
+    oldNodes.insert(  itn->next() );
+
+  // change nodes
+  bool Ok = false;
+  switch ( elem->GetType() )
+  {
+  case SMDSAbs_Edge: {
+    if ( nbnodes == 2 ) {
+      const SMDS_MeshEdge* edge = dynamic_cast<const SMDS_MeshEdge*>( elem );
+      if ( edge )
+        Ok = const_cast<SMDS_MeshEdge*>( edge )->ChangeNodes( nodes[0], nodes[1] );
+    }
+    break;
+  }
+  case SMDSAbs_Face: {
+    const SMDS_FaceOfNodes* face = dynamic_cast<const SMDS_FaceOfNodes*>( elem );
+    if ( face ) {
+      Ok = const_cast<SMDS_FaceOfNodes*>( face )->ChangeNodes( nodes, nbnodes );
+    } else {
+      /// ??? begin
+      const SMDS_PolygonalFaceOfNodes* face = dynamic_cast<const SMDS_PolygonalFaceOfNodes*>(elem);
+      if (face) {
+        Ok = const_cast<SMDS_PolygonalFaceOfNodes*>(face)->ChangeNodes(nodes, nbnodes);
+      }
+      /// ??? end
+    }
+    break;
+  }
+  //case SMDSAbs_PolygonalFace: {
+  //  const SMDS_PolygonalFaceOfNodes* face = dynamic_cast<const SMDS_PolygonalFaceOfNodes*>(elem);
+  //  if (face) {
+  //    Ok = const_cast<SMDS_PolygonalFaceOfNodes*>(face)->ChangeNodes(nodes, nbnodes);
+  //  }
+  //  break;
+  //}
+  case SMDSAbs_Volume: {
+    const SMDS_VolumeOfNodes* vol = dynamic_cast<const SMDS_VolumeOfNodes*>( elem );
+    if ( vol )
+      Ok = const_cast<SMDS_VolumeOfNodes*>( vol )->ChangeNodes( nodes, nbnodes );
+    break;
+  }
+  default:
+    MESSAGE ( "WRONG ELEM TYPE");
+  }
+
+  if ( Ok ) { // update InverseElements
+
+    // AddInverseElement to new nodes
+    for ( int i = 0; i < nbnodes; i++ )
+      if ( oldNodes.find( nodes[i] ) == oldNodes.end() )
+        // new node
+        const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
+      else
+        // remove from oldNodes a node that remains in elem
+        oldNodes.erase( nodes[i] );
+
+
+    // RemoveInverseElement from the nodes removed from elem
+    set<const SMDS_MeshElement*>::iterator it;
+    for ( it = oldNodes.begin(); it != oldNodes.end(); it++ )
+    {
+      SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
+        (const_cast<SMDS_MeshElement *>( *it ));
+      n->RemoveInverseElement( elem );
+    }
+  }
+
+  //MESSAGE ( "::ChangeNodes() Ok = " << Ok);
+
+  return Ok;
+}
+
+//=======================================================================
+//function : ChangePolyhedronNodes
+//purpose  : to change nodes of polyhedral volume
+//=======================================================================
+bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
+                                       std::vector<const SMDS_MeshNode*> nodes,
+                                       std::vector<int>                  quantities)
+{
+  if (elem->GetType() != SMDSAbs_Volume) {
+    MESSAGE("WRONG ELEM TYPE");
+    return false;
+  }
+
+  const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
+  if (!vol) {
+    return false;
+  }
+
+  // keep current nodes of elem
+  set<const SMDS_MeshElement*> oldNodes;
+  SMDS_ElemIteratorPtr itn = elem->nodesIterator();
+  while (itn->more()) {
+    oldNodes.insert(itn->next());
+  }
+
+  // change nodes
+  bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
+  if (!Ok) {
+    return false;
+  }
+
+  // update InverseElements
+
+  // AddInverseElement to new nodes
+  int nbnodes = nodes.size();
+  for (int i = 0; i < nbnodes; i++) {
+    if (oldNodes.find(nodes[i]) == oldNodes.end()) {
+      // new node
+      const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
+    } else {
+      // remove from oldNodes a node that remains in elem
+      oldNodes.erase(nodes[i]);
+    }
+  }
+
+  // RemoveInverseElement from the nodes removed from elem
+  set<const SMDS_MeshElement*>::iterator it;
+  for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
+    SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
+      (const_cast<SMDS_MeshElement *>( *it ));
+    n->RemoveInverseElement(elem);
+  }
+
+  return Ok;
+}
+
+//=======================================================================
+//function : FindEdge
+//purpose  :
+//=======================================================================
+
+const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
+{
+       const SMDS_MeshNode * node1=FindNode(idnode1);
+       const SMDS_MeshNode * node2=FindNode(idnode2);
+       if((node1==NULL)||(node2==NULL)) return NULL;
+       return FindEdge(node1,node2);
+}
+
+//#include "Profiler.h"
+const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
+                                         const SMDS_MeshNode * node2)
+{
+       const SMDS_MeshEdge * toReturn=NULL;
+       //PROFILER_Init();
+       //PROFILER_Set();
+       SMDS_ElemIteratorPtr it1=node1->edgesIterator();
+       //PROFILER_Get(0);
+       //PROFILER_Set();
+       while(it1->more())
+       {
+               const SMDS_MeshEdge * e=static_cast<const SMDS_MeshEdge *>
+                       (it1->next());
+               SMDS_ElemIteratorPtr it2=e->nodesIterator();
+               while(it2->more())
+               {
+                       if(it2->next()->GetID()==node2->GetID())
+                       {
+                               toReturn=e;
+                               break;
+                       }
+               }
+       }
+       //PROFILER_Get(1);
+       return toReturn;
+}
+
+
+SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
+       const SMDS_MeshNode * node2) 
+{
+       SMDS_MeshEdge * toReturn=NULL;
+       toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
+       if(toReturn==NULL)      
+       {
+          toReturn=new SMDS_MeshEdge(node1,node2);
+          myEdges.Add(toReturn);
+       } 
+       return toReturn;
+}
+
+//=======================================================================
+//function : FindFace
+//purpose  :
+//=======================================================================
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
+       int idnode3) const
+{
+       const SMDS_MeshNode * node1=FindNode(idnode1);
+       const SMDS_MeshNode * node2=FindNode(idnode2);
+       const SMDS_MeshNode * node3=FindNode(idnode3);
+       if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
+       return FindFace(node1, node2, node3);
+}
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace(
+               const SMDS_MeshNode *node1,
+               const SMDS_MeshNode *node2,
+               const SMDS_MeshNode *node3)
+{
+       const SMDS_MeshFace * face;
+       const SMDS_MeshElement * node;
+       bool node2found, node3found;
+
+       SMDS_ElemIteratorPtr it1=node1->facesIterator();
+       while(it1->more())
+       {
+               face=static_cast<const SMDS_MeshFace*>(it1->next());
+               if(face->NbNodes()!=3) continue;
+               SMDS_ElemIteratorPtr it2=face->nodesIterator();
+               node2found=false;
+               node3found=false;
+               while(it2->more())
+               {
+                       node=it2->next();
+                       if(node->GetID()==node2->GetID()) node2found=true;
+                       if(node->GetID()==node3->GetID()) node3found=true;
+               }
+               if(node2found&&node3found)
+                       return face;
+       }
+       return NULL;
+}
+
+SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
+               const SMDS_MeshNode *node1,
+               const SMDS_MeshNode *node2,
+               const SMDS_MeshNode *node3)
+{
+       SMDS_MeshFace * toReturn=NULL;
+       toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
+       if(toReturn==NULL)
+       {
+         toReturn=createTriangle(node1,node2,node3);
+       }
+       return toReturn;
+}
+
+//=======================================================================
+//function : FindFace
+//purpose  :
+//=======================================================================
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, int idnode3,
+       int idnode4) const
+{
+       const SMDS_MeshNode * node1=FindNode(idnode1);
+       const SMDS_MeshNode * node2=FindNode(idnode2);
+       const SMDS_MeshNode * node3=FindNode(idnode3);
+       const SMDS_MeshNode * node4=FindNode(idnode4);
+       if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)) return NULL;
+       return FindFace(node1, node2, node3, node4);
+}
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace(
+               const SMDS_MeshNode *node1,
+               const SMDS_MeshNode *node2,
+               const SMDS_MeshNode *node3,
+               const SMDS_MeshNode *node4)
+{
+       const SMDS_MeshFace * face;
+       const SMDS_MeshElement * node;
+       bool node2found, node3found, node4found;
+       SMDS_ElemIteratorPtr it1=node1->facesIterator();
+       while(it1->more())
+       {
+               face=static_cast<const SMDS_MeshFace *>(it1->next());
+               if(face->NbNodes()!=4) continue;
+               SMDS_ElemIteratorPtr it2=face->nodesIterator();
+               node2found=false;
+               node3found=false;
+               node4found=false;
+               while(it2->more())
+               {
+                       node=it2->next();
+                       if(node->GetID()==node2->GetID()) node2found=true;
+                       if(node->GetID()==node3->GetID()) node3found=true;
+                       if(node->GetID()==node4->GetID()) node4found=true;
+               }
+               if(node2found&&node3found&&node4found)
+                       return face;
+       }
+       return NULL;
+}
+
+SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
+               const SMDS_MeshNode *node1,
+               const SMDS_MeshNode *node2,
+               const SMDS_MeshNode *node3,
+               const SMDS_MeshNode *node4)
+{
+       SMDS_MeshFace * toReturn=NULL;
+       toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
+       if(toReturn==NULL)
+       {
+         toReturn=createQuadrangle(node1,node2,node3,node4);
+       }
+       return toReturn;
+}
+
+//=======================================================================
+//function : FindElement
+//purpose  :
+//=======================================================================
+
+const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
+{
+       return myElementIDFactory->MeshElement(IDelem);
+}
+
+//=======================================================================
+//function : FindFace
+//purpose  : find polygon
+//=======================================================================
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
+{
+  int nbnodes = nodes_ids.size();
+  std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
+  for (int inode = 0; inode < nbnodes; inode++) {
+    const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
+    if (node == NULL) return NULL;
+  }
+  return FindFace(poly_nodes);
+}
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
+{
+  int nbNodes = nodes.size();
+  if (nbNodes < 1) return NULL;
+
+  bool isFound = true;
+  const SMDS_MeshFace * face;
+  set<const SMDS_MeshFace *> faces;
+
+  for (int inode = 0; inode < nbNodes && isFound; inode++) {
+    set<const SMDS_MeshFace *> new_faces;
+
+    SMDS_ElemIteratorPtr itF = nodes[inode]->facesIterator();
+    while (itF->more()) {
+      face = static_cast<const SMDS_MeshFace *>(itF->next());
+      if (face->NbNodes() == nbNodes) {
+        if (inode == 0 || faces.find(face) != faces.end()) {
+          new_faces.insert(face);
+        }
+      }
+    }
+    faces = new_faces;
+    if (new_faces.size() == 0) {
+      isFound = false;
+    }
+  }
+
+  if (isFound)
+    return face;
+
+  return NULL;
+}
+
+//=======================================================================
+//function : DumpNodes
+//purpose  : 
+//=======================================================================
+
+void SMDS_Mesh::DumpNodes() const
+{
+       MESSAGE("dump nodes of mesh : ");
+       SMDS_NodeIteratorPtr itnode=nodesIterator();
+       while(itnode->more()) MESSAGE(itnode->next());
+}
+
+//=======================================================================
+//function : DumpEdges
+//purpose  : 
+//=======================================================================
+
+void SMDS_Mesh::DumpEdges() const
+{
+       MESSAGE("dump edges of mesh : ");
+       SMDS_EdgeIteratorPtr itedge=edgesIterator();
+       while(itedge->more()) MESSAGE(itedge->next());
+}
+
+//=======================================================================
+//function : DumpFaces
+//purpose  : 
+//=======================================================================
+
+void SMDS_Mesh::DumpFaces() const
+{
+       MESSAGE("dump faces of mesh : ");
+       SMDS_FaceIteratorPtr itface=facesIterator();
+       while(itface->more()) MESSAGE(itface->next());
+}
+
+//=======================================================================
+//function : DumpVolumes
+//purpose  : 
+//=======================================================================
+
+void SMDS_Mesh::DumpVolumes() const
+{
+       MESSAGE("dump volumes of mesh : ");
+       SMDS_VolumeIteratorPtr itvol=volumesIterator();
+       while(itvol->more()) MESSAGE(itvol->next());
+}
+
+//=======================================================================
+//function : DebugStats
+//purpose  : 
+//=======================================================================
+
+void SMDS_Mesh::DebugStats() const
+{
+       MESSAGE("Debug stats of mesh : ");
+
+       MESSAGE("===== NODES ====="<<NbNodes());
+       MESSAGE("===== EDGES ====="<<NbEdges());
+       MESSAGE("===== FACES ====="<<NbFaces());
+       MESSAGE("===== VOLUMES ====="<<NbVolumes());
+
+       MESSAGE("End Debug stats of mesh ");
+
+       //#ifdef DEB
+       
+       SMDS_NodeIteratorPtr itnode=nodesIterator();
+       int sizeofnodes = 0;
+       int sizeoffaces = 0;
+
+       while(itnode->more())
+       {
+               const SMDS_MeshNode *node = itnode->next();
+
+               sizeofnodes += sizeof(*node);
+               
+               SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
+               while(it->more())
+               {
+                       const SMDS_MeshElement *me = it->next();
+                       sizeofnodes += sizeof(me);
+               }
+
+       }
+
+       SMDS_FaceIteratorPtr itface=facesIterator();
+       while(itface->more())
+       {
+               const SMDS_MeshElement *face = itface->next();          
+               sizeoffaces += sizeof(*face);
+
+       }
+       MESSAGE("total size of node elements = " << sizeofnodes);;
+       MESSAGE("total size of face elements = " << sizeoffaces);;
+
+       //#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the number of nodes
+///////////////////////////////////////////////////////////////////////////////
+int SMDS_Mesh::NbNodes() const
+{
+       return myNodes.Size();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the number of edges (including construction edges)
+///////////////////////////////////////////////////////////////////////////////
+int SMDS_Mesh::NbEdges() const
+{
+       return myEdges.Size();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the number of faces (including construction faces)
+///////////////////////////////////////////////////////////////////////////////
+int SMDS_Mesh::NbFaces() const
+{
+       return myFaces.Size();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the number of volumes
+///////////////////////////////////////////////////////////////////////////////
+int SMDS_Mesh::NbVolumes() const
+{
+       return myVolumes.Size();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the number of child mesh of this mesh.
+/// Note that the tree structure of SMDS_Mesh seems to be unused in this version
+/// (2003-09-08) of SMESH
+///////////////////////////////////////////////////////////////////////////////
+int SMDS_Mesh::NbSubMesh() const
+{
+       return myChildren.size();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Destroy the mesh and all its elements
+/// All pointer on elements owned by this mesh become illegals.
+///////////////////////////////////////////////////////////////////////////////
+SMDS_Mesh::~SMDS_Mesh()
+{
+  list<SMDS_Mesh*>::iterator itc=myChildren.begin();
+  while(itc!=myChildren.end())
+  {
+    delete *itc;
+    itc++;
+  }
+
+  SetOfNodes::Iterator itn(myNodes);
+  for (; itn.More(); itn.Next())
+    delete itn.Value();
+
+  SetOfEdges::Iterator ite(myEdges);
+  for (; ite.More(); ite.Next())
+  {
+    SMDS_MeshElement* elem = ite.Value();
+    if(myParent!=NULL)
+      myElementIDFactory->ReleaseID(elem->GetID());
+    delete elem;
+  }
+
+  SetOfFaces::Iterator itf(myFaces);
+  for (; itf.More(); itf.Next())
+  {
+    SMDS_MeshElement* elem = itf.Value();
+    if(myParent!=NULL)
+      myElementIDFactory->ReleaseID(elem->GetID());
+    delete elem;
+  }
+
+  SetOfVolumes::Iterator itv(myVolumes);
+  for (; itv.More(); itv.Next())
+  {
+    SMDS_MeshElement* elem = itv.Value();
+    if(myParent!=NULL)
+      myElementIDFactory->ReleaseID(elem->GetID());
+    delete elem;
+  }
+
+  if(myParent==NULL)
+  {
+    delete myNodeIDFactory;
+    delete myElementIDFactory;
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return true if this mesh create faces with edges.
+/// A false returned value mean that faces are created with nodes. A concequence
+/// is, iteration on edges (SMDS_Element::edgesIterator) will be unavailable.
+///////////////////////////////////////////////////////////////////////////////
+bool SMDS_Mesh::hasConstructionEdges()
+{
+       return myHasConstructionEdges;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return true if this mesh create volumes with faces
+/// A false returned value mean that volumes are created with nodes or edges.
+/// (see hasConstructionEdges)
+/// A concequence is, iteration on faces (SMDS_Element::facesIterator) will be
+/// unavailable.
+///////////////////////////////////////////////////////////////////////////////
+bool SMDS_Mesh::hasConstructionFaces()
+{
+       return myHasConstructionFaces;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return true if nodes are linked to the finit elements, they are belonging to.
+/// Currently, It always return true.
+///////////////////////////////////////////////////////////////////////////////
+bool SMDS_Mesh::hasInverseElements()
+{
+       return myHasInverseElements;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Make this mesh creating construction edges (see hasConstructionEdges)
+/// @param b true to have construction edges, else false.
+///////////////////////////////////////////////////////////////////////////////
+void SMDS_Mesh::setConstructionEdges(bool b)
+{
+       myHasConstructionEdges=b;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Make this mesh creating construction faces (see hasConstructionFaces)
+/// @param b true to have construction faces, else false.
+///////////////////////////////////////////////////////////////////////////////
+void SMDS_Mesh::setConstructionFaces(bool b)
+{
+        myHasConstructionFaces=b;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Make this mesh creating link from nodes to elements (see hasInverseElements)
+/// @param b true to link nodes to elements, else false.
+///////////////////////////////////////////////////////////////////////////////
+void SMDS_Mesh::setInverseElements(bool b)
+{
+       if(!b) MESSAGE("Error : inverseElement=false not implemented");
+       myHasInverseElements=b;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return an iterator on nodes of the current mesh factory
+///////////////////////////////////////////////////////////////////////////////
+class SMDS_Mesh_MyNodeIterator:public SMDS_NodeIterator
+{
+  SMDS_ElemIteratorPtr myIterator;
+ public:
+  SMDS_Mesh_MyNodeIterator(const SMDS_ElemIteratorPtr& it):myIterator(it)
+  {}
+
+  bool more()
+  {
+    return myIterator->more();
+  }
+
+  const SMDS_MeshNode* next()
+  {
+    return static_cast<const SMDS_MeshNode*>(myIterator->next());
+  }
+};
+
+SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator() const
+{
+  return SMDS_NodeIteratorPtr
+    (new SMDS_Mesh_MyNodeIterator(myNodeIDFactory->elementsIterator()));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return an iterator on elements of the current mesh factory
+///////////////////////////////////////////////////////////////////////////////
+SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator() const
+{
+  return myElementIDFactory->elementsIterator();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Return an iterator on edges of the current mesh.
+///////////////////////////////////////////////////////////////////////////////
+class SMDS_Mesh_MyEdgeIterator:public SMDS_EdgeIterator
+{
+  typedef SMDS_Mesh::SetOfEdges SetOfEdges;
+  SetOfEdges::Iterator myIterator;
+ public:
+  SMDS_Mesh_MyEdgeIterator(const SetOfEdges& s):myIterator(s)
+  {}
+
+  bool more()
+  {
+    while(myIterator.More())
+    {
+      if(myIterator.Value()->GetID()!=-1)
+        return true;
+      myIterator.Next();
+    }
+    return false;
+  }
+
+  const SMDS_MeshEdge* next()
+  {
+    const SMDS_MeshEdge* current = myIterator.Value();
+    myIterator.Next();
+    return current;
+  }
+};
+
+SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const
+{
+  return SMDS_EdgeIteratorPtr(new SMDS_Mesh_MyEdgeIterator(myEdges));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Return an iterator on faces of the current mesh.
+///////////////////////////////////////////////////////////////////////////////
+class SMDS_Mesh_MyFaceIterator:public SMDS_FaceIterator
+{
+  typedef SMDS_Mesh::SetOfFaces SetOfFaces;
+  SetOfFaces::Iterator myIterator;
+ public:
+  SMDS_Mesh_MyFaceIterator(const SetOfFaces& s):myIterator(s)
+  {}
+
+  bool more()
+  {
+    while(myIterator.More())
+    {
+      if(myIterator.Value()->GetID()!=-1)
+        return true;
+      myIterator.Next();
+    }
+    return false;
+  }
+
+  const SMDS_MeshFace* next()
+  {
+    const SMDS_MeshFace* current = myIterator.Value();
+    myIterator.Next();
+    return current;
+  }
+};
+
+SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const
+{
+  return SMDS_FaceIteratorPtr(new SMDS_Mesh_MyFaceIterator(myFaces));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Return an iterator on volumes of the current mesh.
+///////////////////////////////////////////////////////////////////////////////
+class SMDS_Mesh_MyVolumeIterator:public SMDS_VolumeIterator
+{
+  typedef SMDS_Mesh::SetOfVolumes SetOfVolumes;
+  SetOfVolumes::Iterator myIterator;
+ public:
+  SMDS_Mesh_MyVolumeIterator(const SetOfVolumes& s):myIterator(s)
+  {}
+
+  bool more()
+  {
+    return myIterator.More() != Standard_False;
+  }
+
+  const SMDS_MeshVolume* next()
+  {
+    const SMDS_MeshVolume* current = myIterator.Value();
+    myIterator.Next();
+    return current;
+  }
+};
+
+SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const
+{
+  return SMDS_VolumeIteratorPtr(new SMDS_Mesh_MyVolumeIterator(myVolumes));
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Do intersection of sets (more than 2)
+///////////////////////////////////////////////////////////////////////////////
+static set<const SMDS_MeshElement*> * intersectionOfSets(
+       set<const SMDS_MeshElement*> vs[], int numberOfSets)
+{
+       set<const SMDS_MeshElement*>* rsetA=new set<const SMDS_MeshElement*>(vs[0]);
+       set<const SMDS_MeshElement*>* rsetB;
+
+       for(int i=0; i<numberOfSets-1; i++)
+       {
+               rsetB=new set<const SMDS_MeshElement*>();
+               set_intersection(
+                       rsetA->begin(), rsetA->end(),
+                       vs[i+1].begin(), vs[i+1].end(),
+                       inserter(*rsetB, rsetB->begin()));
+               delete rsetA;
+               rsetA=rsetB;
+       }
+       return rsetA;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the list of finit elements owning the given element
+///////////////////////////////////////////////////////////////////////////////
+static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
+{
+       int numberOfSets=element->NbNodes();
+       set<const SMDS_MeshElement*> *initSet = new set<const SMDS_MeshElement*>[numberOfSets];
+
+       SMDS_ElemIteratorPtr itNodes=element->nodesIterator();
+
+       int i=0;
+       while(itNodes->more())
+       {
+               const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
+               SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
+
+               //initSet[i]=set<const SMDS_MeshElement*>();
+               while(itFe->more())
+                  initSet[i].insert(itFe->next());
+
+               i++;
+       }
+       set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
+        delete [] initSet;
+       return retSet;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the list of nodes used only by the given elements
+///////////////////////////////////////////////////////////////////////////////
+static set<const SMDS_MeshElement*> * getExclusiveNodes(
+       set<const SMDS_MeshElement*>& elements)
+{
+       set<const SMDS_MeshElement*> * toReturn=new set<const SMDS_MeshElement*>();
+       set<const SMDS_MeshElement*>::iterator itElements=elements.begin();
+
+       while(itElements!=elements.end())
+       {
+               SMDS_ElemIteratorPtr itNodes = (*itElements)->nodesIterator();
+               itElements++;
+       
+               while(itNodes->more())
+               {
+                       const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
+                       SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
+                       set<const SMDS_MeshElement*> s;
+                       while(itFe->more())
+                          s.insert(itFe->next());
+                       if(s==elements) toReturn->insert(n);
+               }
+       }
+       return toReturn;        
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Find the children of an element that are made of given nodes 
+///@param setOfChildren The set in which matching children will be inserted
+///@param element The element were to search matching children
+///@param nodes The nodes that the children must have to be selected
+///////////////////////////////////////////////////////////////////////////////
+void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>&     setOfChildren, 
+       const SMDS_MeshElement * element, set<const SMDS_MeshElement*>& nodes)
+{
+       
+       switch(element->GetType())
+       {
+       case SMDSAbs_Node:
+               MESSAGE("Internal Error: This should not append");
+               break;
+       case SMDSAbs_Edge:
+       {
+               SMDS_ElemIteratorPtr itn=element->nodesIterator();
+               while(itn->more())
+               {
+                       const SMDS_MeshElement * e=itn->next();
+                       if(nodes.find(e)!=nodes.end())
+                        {
+                          setOfChildren.insert(element);
+                          break;
+                        }
+               }
+       } break;
+       case SMDSAbs_Face:
+       {
+               SMDS_ElemIteratorPtr itn=element->nodesIterator();
+               while(itn->more())
+               {
+                       const SMDS_MeshElement * e=itn->next();
+                       if(nodes.find(e)!=nodes.end())
+                        {
+                          setOfChildren.insert(element);
+                          break;
+                        }
+               }
+               if(hasConstructionEdges())
+               {
+                       SMDS_ElemIteratorPtr ite=element->edgesIterator();
+                       while(ite->more())
+                               addChildrenWithNodes(setOfChildren, ite->next(), nodes);
+               }
+       } break;        
+       case SMDSAbs_Volume:
+       {
+               if(hasConstructionFaces())
+               {
+                       SMDS_ElemIteratorPtr ite=element->facesIterator();
+                       while(ite->more())
+                               addChildrenWithNodes(setOfChildren, ite->next(), nodes);
+               }
+               else if(hasConstructionEdges())
+               {
+                       SMDS_ElemIteratorPtr ite=element->edgesIterator();
+                       while(ite->more())
+                               addChildrenWithNodes(setOfChildren, ite->next(), nodes);
+               }
+       }
+       }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///@param elem The element to delete
+///@param removenodes if true remaining nodes will be removed
+///////////////////////////////////////////////////////////////////////////////
+void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
+       const bool removenodes)
+{
+  list<const SMDS_MeshElement *> removedElems;
+  list<const SMDS_MeshElement *> removedNodes;
+  RemoveElement( elem, removedElems, removedNodes, removenodes );
+}
+  
+///////////////////////////////////////////////////////////////////////////////
+///@param elem The element to delete
+///@param removedElems contains all removed elements
+///@param removedNodes contains all removed nodes
+///@param removenodes if true remaining nodes will be removed
+///////////////////////////////////////////////////////////////////////////////
+void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
+                              list<const SMDS_MeshElement *>& removedElems,
+                              list<const SMDS_MeshElement *>& removedNodes,
+                              bool                            removenodes)
+{
+  // get finite elements built on elem
+  set<const SMDS_MeshElement*> * s1;
+  if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
+      !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face ||
+      elem->GetType() == SMDSAbs_Volume)
+  {
+    s1 = new set<const SMDS_MeshElement*>();
+    s1->insert(elem);
+  }
+  else
+    s1 = getFinitElements(elem);
+
+  // get exclusive nodes (which would become free afterwards)
+  set<const SMDS_MeshElement*> * s2;
+  if (elem->GetType() == SMDSAbs_Node) // a node is removed
+  {
+    // do not remove nodes except elem
+    s2 = new set<const SMDS_MeshElement*>();
+    s2->insert(elem);
+    removenodes = true;
+  }
+  else
+    s2 = getExclusiveNodes(*s1);
+
+  // form the set of finite and construction elements to remove
+  set<const SMDS_MeshElement*> s3;
+  set<const SMDS_MeshElement*>::iterator it=s1->begin();
+  while(it!=s1->end())
+  {
+    addChildrenWithNodes(s3, *it ,*s2);
+    s3.insert(*it);
+    it++;
+  }
+  if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
+
+  // remove finite and construction elements
+  it=s3.begin();
+  while(it!=s3.end())
+  {
+    // Remove element from <InverseElements> of its nodes
+    SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
+    while(itn->more())
+    {
+      SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
+        (const_cast<SMDS_MeshElement *>(itn->next()));
+      n->RemoveInverseElement( (*it) );
+    }
+
+    switch((*it)->GetType())
+    {
+    case SMDSAbs_Node:
+      MESSAGE("Internal Error: This should not happen");
+      break;
+    case SMDSAbs_Edge:
+      myEdges.Remove(static_cast<SMDS_MeshEdge*>
+                    (const_cast<SMDS_MeshElement*>(*it)));
+      break;
+    case SMDSAbs_Face:
+      myFaces.Remove(static_cast<SMDS_MeshFace*>
+                    (const_cast<SMDS_MeshElement*>(*it)));
+      break;
+    case SMDSAbs_Volume:
+      myVolumes.Remove(static_cast<SMDS_MeshVolume*>
+                      (const_cast<SMDS_MeshElement*>(*it)));
+      break;
+    }
+    //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
+    removedElems.push_back( (*it) );
+    myElementIDFactory->ReleaseID((*it)->GetID());
+    delete (*it);
+    it++;
+  }
+
+  // remove exclusive (free) nodes
+  if(removenodes)
+  {
+    it=s2->begin();
+    while(it!=s2->end())
+    {
+      //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
+      myNodes.Remove(static_cast<SMDS_MeshNode*>
+                    (const_cast<SMDS_MeshElement*>(*it)));
+      myNodeIDFactory->ReleaseID((*it)->GetID());
+      removedNodes.push_back( (*it) );
+      delete *it;
+      it++;
+    }
+  }
+
+  delete s2;
+  delete s1;
+}
+
+/*!
+ * Checks if the element is present in mesh.
+ * Useful to determine dead pointers.
+ */
+bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
+{
+  // we should not imply on validity of *elem, so iterate on containers
+  // of all types in the hope of finding <elem> somewhere there
+  SMDS_NodeIteratorPtr itn = nodesIterator();
+  while (itn->more())
+    if (elem == itn->next())
+      return true;
+  SMDS_EdgeIteratorPtr ite = edgesIterator();
+  while (ite->more())
+    if (elem == ite->next())
+      return true;
+  SMDS_FaceIteratorPtr itf = facesIterator();
+  while (itf->more())
+    if (elem == itf->next())
+      return true;
+  SMDS_VolumeIteratorPtr itv = volumesIterator();
+  while (itv->more())
+    if (elem == itv->next())
+      return true;
+  return false;
+}
+
+//=======================================================================
+//function : MaxNodeID
+//purpose  : 
+//=======================================================================
+
+int SMDS_Mesh::MaxNodeID() const
+{
+  return myNodeIDFactory->GetMaxID();
+}
+
+//=======================================================================
+//function : MinNodeID
+//purpose  : 
+//=======================================================================
+
+int SMDS_Mesh::MinNodeID() const
+{
+  return myNodeIDFactory->GetMinID();
+}
+
+//=======================================================================
+//function : MaxElementID
+//purpose  : 
+//=======================================================================
+
+int SMDS_Mesh::MaxElementID() const
+{
+  return myElementIDFactory->GetMaxID();
+}
+
+//=======================================================================
+//function : MinElementID
+//purpose  : 
+//=======================================================================
+
+int SMDS_Mesh::MinElementID() const
+{
+  return myElementIDFactory->GetMinID();
+}
+
+//=======================================================================
+//function : Renumber
+//purpose  : Renumber all nodes or elements.
+//=======================================================================
+
+void SMDS_Mesh::Renumber (const bool isNodes, const int  startID, const int  deltaID)
+{
+  if ( deltaID == 0 )
+    return;
+
+  SMDS_MeshElementIDFactory * idFactory =
+    isNodes ? myNodeIDFactory : myElementIDFactory;
+
+  // get existing elements in the order of ID increasing
+  map<int,SMDS_MeshElement*> elemMap;
+  SMDS_ElemIteratorPtr idElemIt = idFactory->elementsIterator();
+  while ( idElemIt->more() ) {
+    SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(idElemIt->next());
+    int id = elem->GetID();
+    elemMap.insert(map<int,SMDS_MeshElement*>::value_type(id, elem));
+  }
+  // release their ids
+  map<int,SMDS_MeshElement*>::iterator elemIt = elemMap.begin();
+  for ( ; elemIt != elemMap.end(); elemIt++ )
+  {
+    int id = (*elemIt).first;
+    idFactory->ReleaseID( id );
+  }
+  // set new IDs
+  int ID = startID;
+  elemIt = elemMap.begin();
+  for ( ; elemIt != elemMap.end(); elemIt++ )
+  {
+    idFactory->BindID( ID, (*elemIt).second );
+    ID += deltaID;
+  }
+}
+
+//=======================================================================
+//function : GetElementType
+//purpose  : Return type of element or node with id
+//=======================================================================
+
+SMDSAbs_ElementType SMDS_Mesh::GetElementType( const int id, const bool iselem ) const
+{
+  SMDS_MeshElement* elem = 0;
+  if( iselem )
+    elem = myElementIDFactory->MeshElement( id );
+  else
+    elem = myNodeIDFactory->MeshElement( id );
+
+  if( !elem )
+  {
+    //throw SALOME_Exception(LOCALIZED ("this element isn't exist"));
+    return SMDSAbs_All;
+  }
+  else
+    return elem->GetType();
+}
\ No newline at end of file
diff --git a/src/SMDS/SMDS_Mesh.hxx b/src/SMDS/SMDS_Mesh.hxx
new file mode 100644 (file)
index 0000000..612082c
--- /dev/null
@@ -0,0 +1,362 @@
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMDS_Mesh.hxx
+//  Module : SMESH
+
+#ifndef _SMDS_Mesh_HeaderFile
+#define _SMDS_Mesh_HeaderFile
+
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_MeshEdge.hxx"
+#include "SMDS_MeshFace.hxx"
+#include "SMDS_MeshVolume.hxx"
+#include "SMDS_MeshElementIDFactory.hxx"
+#include "SMDS_ElemIterator.hxx"
+#include <NCollection_Map.hxx>
+
+//#ifdef WNT
+//#include <SALOME_WNT.hxx>
+//#else
+//#define SALOME_WNT_EXPORT
+//#endif
+#if defined WNT && defined WIN32 && defined SMDS_EXPORTS
+#define SMDS_WNT_EXPORT __declspec( dllexport )
+#else
+#define SMDS_WNT_EXPORT
+#endif
+
+#include <boost/shared_ptr.hpp>
+#include <set>
+#include <list>
+
+typedef SMDS_Iterator<const SMDS_MeshNode *> SMDS_NodeIterator;
+typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshNode *> > SMDS_NodeIteratorPtr;
+typedef SMDS_Iterator<const SMDS_MeshEdge *> SMDS_EdgeIterator;
+typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshEdge *> > SMDS_EdgeIteratorPtr;
+typedef SMDS_Iterator<const SMDS_MeshFace *> SMDS_FaceIterator;
+typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshFace *> > SMDS_FaceIteratorPtr;
+typedef SMDS_Iterator<const SMDS_MeshVolume *> SMDS_VolumeIterator;
+typedef boost::shared_ptr<SMDS_Iterator<const SMDS_MeshVolume *> > SMDS_VolumeIteratorPtr;
+
+class SMDS_WNT_EXPORT SMDS_Mesh:public SMDS_MeshObject{
+public:
+  
+  SMDS_Mesh();
+  
+  SMDS_NodeIteratorPtr nodesIterator() const;
+  SMDS_EdgeIteratorPtr edgesIterator() const;
+  SMDS_FaceIteratorPtr facesIterator() const;
+  SMDS_VolumeIteratorPtr volumesIterator() const;
+  SMDS_ElemIteratorPtr elementsIterator() const;  
+  
+  SMDSAbs_ElementType GetElementType( const int id, const bool iselem ) const;
+
+  SMDS_Mesh *AddSubMesh();
+  
+  virtual SMDS_MeshNode* AddNodeWithID(double x, double y, double z, int ID);
+  virtual SMDS_MeshNode* AddNode(double x, double y, double z);
+  
+  virtual SMDS_MeshEdge* AddEdgeWithID(int n1, int n2, int ID);
+  virtual SMDS_MeshEdge* AddEdgeWithID(const SMDS_MeshNode * n1,
+                                      const SMDS_MeshNode * n2, 
+                                      int ID);
+  virtual SMDS_MeshEdge* AddEdge(const SMDS_MeshNode * n1,
+                                const SMDS_MeshNode * n2);
+  
+  virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int ID);
+  virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1,
+                                      const SMDS_MeshNode * n2,
+                                      const SMDS_MeshNode * n3, 
+                                      int ID);
+  virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1,
+                                const SMDS_MeshNode * n2,
+                                const SMDS_MeshNode * n3);
+  
+  virtual SMDS_MeshFace* AddFaceWithID(int n1, int n2, int n3, int n4, int ID);
+  virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshNode * n1,
+                                      const SMDS_MeshNode * n2,
+                                      const SMDS_MeshNode * n3,
+                                      const SMDS_MeshNode * n4, 
+                                      int ID);
+  virtual SMDS_MeshFace* AddFace(const SMDS_MeshNode * n1,
+                                const SMDS_MeshNode * n2,
+                                const SMDS_MeshNode * n3,
+                                const SMDS_MeshNode * n4);
+  
+  virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshEdge * e1,
+                                       const SMDS_MeshEdge * e2,
+                                       const SMDS_MeshEdge * e3, int ID);
+  virtual SMDS_MeshFace* AddFace(const SMDS_MeshEdge * e1,
+                                 const SMDS_MeshEdge * e2,
+                                 const SMDS_MeshEdge * e3);
+
+  virtual SMDS_MeshFace* AddFaceWithID(const SMDS_MeshEdge * e1,
+                                       const SMDS_MeshEdge * e2,
+                                       const SMDS_MeshEdge * e3,
+                                       const SMDS_MeshEdge * e4, int ID);
+  virtual SMDS_MeshFace* AddFace(const SMDS_MeshEdge * e1,
+                                 const SMDS_MeshEdge * e2,
+                                 const SMDS_MeshEdge * e3,
+                                 const SMDS_MeshEdge * e4);
+
+  virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4, int ID);
+  virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+                                          const SMDS_MeshNode * n2,
+                                          const SMDS_MeshNode * n3,
+                                          const SMDS_MeshNode * n4, 
+                                          int ID);
+  virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+                                    const SMDS_MeshNode * n2,
+                                    const SMDS_MeshNode * n3,
+                                    const SMDS_MeshNode * n4);
+  
+  virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
+                                           int n5, int ID);
+  virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+                                          const SMDS_MeshNode * n2,
+                                          const SMDS_MeshNode * n3,
+                                          const SMDS_MeshNode * n4,
+                                          const SMDS_MeshNode * n5, 
+                                          int ID);
+  virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+                                    const SMDS_MeshNode * n2,
+                                    const SMDS_MeshNode * n3,
+                                    const SMDS_MeshNode * n4,
+                                    const SMDS_MeshNode * n5);
+  
+  virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
+                                           int n5, int n6, int ID);
+  virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+                                          const SMDS_MeshNode * n2,
+                                          const SMDS_MeshNode * n3,
+                                          const SMDS_MeshNode * n4,
+                                          const SMDS_MeshNode * n5,
+                                          const SMDS_MeshNode * n6, 
+                                          int ID);
+  virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+                                    const SMDS_MeshNode * n2,
+                                    const SMDS_MeshNode * n3,
+                                    const SMDS_MeshNode * n4,
+                                    const SMDS_MeshNode * n5,
+                                    const SMDS_MeshNode * n6);
+  
+  virtual SMDS_MeshVolume* AddVolumeWithID(int n1, int n2, int n3, int n4,
+                                           int n5, int n6, int n7, int n8, int ID);
+  virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshNode * n1,
+                                          const SMDS_MeshNode * n2,
+                                          const SMDS_MeshNode * n3,
+                                          const SMDS_MeshNode * n4,
+                                          const SMDS_MeshNode * n5,
+                                          const SMDS_MeshNode * n6,
+                                          const SMDS_MeshNode * n7,
+                                          const SMDS_MeshNode * n8, 
+                                          int ID);
+  virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshNode * n1,
+                                    const SMDS_MeshNode * n2,
+                                    const SMDS_MeshNode * n3,
+                                    const SMDS_MeshNode * n4,
+                                    const SMDS_MeshNode * n5,
+                                    const SMDS_MeshNode * n6,
+                                    const SMDS_MeshNode * n7,
+                                    const SMDS_MeshNode * n8);
+
+  virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshFace * f1,
+                                           const SMDS_MeshFace * f2,
+                                           const SMDS_MeshFace * f3,
+                                           const SMDS_MeshFace * f4, int ID);
+  virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshFace * f1,
+                                     const SMDS_MeshFace * f2,
+                                     const SMDS_MeshFace * f3,
+                                     const SMDS_MeshFace * f4);
+
+  virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshFace * f1,
+                                           const SMDS_MeshFace * f2,
+                                           const SMDS_MeshFace * f3,
+                                           const SMDS_MeshFace * f4,
+                                           const SMDS_MeshFace * f5, int ID);
+  virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshFace * f1,
+                                     const SMDS_MeshFace * f2,
+                                     const SMDS_MeshFace * f3,
+                                     const SMDS_MeshFace * f4,
+                                     const SMDS_MeshFace * f5);
+
+  virtual SMDS_MeshVolume* AddVolumeWithID(const SMDS_MeshFace * f1,
+                                           const SMDS_MeshFace * f2,
+                                           const SMDS_MeshFace * f3,
+                                           const SMDS_MeshFace * f4,
+                                           const SMDS_MeshFace * f5,
+                                           const SMDS_MeshFace * f6, int ID);
+  virtual SMDS_MeshVolume* AddVolume(const SMDS_MeshFace * f1,
+                                     const SMDS_MeshFace * f2,
+                                     const SMDS_MeshFace * f3,
+                                     const SMDS_MeshFace * f4,
+                                     const SMDS_MeshFace * f5,
+                                     const SMDS_MeshFace * f6);
+
+  virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector<int> nodes_ids,
+                                                 const int        ID);
+
+  virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector<const SMDS_MeshNode*> nodes,
+                                                 const int                         ID);
+
+  virtual SMDS_MeshFace* AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes);
+
+  virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID
+                           (std::vector<int> nodes_ids,
+                            std::vector<int> quantities,
+                            const int        ID);
+
+  virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID
+                           (std::vector<const SMDS_MeshNode*> nodes,
+                            std::vector<int>                  quantities,
+                            const int                         ID);
+
+  virtual SMDS_MeshVolume* AddPolyhedralVolume
+                           (std::vector<const SMDS_MeshNode*> nodes,
+                            std::vector<int>                  quantities);
+
+  virtual void RemoveElement(const SMDS_MeshElement *        elem,
+                             std::list<const SMDS_MeshElement *>& removedElems,
+                             std::list<const SMDS_MeshElement *>& removedNodes,
+                             const bool                      removenodes = false);
+  virtual void RemoveElement(const SMDS_MeshElement * elem, bool removenodes = false);
+  virtual void RemoveNode(const SMDS_MeshNode * node);
+  virtual void RemoveEdge(const SMDS_MeshEdge * edge);
+  virtual void RemoveFace(const SMDS_MeshFace * face);
+  virtual void RemoveVolume(const SMDS_MeshVolume * volume);
+  
+  virtual bool RemoveFromParent();
+  virtual bool RemoveSubMesh(const SMDS_Mesh * aMesh);
+
+  static bool ChangeElementNodes(const SMDS_MeshElement * elem,
+                                 const SMDS_MeshNode    * nodes[],
+                                 const int                nbnodes);
+  static bool ChangePolyhedronNodes(const SMDS_MeshElement * elem,
+                                    std::vector<const SMDS_MeshNode*> nodes,
+                                    std::vector<int>                  quantities);
+
+  virtual void Renumber (const bool isNodes, const int startID = 1, const int deltaID = 1);
+  // Renumber all nodes or elements.
+
+  const SMDS_MeshNode *FindNode(int idnode) const;
+  const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2) const;
+  const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3) const;
+  const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, int idnode4) const;
+  const SMDS_MeshElement *FindElement(int IDelem) const;
+  static const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1,
+                                       const SMDS_MeshNode * n2);
+  static const SMDS_MeshFace* FindFace(const SMDS_MeshNode *n1,
+                                       const SMDS_MeshNode *n2,
+                                       const SMDS_MeshNode *n3);
+  static const SMDS_MeshFace* FindFace(const SMDS_MeshNode *n1,
+                                       const SMDS_MeshNode *n2,
+                                       const SMDS_MeshNode *n3,
+                                       const SMDS_MeshNode *n4);
+
+  const SMDS_MeshFace *FindFace(std::vector<int> nodes_ids) const;
+  static const SMDS_MeshFace* FindFace(std::vector<const SMDS_MeshNode *> nodes);
+
+  int MaxNodeID() const;
+  int MinNodeID() const;
+  int MaxElementID() const;
+  int MinElementID() const;
+
+
+  int NbNodes() const;
+  int NbEdges() const;
+  int NbFaces() const;
+  int NbVolumes() const;
+  int NbSubMesh() const;
+  void DumpNodes() const;
+  void DumpEdges() const;
+  void DumpFaces() const;
+  void DumpVolumes() const;
+  void DebugStats() const;
+  SMDS_Mesh *boundaryFaces();
+  SMDS_Mesh *boundaryEdges();
+  virtual ~SMDS_Mesh();
+  bool hasConstructionEdges();
+  bool hasConstructionFaces();
+  bool hasInverseElements();
+  void setConstructionEdges(bool);
+  void setConstructionFaces(bool);
+  void setInverseElements(bool);
+
+  /*!
+   * Checks if the element is present in mesh.
+   * Useful to determine dead pointers.
+   * Use this function for debug purpose only! Do not check in the code
+   * using it even in _DEBUG_ mode
+   */
+  bool Contains (const SMDS_MeshElement* elem) const;
+
+  typedef NCollection_Map<SMDS_MeshNode *> SetOfNodes;
+  typedef NCollection_Map<SMDS_MeshEdge *> SetOfEdges;
+  typedef NCollection_Map<SMDS_MeshFace *> SetOfFaces;
+  typedef NCollection_Map<SMDS_MeshVolume *> SetOfVolumes;
+
+private:
+  SMDS_Mesh(SMDS_Mesh * parent);
+
+  SMDS_MeshFace * createTriangle(const SMDS_MeshNode * node1, 
+                                const SMDS_MeshNode * node2, 
+                                const SMDS_MeshNode * node3);
+  SMDS_MeshFace * createQuadrangle(const SMDS_MeshNode * node1,
+                                  const SMDS_MeshNode * node2, 
+                                  const SMDS_MeshNode * node3, 
+                                  const SMDS_MeshNode * node4);
+  SMDS_MeshEdge* FindEdgeOrCreate(const SMDS_MeshNode * n1,
+                                 const SMDS_MeshNode * n2);
+  SMDS_MeshFace* FindFaceOrCreate(const SMDS_MeshNode *n1,
+                                 const SMDS_MeshNode *n2,
+                                 const SMDS_MeshNode *n3);
+  SMDS_MeshFace* FindFaceOrCreate(const SMDS_MeshNode *n1,
+                                 const SMDS_MeshNode *n2,
+                                 const SMDS_MeshNode *n3,
+                                 const SMDS_MeshNode *n4);
+
+  bool registerElement(int ID, SMDS_MeshElement * element);
+
+  void addChildrenWithNodes(std::set<const SMDS_MeshElement*>& setOfChildren, 
+                           const SMDS_MeshElement * element, 
+                           std::set<const SMDS_MeshElement*>& nodes);
+
+  // Fields PRIVATE
+  
+  SetOfNodes myNodes;
+  SetOfEdges myEdges;
+  SetOfFaces myFaces;
+  SetOfVolumes myVolumes;
+  SMDS_Mesh *myParent;
+  std::list<SMDS_Mesh *> myChildren;
+  SMDS_MeshElementIDFactory *myNodeIDFactory;
+  SMDS_MeshElementIDFactory *myElementIDFactory;
+  
+  bool myHasConstructionEdges;
+  bool myHasConstructionFaces;
+  bool myHasInverseElements;
+};
+
+
+#endif
diff --git a/src/SMDS/SMDS_MeshElement.hxx b/src/SMDS/SMDS_MeshElement.hxx
new file mode 100644 (file)
index 0000000..73870b7
--- /dev/null
@@ -0,0 +1,87 @@
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMDS_MeshElement.hxx
+//  Module : SMESH
+
+#ifndef _SMDS_MeshElement_HeaderFile
+#define _SMDS_MeshElement_HeaderFile
+       
+#include "SMDSAbs_ElementType.hxx"
+#include "SMDS_MeshObject.hxx"
+#include "SMDS_ElemIterator.hxx"
+#include "SMDS_MeshElementIDFactory.hxx"
+
+//#ifdef WNT
+//#include <SALOME_WNT.hxx>
+//#else
+//#define SALOME_WNT_EXPORT
+//#endif
+
+#if defined WNT && defined WIN32 && defined SMDS_EXPORTS
+#define SMDS_WNT_EXPORT __declspec( dllexport )
+#else
+#define SMDS_WNT_EXPORT
+#endif
+
+#include <vector>
+#include <iostream>
+
+class SMDS_MeshNode;
+class SMDS_MeshEdge;
+class SMDS_MeshFace;   
+
+///////////////////////////////////////////////////////////////////////////////
+/// Base class for elements
+///////////////////////////////////////////////////////////////////////////////
+class SMDS_WNT_EXPORT SMDS_MeshElement:public SMDS_MeshObject
+{
+
+  public:
+       SMDS_ElemIteratorPtr nodesIterator() const;
+       SMDS_ElemIteratorPtr edgesIterator() const;
+       SMDS_ElemIteratorPtr facesIterator() const;
+       virtual SMDS_ElemIteratorPtr
+               elementsIterator(SMDSAbs_ElementType type) const;
+
+       virtual int NbNodes() const;
+       virtual int NbEdges() const;
+       virtual int NbFaces() const;
+       int GetID() const;
+
+       ///Return the type of the current element
+       virtual SMDSAbs_ElementType GetType() const = 0;
+       virtual bool IsPoly() const { return false; };
+
+       friend std::ostream & operator <<(std::ostream & OS, const SMDS_MeshElement *);
+       friend bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement*elem);
+
+  protected:
+       SMDS_MeshElement(int ID=-1);
+       virtual void Print(std::ostream & OS) const;
+       
+  private:
+       int myID;
+};
+
+#endif
diff --git a/src/SMDS/SMDS_MeshGroup.hxx b/src/SMDS/SMDS_MeshGroup.hxx
new file mode 100644 (file)
index 0000000..37893fa
--- /dev/null
@@ -0,0 +1,87 @@
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//
+//  Copyright (C) 2003  OPEN CASCADE
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org or email : webmaster@opencascade.org 
+//
+//
+//
+//  File   : SMDS_MeshGroup.hxx
+//  Module : SMESH
+
+#ifndef _SMDS_MeshGroup_HeaderFile
+#define _SMDS_MeshGroup_HeaderFile
+
+#include "SMDS_Mesh.hxx"
+#include <set>
+
+//#ifdef WNT
+//#include <SALOME_WNT.hxx>
+//#else
+//#define SALOME_WNT_EXPORT
+//#endif
+
+#if defined WNT && defined WIN32 && defined SMDS_EXPORTS
+#define SMDS_WNT_EXPORT __declspec( dllexport )
+#else
+#define SMDS_WNT_EXPORT
+#endif
+
+class SMDS_WNT_EXPORT SMDS_MeshGroup:public SMDS_MeshObject
+{
+  public:
+       SMDS_MeshGroup(const SMDS_Mesh * theMesh,
+                       const SMDSAbs_ElementType theType = SMDSAbs_All);
+       const SMDS_MeshGroup * AddSubGroup
+                      (const SMDSAbs_ElementType theType = SMDSAbs_All);
+       virtual bool RemoveSubGroup(const SMDS_MeshGroup* theGroup);
+       virtual bool RemoveFromParent();
+
+        const SMDS_Mesh* GetMesh() const { return myMesh; }
+
+        void SetType (const SMDSAbs_ElementType theType);
+        void Clear();
+       void Add(const SMDS_MeshElement * theElem);
+       void Remove(const SMDS_MeshElement * theElem);
+       bool IsEmpty() const { return myElements.empty(); }
+       int Extent() const { return myElements.size(); }
+
+        SMDSAbs_ElementType GetType() const { return myType; }
+
+       bool Contains(const SMDS_MeshElement * theElem) const;
+
+        void InitIterator() const
+        { const_cast<TIterator&>(myIterator) = myElements.begin(); }
+
+        bool More() const { return myIterator != myElements.end(); }
+
+        const SMDS_MeshElement* Next() const
+        { return *(const_cast<TIterator&>(myIterator))++; }
+
+  private:
+       SMDS_MeshGroup(SMDS_MeshGroup* theParent,
+                       const SMDSAbs_ElementType theType = SMDSAbs_All);
+
+        typedef std::set<const SMDS_MeshElement *>::const_iterator TIterator;
+       const SMDS_Mesh *                       myMesh;
+       SMDSAbs_ElementType                     myType;
+       std::set<const SMDS_MeshElement *>      myElements;
+       SMDS_MeshGroup *                        myParent;
+       std::list<const SMDS_MeshGroup*>        myChildren;
+        TIterator                               myIterator;
+};
+#endif
diff --git a/src/SMDS/SMDS_MeshNode.hxx b/src/SMDS/SMDS_MeshNode.hxx
new file mode 100644 (file)
index 0000000..042a173
--- /dev/null
@@ -0,0 +1,77 @@
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMDS_MeshNode.hxx
+//  Module : SMESH
+
+#ifndef _SMDS_MeshNode_HeaderFile
+#define _SMDS_MeshNode_HeaderFile
+
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_Position.hxx"
+#include <NCollection_List.hxx>
+
+//#ifdef WNT
+//#include <SALOME_WNT.hxx>
+//#else
+//#define SALOME_WNT_EXPORT
+//#endif
+
+#if defined WNT && defined WIN32 && defined SMDS_EXPORTS
+#define SMDS_WNT_EXPORT __declspec( dllexport )
+#else
+#define SMDS_WNT_EXPORT
+#endif
+
+class SMDS_WNT_EXPORT SMDS_MeshNode:public SMDS_MeshElement
+{
+
+  public:
+       SMDS_MeshNode(double x, double y, double z);
+       void Print(std::ostream & OS) const;
+       double X() const;
+       double Y() const;
+       double Z() const;
+       void AddInverseElement(const SMDS_MeshElement * ME);
+       void RemoveInverseElement(const SMDS_MeshElement * parent);
+       void ClearInverseElements();
+       bool emptyInverseElements();
+       SMDS_ElemIteratorPtr GetInverseElementIterator() const; 
+       void SetPosition(const SMDS_PositionPtr& aPos);
+       const SMDS_PositionPtr& GetPosition() const;
+       SMDSAbs_ElementType GetType() const;
+       int NbNodes() const;
+       void setXYZ(double x, double y, double z);
+       friend bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2);
+
+  protected:
+       SMDS_ElemIteratorPtr
+               elementsIterator(SMDSAbs_ElementType type) const;
+
+  private:
+       double myX, myY, myZ;
+       SMDS_PositionPtr myPosition;
+       NCollection_List<const SMDS_MeshElement*> myInverseElements;
+};
+
+#endif
diff --git a/src/SMDS/SMDS_MeshObject.hxx b/src/SMDS/SMDS_MeshObject.hxx
new file mode 100644 (file)
index 0000000..f734309
--- /dev/null
@@ -0,0 +1,48 @@
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMDS_MeshObject.hxx
+//  Module : SMESH
+
+#ifndef _SMDS_MeshObject_HeaderFile
+#define _SMDS_MeshObject_HeaderFile
+
+
+//#ifdef WNT
+//#include <SALOME_WNT.hxx>
+//#else
+//#define SALOME_WNT_EXPORT
+//#endif
+
+#if defined WNT && defined WIN32 && defined SMDS_EXPORTS
+#define SMDS_WNT_EXPORT __declspec( dllexport )
+#else
+#define SMDS_WNT_EXPORT
+#endif
+
+class SMDS_WNT_EXPORT SMDS_MeshObject
+{
+ public:
+  virtual ~SMDS_MeshObject() {}
+};
+#endif
diff --git a/src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx b/src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx
new file mode 100644 (file)
index 0000000..84ce213
--- /dev/null
@@ -0,0 +1,190 @@
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+
+#ifdef _MSC_VER
+#pragma warning(disable:4786)
+#endif
+
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "utilities.h"
+
+#include <set>
+
+using namespace std;
+
+//=======================================================================
+//function : Constructor
+//purpose  : Create a volume of many faces
+//=======================================================================
+SMDS_PolyhedralVolumeOfNodes::SMDS_PolyhedralVolumeOfNodes
+                                (std::vector<const SMDS_MeshNode *> nodes,
+                                 std::vector<int>                   quantities)
+: SMDS_VolumeOfNodes(NULL, NULL, NULL, NULL)
+{
+  ChangeNodes(nodes, quantities);
+}
+
+//=======================================================================
+//function : GetType
+//purpose  : 
+//=======================================================================
+SMDSAbs_ElementType SMDS_PolyhedralVolumeOfNodes::GetType() const
+{
+//  return SMDSAbs_PolyhedralVolume;
+  return SMDSAbs_Volume;
+}
+
+//=======================================================================
+//function : ChangeNodes
+//purpose  : 
+//=======================================================================
+bool SMDS_PolyhedralVolumeOfNodes::ChangeNodes (std::vector<const SMDS_MeshNode *> nodes,
+                                                std::vector<int>                   quantities)
+{
+  myNodesByFaces = nodes;
+  myQuantities = quantities;
+
+  // Init fields of parent class
+  int aNbNodes = 0;
+  std::set<const SMDS_MeshNode *> aSet;
+  int nodes_len = nodes.size();
+  for (int j = 0; j < nodes_len; j++) {
+    if (aSet.find(nodes[j]) == aSet.end()) {
+      aSet.insert(nodes[j]);
+      aNbNodes++;
+    }
+  }
+
+  int k = 0;
+#ifndef WNT
+  const SMDS_MeshNode* aNodes [aNbNodes];
+#else
+  const SMDS_MeshNode** aNodes = (const SMDS_MeshNode **)new SMDS_MeshNode*[aNbNodes];
+#endif
+  std::set<const SMDS_MeshNode *>::iterator anIter = aSet.begin();
+  for (; anIter != aSet.end(); anIter++, k++) {
+    aNodes[k] = *anIter;
+  }
+
+  //SMDS_VolumeOfNodes::ChangeNodes(aNodes, aNbNodes);
+  delete [] myNodes;
+  //myNbNodes = nodes.size();
+  myNbNodes = aNbNodes;
+  myNodes = new const SMDS_MeshNode* [myNbNodes];
+  for (int i = 0; i < myNbNodes; i++) {
+    //myNodes[i] = nodes[i];
+    myNodes[i] = aNodes[i];
+  }
+
+#ifdef WNT
+  delete [] aNodes;
+#endif
+
+  return true;
+}
+
+//=======================================================================
+//function : NbEdges
+//purpose  : 
+//=======================================================================
+int SMDS_PolyhedralVolumeOfNodes::NbEdges() const
+{
+  int nbEdges = 0;
+
+  for (int ifa = 0; ifa < myQuantities.size(); ifa++) {
+    nbEdges += myQuantities[ifa];
+  }
+  nbEdges /= 2;
+
+  return nbEdges;
+}
+
+//=======================================================================
+//function : NbFaces
+//purpose  : 
+//=======================================================================
+int SMDS_PolyhedralVolumeOfNodes::NbFaces() const
+{
+  return myQuantities.size();
+}
+
+//=======================================================================
+//function : NbFaceNodes
+//purpose  : 
+//=======================================================================
+int SMDS_PolyhedralVolumeOfNodes::NbFaceNodes (const int face_ind) const
+{
+  if (face_ind < 1 || myQuantities.size() < face_ind)
+    return 0;
+  return myQuantities[face_ind - 1];
+}
+
+//=======================================================================
+//function : GetFaceNode
+//purpose  : 
+//=======================================================================
+const SMDS_MeshNode* SMDS_PolyhedralVolumeOfNodes::GetFaceNode (const int face_ind,
+                                                                const int node_ind) const
+{
+  if (node_ind < 1 || NbFaceNodes(face_ind) < node_ind)
+    return NULL;
+
+  int i, first_node = 0;
+  for (i = 0; i < face_ind - 1; i++) {
+    first_node += myQuantities[i];
+  }
+
+  return myNodesByFaces[first_node + node_ind - 1];
+}
+
+//=======================================================================
+//function : Print
+//purpose  : 
+//=======================================================================
+void SMDS_PolyhedralVolumeOfNodes::Print (ostream & OS) const
+{
+  OS << "polyhedral volume <" << GetID() << "> : ";
+
+  int faces_len = myQuantities.size();
+  //int nodes_len = myNodesByFaces.size();
+  int cur_first_node = 0;
+
+  int i, j;
+  for (i = 0; i < faces_len; i++) {
+    OS << "face_" << i << " (";
+    for (j = 0; j < myQuantities[i] - 1; j++) {
+      OS << myNodesByFaces[cur_first_node + j] << ",";
+    }
+    OS << myNodesByFaces[cur_first_node + j] << ") ";
+    cur_first_node += myQuantities[i];
+  }
+}
+
+//=======================================================================
+//function : ChangeNodes
+//purpose  : usage disabled
+//=======================================================================
+bool SMDS_PolyhedralVolumeOfNodes::ChangeNodes (const SMDS_MeshNode* nodes[],
+                                                const int            nbNodes)
+{
+  return false;
+}
diff --git a/src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx b/src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx
new file mode 100644 (file)
index 0000000..baecaf3
--- /dev/null
@@ -0,0 +1,77 @@
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMDS_PolyhedralVolumeOfNodes.hxx
+//  Module : SMESH
+
+#ifndef _SMDS_PolyhedralVolumeOfNodes_HeaderFile
+#define _SMDS_PolyhedralVolumeOfNodes_HeaderFile
+
+#include "SMDS_VolumeOfNodes.hxx"
+
+#if defined WNT && defined WIN32 && defined SMDS_EXPORTS
+#define SMDS_WNT_EXPORT __declspec( dllexport )
+#else
+#define SMDS_WNT_EXPORT
+#endif
+class SMDS_WNT_EXPORT SMDS_PolyhedralVolumeOfNodes:public SMDS_VolumeOfNodes
+{
+ public:
+  SMDS_PolyhedralVolumeOfNodes (std::vector<const SMDS_MeshNode *> nodes,
+                                std::vector<int>                   quantities);
+
+  //virtual ~SMDS_PolyhedralVolumeOfNodes();
+
+  virtual SMDSAbs_ElementType GetType() const; 
+  virtual bool IsPoly() const { return true; };
+
+  bool ChangeNodes (std::vector<const SMDS_MeshNode *> nodes,
+                    std::vector<int>                   quantities);
+
+  //virtual int NbNodes() const;
+  virtual int NbEdges() const;
+  virtual int NbFaces() const;
+
+  int NbFaceNodes (const int face_ind) const;
+  // 1 <= face_ind <= NbFaces()
+
+  const SMDS_MeshNode* GetFaceNode (const int face_ind, const int node_ind) const;
+  // 1 <= face_ind <= NbFaces()
+  // 1 <= node_ind <= NbFaceNodes()
+
+  virtual void Print (std::ostream & OS) const;
+
+ protected:
+  //virtual SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const;
+
+ private:
+  // usage disabled
+  bool ChangeNodes (const SMDS_MeshNode* nodes[],
+                    const int            nbNodes);
+
+ private:
+  std::vector<const SMDS_MeshNode *> myNodesByFaces;
+  std::vector<int> myQuantities;
+};
+
+#endif
diff --git a/src/SMDS/SMDS_Position.hxx b/src/SMDS/SMDS_Position.hxx
new file mode 100644 (file)
index 0000000..9b11dc6
--- /dev/null
@@ -0,0 +1,68 @@
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMDS_Position.hxx
+//  Module : SMESH
+
+#ifndef _SMDS_Position_HeaderFile
+#define _SMDS_Position_HeaderFile
+
+#include "SMDS_TypeOfPosition.hxx"
+#include <boost/shared_ptr.hpp>
+
+//#ifdef WNT
+//#include <SALOME_WNT.hxx>
+//#else
+//#define SALOME_WNT_EXPORT
+//#endif
+
+#if defined WNT && defined WIN32 && defined SMDS_EXPORTS
+#define SMDS_WNT_EXPORT __declspec( dllexport )
+#else
+#define SMDS_WNT_EXPORT
+#endif
+
+class SMDS_Position;
+typedef boost::shared_ptr<SMDS_Position> SMDS_PositionPtr;
+
+
+class SMDS_WNT_EXPORT SMDS_Position
+{
+
+  public:
+       const virtual double * Coords() const = 0;
+       virtual SMDS_TypeOfPosition GetTypeOfPosition() const = 0;
+       virtual int GetDim() const;
+       void SetShapeId(int aShapeId);
+       int GetShapeId() const;
+       virtual ~SMDS_Position() {}
+
+  protected:
+         SMDS_Position(int aShapeId);
+
+  private:
+       int myShapeId;
+};
+
+
+#endif
diff --git a/src/SMDS/SMDS_SpacePosition.hxx b/src/SMDS/SMDS_SpacePosition.hxx
new file mode 100644 (file)
index 0000000..f4c7bff
--- /dev/null
@@ -0,0 +1,57 @@
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMDS_SpacePosition.hxx
+//  Module : SMESH
+
+#ifndef _SMDS_SpacePosition_HeaderFile
+#define _SMDS_SpacePosition_HeaderFile
+
+#include "SMDS_Position.hxx"
+
+//#ifdef WNT
+//#include <SALOME_WNT.hxx>
+//#else
+//#define SALOME_WNT_EXPORT
+//#endif
+
+#if defined WNT && defined WIN32 && defined SMDS_EXPORTS
+#define SMDS_WNT_EXPORT __declspec( dllexport )
+#else
+#define SMDS_WNT_EXPORT
+#endif
+
+class SMDS_WNT_EXPORT SMDS_SpacePosition:public SMDS_Position
+{
+
+  public:
+       SMDS_SpacePosition(double x=0, double y=0, double z=0);
+       const virtual double * Coords() const;
+       virtual inline SMDS_TypeOfPosition GetTypeOfPosition() const;
+       inline void SetCoords(const double x, const double y, const double z);
+        static SMDS_PositionPtr originSpacePosition();
+  private:
+       double myCoords[3];     
+};
+
+#endif
diff --git a/src/SMDS/SMDS_VertexPosition.hxx b/src/SMDS/SMDS_VertexPosition.hxx
new file mode 100644 (file)
index 0000000..68c1e3a
--- /dev/null
@@ -0,0 +1,53 @@
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMDS_VertexPosition.hxx
+//  Module : SMESH
+
+#ifndef _SMDS_VertexPosition_HeaderFile
+#define _SMDS_VertexPosition_HeaderFile
+
+#include "SMDS_Position.hxx"
+
+//#ifdef WNT
+//#include <SALOME_WNT.hxx>
+//#else
+//#define SALOME_WNT_EXPORT
+//#endif
+
+#if defined WNT && defined WIN32 && defined SMDS_EXPORTS
+#define SMDS_WNT_EXPORT __declspec( dllexport )
+#else
+#define SMDS_WNT_EXPORT
+#endif
+
+class SMDS_WNT_EXPORT SMDS_VertexPosition:public SMDS_Position
+{
+
+  public:      
+       SMDS_TypeOfPosition GetTypeOfPosition() const;
+       SMDS_VertexPosition(int aVertexId=0);
+       const double *Coords() const;
+};
+
+#endif
diff --git a/src/SMESH/SMESH_HypoFilter.cxx b/src/SMESH/SMESH_HypoFilter.cxx
new file mode 100644 (file)
index 0000000..ff14016
--- /dev/null
@@ -0,0 +1,305 @@
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESH_HypoFilter.cxx
+//  Module : SMESH
+//  $Header$
+
+#include "SMESH_HypoFilter.hxx"
+
+#include "SMESH_Hypothesis.hxx"
+#include "SMESH_subMesh.hxx"
+
+using namespace std;
+
+
+//=======================================================================
+//function : NamePredicate::Value
+//purpose  : 
+//=======================================================================
+
+bool SMESH_HypoFilter::NamePredicate::IsOk (const SMESH_Hypothesis* aHyp,
+                                            const TopoDS_Shape&     /*aShape*/ ) const
+{
+  return ( _name == aHyp->GetName() );
+}
+
+//=======================================================================
+//function : TypePredicate::Value
+//purpose  : 
+//=======================================================================
+
+int SMESH_HypoFilter::TypePredicate::Value( const SMESH_Hypothesis* aHyp ) const
+{
+  return aHyp->GetType();
+};
+
+//=======================================================================
+//function : DimPredicate::Value
+//purpose  : 
+//=======================================================================
+
+int SMESH_HypoFilter::DimPredicate::Value( const SMESH_Hypothesis* aHyp ) const
+{
+  return aHyp->GetDim();
+}
+
+//=======================================================================
+//function : ApplicablePredicate::IsOk
+//purpose  : 
+//=======================================================================
+
+bool SMESH_HypoFilter::ApplicablePredicate::IsOk(const SMESH_Hypothesis* aHyp,
+                                                 const TopoDS_Shape&     /*aShape*/) const
+{
+  return SMESH_subMesh::IsApplicableHypotesis( aHyp, (TopAbs_ShapeEnum)_shapeType );
+};
+
+//=======================================================================
+//function : ApplicablePredicate::ApplicablePredicate
+//purpose  : 
+//=======================================================================
+
+SMESH_HypoFilter::ApplicablePredicate::ApplicablePredicate( const TopoDS_Shape& theShape )
+{
+  _shapeType = ( theShape.IsNull() ? TopAbs_SHAPE : theShape.ShapeType());
+}
+
+//=======================================================================
+//function : InstancePredicate::IsOk
+//purpose  : 
+//=======================================================================
+
+bool SMESH_HypoFilter::InstancePredicate::IsOk(const SMESH_Hypothesis* aHyp,
+                                               const TopoDS_Shape&     /*aShape*/) const
+{
+  return _hypo == aHyp;
+}
+
+//=======================================================================
+//function : IsAssignedToPredicate::IsOk
+//purpose  : 
+//=======================================================================
+
+bool SMESH_HypoFilter::IsAssignedToPredicate::IsOk(const SMESH_Hypothesis* aHyp,
+                                               const TopoDS_Shape&     aShape) const
+{
+  return ( !_mainShape.IsNull() && !aShape.IsNull() && _mainShape.IsSame( aShape ));
+}
+
+//=======================================================================
+//function : SMESH_HypoFilter
+//purpose  : 
+//=======================================================================
+
+SMESH_HypoFilter::SMESH_HypoFilter()
+{
+}
+
+//=======================================================================
+//function : SMESH_HypoFilter
+//purpose  : 
+//=======================================================================
+
+SMESH_HypoFilter::SMESH_HypoFilter( SMESH_HypoPredicate* aPredicate, bool notNagate )
+{
+  add( notNagate ? AND : AND_NOT, aPredicate );
+}
+
+//=======================================================================
+//function : And
+//purpose  : 
+//=======================================================================
+
+SMESH_HypoFilter & SMESH_HypoFilter::And( SMESH_HypoPredicate* aPredicate )
+{
+  add( AND, aPredicate );
+  return *this;
+}
+
+//=======================================================================
+//function : AndNot
+//purpose  : 
+//=======================================================================
+
+SMESH_HypoFilter & SMESH_HypoFilter::AndNot( SMESH_HypoPredicate* aPredicate )
+{
+  add( AND_NOT, aPredicate );
+  return *this;
+}
+
+//=======================================================================
+//function : Or
+//purpose  : 
+//=======================================================================
+
+SMESH_HypoFilter & SMESH_HypoFilter::Or( SMESH_HypoPredicate* aPredicate )
+{
+  add( OR, aPredicate );
+  return *this;
+}
+
+//=======================================================================
+//function : OrNot
+//purpose  : Return predicates
+//=======================================================================
+
+SMESH_HypoFilter & SMESH_HypoFilter::OrNot( SMESH_HypoPredicate* aPredicate )
+{
+  add( OR_NOT, aPredicate );
+  return *this;
+}
+
+//=======================================================================
+//function : Is
+//purpose  : 
+//=======================================================================
+
+SMESH_HypoPredicate* SMESH_HypoFilter::Is(const SMESH_Hypothesis* theHypo)
+{
+  return new InstancePredicate( theHypo );
+}
+
+//=======================================================================
+//function : IsAlgo
+//purpose  : 
+//=======================================================================
+
+SMESH_HypoPredicate* SMESH_HypoFilter::IsAlgo()
+{
+  return new TypePredicate( MORE, SMESHDS_Hypothesis::PARAM_ALGO );
+}
+
+//=======================================================================
+//function : IsGlobal
+//purpose  : 
+//=======================================================================
+
+ SMESH_HypoPredicate* SMESH_HypoFilter::IsGlobal(const TopoDS_Shape& theMainShape)
+{
+  return new IsAssignedToPredicate( theMainShape );
+}
+
+//=======================================================================
+//function : IsAssignedTo
+//purpose  : 
+//=======================================================================
+
+ SMESH_HypoPredicate* SMESH_HypoFilter::IsAssignedTo(const TopoDS_Shape& theShape)
+{
+  return new IsAssignedToPredicate( theShape );
+}
+
+//=======================================================================
+//function : HasName
+//purpose  : 
+//=======================================================================
+
+SMESH_HypoPredicate* SMESH_HypoFilter::HasName(const string & theName)
+{
+  return new NamePredicate( theName );
+}
+
+//=======================================================================
+//function : HasDim
+//purpose  : 
+//=======================================================================
+
+SMESH_HypoPredicate* SMESH_HypoFilter::HasDim(const int theDim)
+{
+  return new DimPredicate( EQUAL, theDim );
+}
+
+//=======================================================================
+//function : IsApplicableTo
+//purpose  : 
+//=======================================================================
+
+SMESH_HypoPredicate* SMESH_HypoFilter::IsApplicableTo(const TopoDS_Shape& theShape)
+{
+  return new ApplicablePredicate( theShape );
+}
+
+//=======================================================================
+//function : HasType
+//purpose  : 
+//=======================================================================
+
+SMESH_HypoPredicate* SMESH_HypoFilter::HasType(const int theHypType)
+{
+  return new TypePredicate( EQUAL, theHypType );
+}
+
+//=======================================================================
+//function : IsOk
+//purpose  : 
+//=======================================================================
+
+bool SMESH_HypoFilter::IsOk (const SMESH_Hypothesis* aHyp,
+                             const TopoDS_Shape&     aShape) const
+{
+  if ( myPredicates.empty() )
+    return true;
+
+  bool ok = ( myPredicates.front()->_logical_op <= AND_NOT );
+  list<SMESH_HypoPredicate*>::const_iterator pred = myPredicates.begin();
+  for ( ; pred != myPredicates.end(); ++pred )
+  {
+    bool ok2 = (*pred)->IsOk( aHyp, aShape );
+    switch ( (*pred)->_logical_op ) {
+    case AND:     ok = ok && ok2; break;
+    case AND_NOT: ok = ok && !ok2; break;
+    case OR:      ok = ok || ok2; break;
+    case OR_NOT:  ok = ok || !ok2; break;
+    default:;
+    }
+  }
+  return ok;
+}
+
+//=======================================================================
+//function : Init
+//purpose  : 
+//=======================================================================
+
+SMESH_HypoFilter & SMESH_HypoFilter::Init  ( SMESH_HypoPredicate* aPredicate, bool notNagate )
+{
+  list<SMESH_HypoPredicate*>::const_iterator pred = myPredicates.begin();
+  for ( ; pred != myPredicates.end(); ++pred )
+    delete *pred;
+
+  add( notNagate ? AND : AND_NOT, aPredicate );
+  return *this;
+}
+
+
+//=======================================================================
+//function : IsOk
+//purpose  : 
+//=======================================================================
+
+SMESH_HypoFilter::~SMESH_HypoFilter()
+{
+  Init(0);
+}
+
diff --git a/src/SMESH/SMESH_HypoFilter.hxx b/src/SMESH/SMESH_HypoFilter.hxx
new file mode 100644 (file)
index 0000000..6bc34bf
--- /dev/null
@@ -0,0 +1,164 @@
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESH_HypoFilter.hxx
+//  Module : SMESH
+//  $Header$
+
+
+#ifndef SMESH_HypoFilter_HeaderFile
+#define SMESH_HypoFilter_HeaderFile
+
+// ===========================
+// Filter of SMESH_Hypothesis
+// ===========================
+
+#include <list>
+#include <string>
+#include <TopoDS_Shape.hxx>
+
+class SMESH_HypoFilter;
+class SMESH_Hypothesis;
+
+class SMESH_HypoPredicate {
+ public:
+  virtual bool IsOk(const SMESH_Hypothesis* aHyp,
+                    const TopoDS_Shape&     aShape) const = 0;
+  // check aHyp or/and aShape it is assigned to
+  virtual ~SMESH_HypoPredicate() {}
+ private:
+  int _logical_op;
+  friend class SMESH_HypoFilter;
+};
+
+class SMESH_HypoFilter: public SMESH_HypoPredicate
+{
+ public:
+  // Create and add predicates.
+  // Added predicates will be destroyed by filter when it dies
+  SMESH_HypoFilter();
+  SMESH_HypoFilter( SMESH_HypoPredicate* aPredicate, bool notNagate = true );
+  // notNagate==false means !aPredicate->IsOk()
+  SMESH_HypoFilter & Init  ( SMESH_HypoPredicate* aPredicate, bool notNagate = true );
+  SMESH_HypoFilter & And   ( SMESH_HypoPredicate* aPredicate );
+  SMESH_HypoFilter & AndNot( SMESH_HypoPredicate* aPredicate );
+  SMESH_HypoFilter & Or    ( SMESH_HypoPredicate* aPredicate );
+  SMESH_HypoFilter & OrNot ( SMESH_HypoPredicate* aPredicate );
+
+  // Create predicates
+  static SMESH_HypoPredicate* IsAlgo();
+  static SMESH_HypoPredicate* IsApplicableTo(const TopoDS_Shape& theShape);
+  static SMESH_HypoPredicate* IsAssignedTo(const TopoDS_Shape& theShape);
+  static SMESH_HypoPredicate* Is(const SMESH_Hypothesis* theHypo);
+  static SMESH_HypoPredicate* IsGlobal(const TopoDS_Shape& theMainShape);
+  static SMESH_HypoPredicate* HasName(const std::string & theName);
+  static SMESH_HypoPredicate* HasDim(const int theDim);
+  static SMESH_HypoPredicate* HasType(const int theHypType);
+
+  bool IsOk (const SMESH_Hypothesis* aHyp,
+             const TopoDS_Shape&     aShape) const;
+  // check aHyp or/and aShape it is assigned to
+
+  ~SMESH_HypoFilter();
+
+
+ protected:
+  // fields
+
+  std::list<SMESH_HypoPredicate*> myPredicates;
+
+  // private methods
+
+  enum Logical { AND, AND_NOT, OR, OR_NOT };
+  enum Comparison { EQUAL, NOT_EQUAL, MORE, LESS };
+
+  SMESH_HypoFilter(const SMESH_HypoFilter& other){}
+
+  void add( Logical bool_op, SMESH_HypoPredicate* pred )
+  {
+    if ( pred ) {
+      pred->_logical_op = bool_op;
+      myPredicates.push_back( pred );
+    }
+  }
+
+  // predicates implementation
+
+  template <typename TValue>
+    struct templPredicate: public SMESH_HypoPredicate {
+      Comparison _comp;
+      TValue     _val;
+      virtual TValue Value(const SMESH_Hypothesis* aHyp) const = 0;
+      virtual bool IsOk(const SMESH_Hypothesis* aHyp, const TopoDS_Shape& ) const
+      {
+        if      ( _comp == EQUAL )     return _val == Value( aHyp );
+        else if ( _comp == NOT_EQUAL ) return _val != Value( aHyp );
+        else if ( _comp == MORE )      return _val < Value( aHyp );
+        else                           return _val > Value( aHyp );
+      }
+    };
+
+  struct NamePredicate : public SMESH_HypoPredicate {
+    std::string _name;
+    NamePredicate( std::string name ): _name(name){}
+    bool IsOk(const SMESH_Hypothesis* aHyp,
+              const TopoDS_Shape&     aShape) const;
+  };
+  
+  struct TypePredicate : public templPredicate< int > {
+    TypePredicate( Comparison comp, int hypType )
+    { _comp = comp; _val = hypType; }
+    int Value( const SMESH_Hypothesis* aHyp ) const;
+  };
+  
+  struct DimPredicate : public templPredicate< int > {
+    DimPredicate( Comparison comp, int dim )
+    { _comp = comp; _val = dim; }
+    int Value( const SMESH_Hypothesis* aHyp ) const;
+  };
+  
+  struct ApplicablePredicate : public SMESH_HypoPredicate {
+    int _shapeType;
+    ApplicablePredicate( const TopoDS_Shape& theShape );
+    bool IsOk(const SMESH_Hypothesis* aHyp,
+              const TopoDS_Shape&     aShape) const;
+  };
+        
+  struct InstancePredicate : public SMESH_HypoPredicate {
+    const SMESH_Hypothesis* _hypo;
+    InstancePredicate( const SMESH_Hypothesis* hypo ):_hypo(hypo){}
+    bool IsOk(const SMESH_Hypothesis* aHyp,
+              const TopoDS_Shape&     aShape) const;
+  };
+        
+  struct IsAssignedToPredicate : public SMESH_HypoPredicate {
+    TopoDS_Shape _mainShape;
+    IsAssignedToPredicate( const TopoDS_Shape& mainShape ):_mainShape(mainShape){}
+    bool IsOk(const SMESH_Hypothesis* aHyp,
+              const TopoDS_Shape&     aShape) const;
+  };
+        
+};
+
+
+#endif
diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx
new file mode 100644 (file)
index 0000000..5f92232
--- /dev/null
@@ -0,0 +1,1065 @@
+//  SMESH SMESHDS : management of mesh data and SMESH document
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESH_Mesh.cxx
+//  Author : Yves FRICAUD, OCC
+//  Module : SMESH
+//  $Header: 
+
+#include "SMESHDS_Mesh.hxx"
+
+#include "SMESHDS_Group.hxx"
+#include "SMDS_VertexPosition.hxx"
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_FacePosition.hxx"
+#include "SMESHDS_GroupOnGeom.hxx"
+#include <TopExp_Explorer.hxx>
+#include <TopExp.hxx>
+#include <TopoDS_Iterator.hxx>
+
+#include "utilities.h"
+
+using namespace std;
+
+//=======================================================================
+//function : Create
+//purpose  : 
+//=======================================================================
+SMESHDS_Mesh::SMESHDS_Mesh(int MeshID):myMeshID(MeshID)
+{
+       myScript = new SMESHDS_Script();
+}
+
+//=======================================================================
+//function : ShapeToMesh
+//purpose  : 
+//=======================================================================
+void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S)
+{
+  if ( !myShape.IsNull() && S.IsNull() )
+  {
+    // removal of a shape to mesh, delete ...
+    // - hypotheses
+    myShapeToHypothesis.clear();
+    // - shape indices in SMDS_Position of nodes
+    map<int,SMESHDS_SubMesh*>::iterator i_sub = myShapeIndexToSubMesh.begin();
+    for ( ; i_sub != myShapeIndexToSubMesh.end(); i_sub++ ) {
+      if ( !i_sub->second->IsComplexSubmesh() ) {
+        SMDS_NodeIteratorPtr nIt = i_sub->second->GetNodes();
+        while ( nIt->more() )
+          nIt->next()->GetPosition()->SetShapeId( 0 );
+      }
+    }
+    // - sub-meshes
+    myIndexToShape.Clear();
+    myShapeIndexToSubMesh.clear();
+    // - groups on geometry
+    set<SMESHDS_GroupBase*>::iterator gr = myGroups.begin();
+    while ( gr != myGroups.end() ) {
+      if ( dynamic_cast<SMESHDS_GroupOnGeom*>( *gr ))
+        myGroups.erase( gr++ );
+      else
+        gr++;
+    }
+  }
+  else {
+    myShape = S;
+    if ( !S.IsNull() )
+      TopExp::MapShapes(myShape, myIndexToShape);
+  }
+}
+
+//=======================================================================
+//function : AddHypothesis
+//purpose  : 
+//=======================================================================
+
+bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS,
+       const SMESHDS_Hypothesis * H)
+{
+       list<const SMESHDS_Hypothesis *>& alist=myShapeToHypothesis[SS];
+
+       //Check if the Hypothesis is still present
+       list<const SMESHDS_Hypothesis*>::iterator ith=alist.begin();
+
+       for (; ith!=alist.end(); ith++)
+               if (H == *ith) return false;
+
+       alist.push_back(H);
+       return true;
+}
+
+//=======================================================================
+//function : RemoveHypothesis
+//purpose  : 
+//=======================================================================
+
+bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S,
+       const SMESHDS_Hypothesis * H)
+{
+       ShapeToHypothesis::iterator its=myShapeToHypothesis.find(S);
+       if(its!=myShapeToHypothesis.end())
+       {
+               list<const SMESHDS_Hypothesis*>::iterator ith=(*its).second.begin();
+
+               for (; ith!=(*its).second.end(); ith++)
+                       if (H == *ith)
+                       {
+                               (*its).second.erase(ith);
+                               return true;
+                       }
+       }
+       return false;
+}
+
+//=======================================================================
+//function : AddNode
+//purpose  : 
+//=======================================================================
+SMDS_MeshNode* SMESHDS_Mesh::AddNode(double x, double y, double z){
+  SMDS_MeshNode* node = SMDS_Mesh::AddNode(x, y, z);
+  if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
+  return node;
+}
+
+SMDS_MeshNode* SMESHDS_Mesh::AddNodeWithID(double x, double y, double z, int ID){
+  SMDS_MeshNode* node = SMDS_Mesh::AddNodeWithID(x,y,z,ID);
+  if(node!=NULL) myScript->AddNode(node->GetID(), x, y, z);
+  return node;
+}
+
+//=======================================================================
+//function : MoveNode
+//purpose  : 
+//=======================================================================
+void SMESHDS_Mesh::MoveNode(const SMDS_MeshNode *n, double x, double y, double z)
+{
+  SMDS_MeshNode * node=const_cast<SMDS_MeshNode*>(n);
+  node->setXYZ(x,y,z);
+  myScript->MoveNode(n->GetID(), x, y, z);
+}
+
+//=======================================================================
+//function : ChangeElementNodes
+//purpose  : 
+//=======================================================================
+
+bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
+                                      const SMDS_MeshNode    * nodes[],
+                                      const int                nbnodes)
+{
+  if ( ! SMDS_Mesh::ChangeElementNodes( elem, nodes, nbnodes ))
+    return false;
+
+  vector<int> IDs( nbnodes );
+  for ( int i = 0; i < nbnodes; i++ )
+    IDs [ i ] = nodes[ i ]->GetID();
+  myScript->ChangeElementNodes( elem->GetID(), &IDs[0], nbnodes);
+
+  return true;
+}
+
+//=======================================================================
+//function : ChangePolygonNodes
+//purpose  : 
+//=======================================================================
+bool SMESHDS_Mesh::ChangePolygonNodes
+                   (const SMDS_MeshElement *     elem,
+                    vector<const SMDS_MeshNode*> nodes)
+{
+  ASSERT(nodes.size() > 3);
+
+  return ChangeElementNodes(elem, &nodes[0], nodes.size());
+}
+
+//=======================================================================
+//function : ChangePolyhedronNodes
+//purpose  : 
+//=======================================================================
+bool SMESHDS_Mesh::ChangePolyhedronNodes
+                   (const SMDS_MeshElement * elem,
+                    std::vector<const SMDS_MeshNode*> nodes,
+                    std::vector<int>                  quantities)
+{
+  ASSERT(nodes.size() > 3);
+
+  if (!SMDS_Mesh::ChangePolyhedronNodes(elem, nodes, quantities))
+    return false;
+
+  int i, len = nodes.size();
+  std::vector<int> nodes_ids (len);
+  for (i = 0; i < len; i++) {
+    nodes_ids[i] = nodes[i]->GetID();
+  }
+  myScript->ChangePolyhedronNodes(elem->GetID(), nodes_ids, quantities);
+
+  return true;
+}
+
+//=======================================================================
+//function : Renumber
+//purpose  : 
+//=======================================================================
+
+void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
+{
+  SMDS_Mesh::Renumber( isNodes, startID, deltaID );
+  myScript->Renumber( isNodes, startID, deltaID );
+}
+
+//=======================================================================
+//function :AddEdgeWithID
+//purpose  : 
+//=======================================================================
+SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(int n1, int n2, int ID)
+{
+  SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdgeWithID(n1,n2,ID);
+  if(anElem) myScript->AddEdge(ID,n1,n2);
+  return anElem;
+}
+
+SMDS_MeshEdge* SMESHDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
+                                          const SMDS_MeshNode * n2, 
+                                          int ID)
+{
+  return AddEdgeWithID(n1->GetID(),
+                      n2->GetID(),
+                      ID);
+}
+
+SMDS_MeshEdge* SMESHDS_Mesh::AddEdge(const SMDS_MeshNode * n1,
+                                    const SMDS_MeshNode * n2)
+{
+  SMDS_MeshEdge* anElem = SMDS_Mesh::AddEdge(n1,n2);
+  if(anElem) myScript->AddEdge(anElem->GetID(), 
+                              n1->GetID(), 
+                              n2->GetID());
+  return anElem;
+}
+
+//=======================================================================
+//function :AddFace
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int ID)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, ID);
+  if(anElem) myScript->AddFace(ID,n1,n2,n3);
+  return anElem;
+}
+
+SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
+                                          const SMDS_MeshNode * n2,
+                                          const SMDS_MeshNode * n3, 
+                                          int ID)
+{
+  return AddFaceWithID(n1->GetID(),
+                      n2->GetID(),
+                      n3->GetID(),
+                      ID);
+}
+
+SMDS_MeshFace* SMESHDS_Mesh::AddFace( const SMDS_MeshNode * n1,
+                                     const SMDS_MeshNode * n2,
+                                     const SMDS_MeshNode * n3)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3);
+  if(anElem) myScript->AddFace(anElem->GetID(), 
+                              n1->GetID(), 
+                              n2->GetID(),
+                              n3->GetID());
+  return anElem;
+}
+
+//=======================================================================
+//function :AddFace
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(int n1, int n2, int n3, int n4, int ID)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddFaceWithID(n1, n2, n3, n4, ID);
+  if(anElem) myScript->AddFace(ID, n1, n2, n3, n4);
+  return anElem;
+}
+
+SMDS_MeshFace* SMESHDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
+                                          const SMDS_MeshNode * n2,
+                                          const SMDS_MeshNode * n3,
+                                          const SMDS_MeshNode * n4, 
+                                          int ID)
+{
+  return AddFaceWithID(n1->GetID(),
+                      n2->GetID(),
+                      n3->GetID(),
+                      n4->GetID(),
+                      ID);
+}
+
+SMDS_MeshFace* SMESHDS_Mesh::AddFace(const SMDS_MeshNode * n1,
+                                    const SMDS_MeshNode * n2,
+                                    const SMDS_MeshNode * n3,
+                                    const SMDS_MeshNode * n4)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddFace(n1, n2, n3, n4);
+  if(anElem) myScript->AddFace(anElem->GetID(), 
+                              n1->GetID(), 
+                              n2->GetID(), 
+                              n3->GetID(),
+                              n4->GetID());
+  return anElem;
+}
+
+//=======================================================================
+//function :AddVolume
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int ID)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
+  if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4);
+  return anElem;
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                              const SMDS_MeshNode * n2,
+                                              const SMDS_MeshNode * n3,
+                                              const SMDS_MeshNode * n4, 
+                                              int ID)
+{
+  return AddVolumeWithID(n1->GetID(), 
+                        n2->GetID(), 
+                        n3->GetID(),
+                        n4->GetID(),
+                        ID);
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                        const SMDS_MeshNode * n2,
+                                        const SMDS_MeshNode * n3,
+                                        const SMDS_MeshNode * n4)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4);
+  if(anElem) myScript->AddVolume(anElem->GetID(), 
+                                n1->GetID(), 
+                                n2->GetID(), 
+                                n3->GetID(),
+                                n4->GetID());
+  return anElem;
+}
+
+//=======================================================================
+//function :AddVolume
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int ID)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
+  if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5);
+  return anElem;
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                              const SMDS_MeshNode * n2,
+                                              const SMDS_MeshNode * n3,
+                                              const SMDS_MeshNode * n4,
+                                              const SMDS_MeshNode * n5, 
+                                              int ID)
+{
+  return AddVolumeWithID(n1->GetID(), 
+                        n2->GetID(), 
+                        n3->GetID(),
+                        n4->GetID(), 
+                        n5->GetID(),
+                        ID);
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                        const SMDS_MeshNode * n2,
+                                        const SMDS_MeshNode * n3,
+                                        const SMDS_MeshNode * n4,
+                                        const SMDS_MeshNode * n5)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5);
+  if(anElem) myScript->AddVolume(anElem->GetID(), 
+                                n1->GetID(), 
+                                n2->GetID(), 
+                                n3->GetID(),
+                                n4->GetID(), 
+                                n5->GetID());
+  return anElem;
+}
+
+//=======================================================================
+//function :AddVolume
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int ID)
+{
+  SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
+  if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6);
+  return anElem;
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                              const SMDS_MeshNode * n2,
+                                              const SMDS_MeshNode * n3,
+                                              const SMDS_MeshNode * n4,
+                                              const SMDS_MeshNode * n5,
+                                              const SMDS_MeshNode * n6, 
+                                              int ID)
+{
+  return AddVolumeWithID(n1->GetID(), 
+                        n2->GetID(), 
+                        n3->GetID(),
+                        n4->GetID(), 
+                        n5->GetID(), 
+                        n6->GetID(),
+                        ID);
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                        const SMDS_MeshNode * n2,
+                                        const SMDS_MeshNode * n3,
+                                        const SMDS_MeshNode * n4,
+                                        const SMDS_MeshNode * n5,
+                                        const SMDS_MeshNode * n6)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6);
+  if(anElem) myScript->AddVolume(anElem->GetID(), 
+                                n1->GetID(), 
+                                n2->GetID(), 
+                                n3->GetID(),
+                                n4->GetID(), 
+                                n5->GetID(), 
+                                n6->GetID());
+  return anElem;
+}
+
+//=======================================================================
+//function :AddVolume
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int ID)
+{
+  SMDS_MeshVolume *anElem= SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
+  if(anElem) myScript->AddVolume(ID, n1, n2, n3, n4, n5, n6, n7, n8);
+  return anElem;
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
+                                              const SMDS_MeshNode * n2,
+                                              const SMDS_MeshNode * n3,
+                                              const SMDS_MeshNode * n4,
+                                              const SMDS_MeshNode * n5,
+                                              const SMDS_MeshNode * n6,
+                                              const SMDS_MeshNode * n7,
+                                              const SMDS_MeshNode * n8, 
+                                              int ID)
+{
+  return AddVolumeWithID(n1->GetID(), 
+                        n2->GetID(), 
+                        n3->GetID(),
+                        n4->GetID(), 
+                        n5->GetID(), 
+                        n6->GetID(), 
+                        n7->GetID(), 
+                        n8->GetID(),
+                        ID);
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
+                                        const SMDS_MeshNode * n2,
+                                        const SMDS_MeshNode * n3,
+                                        const SMDS_MeshNode * n4,
+                                        const SMDS_MeshNode * n5,
+                                        const SMDS_MeshNode * n6,
+                                        const SMDS_MeshNode * n7,
+                                        const SMDS_MeshNode * n8)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
+  if(anElem) myScript->AddVolume(anElem->GetID(), 
+                                n1->GetID(), 
+                                n2->GetID(), 
+                                n3->GetID(),
+                                n4->GetID(), 
+                                n5->GetID(), 
+                                n6->GetID(), 
+                                n7->GetID(), 
+                                n8->GetID());
+  return anElem;
+}
+
+//=======================================================================
+//function : AddPolygonalFace
+//purpose  : 
+//=======================================================================
+SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
+                                                     const int        ID)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes_ids, ID);
+  if (anElem) {
+    myScript->AddPolygonalFace(ID, nodes_ids);
+  }
+  return anElem;
+}
+
+SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID
+                             (std::vector<const SMDS_MeshNode*> nodes,
+                              const int                         ID)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
+  if (anElem) {
+    int i, len = nodes.size();
+    std::vector<int> nodes_ids (len);
+    for (i = 0; i < len; i++) {
+      nodes_ids[i] = nodes[i]->GetID();
+    }
+    myScript->AddPolygonalFace(ID, nodes_ids);
+  }
+  return anElem;
+}
+
+SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace
+                             (std::vector<const SMDS_MeshNode*> nodes)
+{
+  SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes);
+  if (anElem) {
+    int i, len = nodes.size();
+    std::vector<int> nodes_ids (len);
+    for (i = 0; i < len; i++) {
+      nodes_ids[i] = nodes[i]->GetID();
+    }
+    myScript->AddPolygonalFace(anElem->GetID(), nodes_ids);
+  }
+  return anElem;
+}
+
+//=======================================================================
+//function : AddPolyhedralVolume
+//purpose  : 
+//=======================================================================
+SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (std::vector<int> nodes_ids,
+                                                          std::vector<int> quantities,
+                                                          const int        ID)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes_ids, quantities, ID);
+  if (anElem) {
+    myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
+  }
+  return anElem;
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID
+                               (std::vector<const SMDS_MeshNode*> nodes,
+                                std::vector<int>                  quantities,
+                                const int                         ID)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
+  if (anElem) {
+    int i, len = nodes.size();
+    std::vector<int> nodes_ids (len);
+    for (i = 0; i < len; i++) {
+      nodes_ids[i] = nodes[i]->GetID();
+    }
+    myScript->AddPolyhedralVolume(ID, nodes_ids, quantities);
+  }
+  return anElem;
+}
+
+SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume
+                               (std::vector<const SMDS_MeshNode*> nodes,
+                                std::vector<int>                  quantities)
+{
+  SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolume(nodes, quantities);
+  if (anElem) {
+    int i, len = nodes.size();
+    std::vector<int> nodes_ids (len);
+    for (i = 0; i < len; i++) {
+      nodes_ids[i] = nodes[i]->GetID();
+    }
+    myScript->AddPolyhedralVolume(anElem->GetID(), nodes_ids, quantities);
+  }
+  return anElem;
+}
+
+//=======================================================================
+//function : removeFromContainers
+//purpose  : 
+//=======================================================================
+
+static void removeFromContainers (map<int,SMESHDS_SubMesh*> &      theSubMeshes,
+                                  set<SMESHDS_GroupBase*>&             theGroups,
+                                  list<const SMDS_MeshElement *> & theElems,
+                                  const bool                       isNode)
+{
+  if ( theElems.empty() )
+    return;
+
+  // Rm from group
+  // Element can belong to several groups
+  if ( !theGroups.empty() )
+  {
+    set<SMESHDS_GroupBase*>::iterator GrIt = theGroups.begin();
+    for ( ; GrIt != theGroups.end(); GrIt++ )
+    {
+      SMESHDS_Group* group = dynamic_cast<SMESHDS_Group*>( *GrIt );
+      if ( !group || group->IsEmpty() ) continue;
+
+      list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
+      for ( ; elIt != theElems.end(); elIt++ )
+      {
+        group->SMDSGroup().Remove( *elIt );
+        if ( group->IsEmpty() ) break;
+      }
+    }
+  }
+
+  // Rm from sub-meshes
+  // Element should belong to only one sub-mesh
+  map<int,SMESHDS_SubMesh*>::iterator SubIt = theSubMeshes.begin();
+  for ( ; SubIt != theSubMeshes.end(); SubIt++ )
+  {
+    int size = isNode ? (*SubIt).second->NbNodes() : (*SubIt).second->NbElements();
+    if ( size == 0 ) continue;
+
+    list<const SMDS_MeshElement *>::iterator elIt = theElems.begin();
+    while ( elIt != theElems.end() )
+    {
+      bool removed = false;
+      if ( isNode )
+        removed = (*SubIt).second->RemoveNode( static_cast<const SMDS_MeshNode*> (*elIt) );
+      else
+        removed = (*SubIt).second->RemoveElement( *elIt );
+
+      if (removed)
+      {
+        elIt = theElems.erase( elIt );
+        if ( theElems.empty() )
+          return; // all elements are found and removed
+      }
+      else
+      {
+        elIt++ ;
+      }
+    }
+  }
+}
+  
+//=======================================================================
+//function : RemoveNode
+//purpose  : 
+//=======================================================================
+void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
+{
+  myScript->RemoveNode(n->GetID());
+  
+  list<const SMDS_MeshElement *> removedElems;
+  list<const SMDS_MeshElement *> removedNodes;
+
+  SMDS_Mesh::RemoveElement( n, removedElems, removedNodes, true );
+
+  removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
+  removeFromContainers( myShapeIndexToSubMesh, myGroups, removedNodes, true );
+}
+
+//=======================================================================
+//function : RemoveElement
+//purpose  : 
+//========================================================================
+void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
+{
+  if (elt->GetType() == SMDSAbs_Node)
+  {
+    RemoveNode( static_cast<const SMDS_MeshNode*>( elt ));
+    return;
+  }
+
+  myScript->RemoveElement(elt->GetID());
+
+  list<const SMDS_MeshElement *> removedElems;
+  list<const SMDS_MeshElement *> removedNodes;
+
+  SMDS_Mesh::RemoveElement(elt, removedElems, removedNodes, false);
+  
+  removeFromContainers( myShapeIndexToSubMesh, myGroups, removedElems, false );
+}
+
+//=======================================================================
+//function : SetNodeOnVolume
+//purpose  : 
+//=======================================================================
+void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
+                                   const TopoDS_Shell & S)
+{
+  SetNodeInVolume( aNode, myIndexToShape.FindIndex(S) );
+}
+//=======================================================================
+//function : SetNodeOnVolume
+//purpose  : 
+//=======================================================================
+void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
+                                   const TopoDS_Solid & S)
+{
+  SetNodeInVolume( aNode, myIndexToShape.FindIndex(S) );
+}
+
+//=======================================================================
+//function : SetNodeOnFace
+//purpose  : 
+//=======================================================================
+void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode *     aNode,
+                                 const TopoDS_Face & S,
+                                 double              u,
+                                 double              v)
+{
+  SetNodeOnFace( aNode, myIndexToShape.FindIndex(S), u, v );
+}
+
+//=======================================================================
+//function : SetNodeOnEdge
+//purpose  : 
+//=======================================================================
+void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode *     aNode,
+                                 const TopoDS_Edge & S,
+                                 double              u)
+{
+  SetNodeOnEdge( aNode, myIndexToShape.FindIndex(S), u );
+}
+
+//=======================================================================
+//function : SetNodeOnVertex
+//purpose  : 
+//=======================================================================
+void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode *       aNode,
+                                   const TopoDS_Vertex & S)
+{
+  SetNodeOnVertex( aNode, myIndexToShape.FindIndex(S));
+}
+
+//=======================================================================
+//function : UnSetNodeOnShape
+//purpose  : 
+//=======================================================================
+void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
+{
+       MESSAGE("not implemented");
+}
+
+//=======================================================================
+//function : SetMeshElementOnShape
+//purpose  : 
+//=======================================================================
+void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement * anElement,
+       const TopoDS_Shape & S)
+{
+       if (myShape.IsNull()) MESSAGE("myShape is NULL");
+
+       int Index = myIndexToShape.FindIndex(S);
+
+       if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
+               myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
+
+       myShapeIndexToSubMesh[Index]->AddElement(anElement);
+}
+
+//=======================================================================
+//function : UnSetMeshElementOnShape
+//purpose  : 
+//=======================================================================
+void SMESHDS_Mesh::
+UnSetMeshElementOnShape(const SMDS_MeshElement * anElement,
+       const TopoDS_Shape & S)
+{
+       if (myShape.IsNull()) MESSAGE("myShape is NULL");
+
+       int Index = myIndexToShape.FindIndex(S);
+
+       if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end())
+               myShapeIndexToSubMesh[Index]->RemoveElement(anElement);
+}
+
+//=======================================================================
+//function : ShapeToMesh
+//purpose  : 
+//=======================================================================
+TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const
+{
+       return myShape;
+}
+
+//=======================================================================
+//function : IsGroupOfSubShapes
+//purpose  : return true if at least one subshape of theShape is a subshape
+//           of myShape or theShape == myShape
+//=======================================================================
+
+bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const
+{
+  if ( myShape.IsSame( theShape ))
+    return true;
+
+  for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() ) {
+    if (myIndexToShape.Contains( it.Value() ) ||
+        IsGroupOfSubShapes( it.Value() ))
+      return true;
+  }
+  
+  return false;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the sub mesh linked to the a given TopoDS_Shape or NULL if the given
+/// TopoDS_Shape is unknown
+///////////////////////////////////////////////////////////////////////////////
+SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const TopoDS_Shape & S) const
+{
+  if (myShape.IsNull()) MESSAGE("myShape is NULL");
+
+  int Index = ShapeToIndex(S);
+  TShapeIndexToSubMesh::const_iterator anIter = myShapeIndexToSubMesh.find(Index);
+  if (anIter != myShapeIndexToSubMesh.end())
+    return anIter->second;
+  else
+    return NULL;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the sub mesh by Id of shape it is linked to
+///////////////////////////////////////////////////////////////////////////////
+SMESHDS_SubMesh * SMESHDS_Mesh::MeshElements(const int Index)
+{
+  if (myShape.IsNull()) MESSAGE("myShape is NULL");
+
+  if (myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end())
+    return myShapeIndexToSubMesh[Index];
+  else
+    return NULL;
+}
+
+//=======================================================================
+//function : SubMeshIndices
+//purpose  : 
+//=======================================================================
+list<int> SMESHDS_Mesh::SubMeshIndices()
+{
+  list<int> anIndices;
+  std::map<int,SMESHDS_SubMesh*>::iterator anIter = myShapeIndexToSubMesh.begin();
+  for (; anIter != myShapeIndexToSubMesh.end(); anIter++) {
+    anIndices.push_back((*anIter).first);
+  }
+  return anIndices;
+}
+
+//=======================================================================
+//function : GetHypothesis
+//purpose  : 
+//=======================================================================
+
+const list<const SMESHDS_Hypothesis*>& SMESHDS_Mesh::GetHypothesis(
+       const TopoDS_Shape & S) const
+{
+       if (myShapeToHypothesis.find(S)!=myShapeToHypothesis.end())
+               return myShapeToHypothesis.find(S)->second;
+
+       static list<const SMESHDS_Hypothesis*> empty;
+       return empty;
+}
+
+//=======================================================================
+//function : GetScript
+//purpose  : 
+//=======================================================================
+SMESHDS_Script* SMESHDS_Mesh::GetScript()
+{
+       return myScript;
+}
+
+//=======================================================================
+//function : ClearScript
+//purpose  : 
+//=======================================================================
+void SMESHDS_Mesh::ClearScript()
+{
+       myScript->Clear();
+}
+
+//=======================================================================
+//function : HasMeshElements
+//purpose  : 
+//=======================================================================
+bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S)
+{
+       if (myShape.IsNull()) MESSAGE("myShape is NULL");
+       int Index = myIndexToShape.FindIndex(S);
+       return myShapeIndexToSubMesh.find(Index)!=myShapeIndexToSubMesh.end();
+}
+
+//=======================================================================
+//function : HasHypothesis
+//purpose  : 
+//=======================================================================
+bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
+{
+       return myShapeToHypothesis.find(S)!=myShapeToHypothesis.end();
+}
+
+//=======================================================================
+//function : NewSubMesh 
+//purpose  : 
+//=======================================================================
+SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
+{
+  SMESHDS_SubMesh* SM = 0;
+  TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
+  if (anIter == myShapeIndexToSubMesh.end())
+  {
+    SM = new SMESHDS_SubMesh();
+    myShapeIndexToSubMesh[Index]=SM;
+  }
+  else
+    SM = anIter->second;
+  return SM;
+}
+
+//=======================================================================
+//function : AddCompoundSubmesh
+//purpose  : 
+//=======================================================================
+
+int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S,
+                                     TopAbs_ShapeEnum    type)
+{
+  int aMainIndex = 0;
+  if ( IsGroupOfSubShapes( S ) || (S.ShapeType() == TopAbs_VERTEX && myIndexToShape.Contains(S)) )
+  {
+    aMainIndex = myIndexToShape.Add( S );
+    bool all = ( type == TopAbs_SHAPE );
+    if ( all ) // corresponding simple submesh may exist
+      aMainIndex = -aMainIndex;
+    //MESSAGE("AddCompoundSubmesh index = " << aMainIndex );
+    SMESHDS_SubMesh * aNewSub = NewSubMesh( aMainIndex );
+    if ( !aNewSub->IsComplexSubmesh() ) // is empty
+    {
+      int shapeType = all ? myShape.ShapeType() : type;
+      int typeLimit = all ? TopAbs_VERTEX : type;
+      for ( ; shapeType <= typeLimit; shapeType++ )
+      {
+        TopExp_Explorer exp( S, TopAbs_ShapeEnum( shapeType ));
+        for ( ; exp.More(); exp.Next() )
+        {
+          int index = myIndexToShape.FindIndex( exp.Current() );
+          if ( index )
+            aNewSub->AddSubMesh( NewSubMesh( index ));
+        }
+      }
+    }
+  }
+  return aMainIndex;
+}
+
+//=======================================================================
+//function : IndexToShape
+//purpose  : 
+//=======================================================================
+TopoDS_Shape SMESHDS_Mesh::IndexToShape(int ShapeIndex)
+{
+       return myIndexToShape.FindKey(ShapeIndex);
+}
+
+//=======================================================================
+//function : ShapeToIndex
+//purpose  : 
+//=======================================================================
+int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
+{
+  if (myShape.IsNull())
+    MESSAGE("myShape is NULL");
+
+  int index = myIndexToShape.FindIndex(S);
+  
+  return index;
+}
+
+//=======================================================================
+//function : SetNodeOnVolume
+//purpose  : 
+//=======================================================================
+void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
+{
+  addNodeToSubmesh( aNode, Index );
+}
+
+//=======================================================================
+//function : SetNodeOnFace
+//purpose  : 
+//=======================================================================
+void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, double v)
+{
+  //Set Position on Node
+  aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, u, v)));
+
+  addNodeToSubmesh( aNode, Index );
+}
+
+//=======================================================================
+//function : SetNodeOnEdge
+//purpose  : 
+//=======================================================================
+void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode,
+                                 int            Index,
+                                 double         u)
+{
+  //Set Position on Node
+  aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, u)));
+
+  addNodeToSubmesh( aNode, Index );
+}
+
+//=======================================================================
+//function : SetNodeOnVertex
+//purpose  : 
+//=======================================================================
+void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
+{
+  //Set Position on Node
+  aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index)));
+
+  addNodeToSubmesh( aNode, Index );
+}
+
+//=======================================================================
+//function : SetMeshElementOnShape
+//purpose  : 
+//=======================================================================
+void SMESHDS_Mesh::SetMeshElementOnShape(const SMDS_MeshElement* anElement,
+       int Index)
+{
+       if (myShapeIndexToSubMesh.find(Index)==myShapeIndexToSubMesh.end())
+               myShapeIndexToSubMesh[Index]=new SMESHDS_SubMesh();
+
+       myShapeIndexToSubMesh[Index]->AddElement(anElement);
+}
+
+SMESHDS_Mesh::~SMESHDS_Mesh()
+{
+}
diff --git a/src/SMESHDS/SMESHDS_SubMesh.cxx b/src/SMESHDS/SMESHDS_SubMesh.cxx
new file mode 100644 (file)
index 0000000..5bdbfc6
--- /dev/null
@@ -0,0 +1,299 @@
+//  SMESH SMESHDS : management of mesh data and SMESH document
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESH_SubMesh.cxx
+//  Author : Yves FRICAUD, OCC
+//  Module : SMESH
+//  $Header: 
+
+#include "SMESHDS_SubMesh.hxx"
+
+#include "utilities.h"
+
+using namespace std;
+
+//=======================================================================
+//function : AddElement
+//purpose  : 
+//=======================================================================
+void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME)
+{
+  if ( !IsComplexSubmesh() )
+    myElements.insert(ME);
+}
+
+//=======================================================================
+//function : RemoveElement
+//purpose  : 
+//=======================================================================
+bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME)
+{
+  if ( !IsComplexSubmesh() && NbElements() )
+    return myElements.erase(ME);
+  
+  return false;
+}
+
+//=======================================================================
+//function : AddNode
+//purpose  : 
+//=======================================================================
+void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
+{
+  if ( !IsComplexSubmesh() )
+    myNodes.insert(N);
+}
+
+//=======================================================================
+//function : RemoveNode
+//purpose  : 
+//=======================================================================
+
+bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N)
+{
+  if ( !IsComplexSubmesh() && NbNodes() )
+    return myNodes.erase(N);
+
+  return false;
+}
+
+//=======================================================================
+//function : NbElements
+//purpose  : 
+//=======================================================================
+int SMESHDS_SubMesh::NbElements() const
+{
+  if ( !IsComplexSubmesh() )
+    return myElements.size();
+
+  int nbElems = 0;
+#ifndef WNT
+  set<const SMESHDS_SubMesh*>::iterator it = mySubMeshes.begin();
+#else
+  set<const SMESHDS_SubMesh*>::const_iterator it = mySubMeshes.begin();
+#endif
+  for ( ; it != mySubMeshes.end(); it++ )
+    nbElems += (*it)->NbElements();
+
+  return nbElems;
+}
+
+//=======================================================================
+//function : NbNodes
+//purpose  : 
+//=======================================================================
+
+int SMESHDS_SubMesh::NbNodes() const
+{
+ if ( !IsComplexSubmesh() )
+   return myNodes.size(); 
+
+  int nbElems = 0;
+#ifndef WNT
+  set<const SMESHDS_SubMesh*>::iterator it = mySubMeshes.begin();
+#else
+  set<const SMESHDS_SubMesh*>::const_iterator it = mySubMeshes.begin();
+#endif
+  for ( ; it != mySubMeshes.end(); it++ )
+    nbElems += (*it)->NbNodes();
+
+  return nbElems;
+}
+
+// =====================
+// class MySetIterator
+// =====================
+
+template<typename T> class MySetIterator:public SMDS_Iterator<const T*>
+{
+  typedef const set<const T*> TSet;
+  typename TSet::const_iterator myIt;
+  TSet& mySet;
+
+  public:
+       MySetIterator(const set<const T*>& s):mySet(s), myIt(s.begin())
+       {
+       }
+
+       bool more()
+       {
+               return myIt!=mySet.end();
+       }
+       const T* next()
+       {
+               const T* t=*myIt;
+               myIt++;
+               return t;                       
+       }
+};
+
+// =====================
+// class MyIterator
+// =====================
+
+template<typename VALUE> class MyIterator : public SMDS_Iterator<VALUE>
+{
+ public:
+  MyIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
+    : mySubMeshes( theSubMeshes ), mySubIt( theSubMeshes.begin() ), myMore(false)
+    {}
+  bool more()
+  {
+    while (( !myElemIt.get() || !myElemIt->more() ) &&
+           mySubIt != mySubMeshes.end())
+    {
+      myElemIt = getElements(*mySubIt);
+      mySubIt++;
+    }
+    myMore = myElemIt.get() && myElemIt->more();
+    return myMore;
+  }
+  VALUE next()
+  {
+    VALUE elem = 0;
+    if ( myMore )
+      elem = myElemIt->next();
+    return elem;
+  }
+ protected:
+  virtual boost::shared_ptr< SMDS_Iterator<VALUE> >
+    getElements(const SMESHDS_SubMesh*) const = 0;
+
+ private:
+  bool                                        myMore;
+  const set<const SMESHDS_SubMesh*>&          mySubMeshes;
+  set<const SMESHDS_SubMesh*>::const_iterator mySubIt;
+  boost::shared_ptr< SMDS_Iterator<VALUE> >   myElemIt;
+};
+
+// =====================
+// class MyElemIterator
+// =====================
+
+class MyElemIterator: public MyIterator<const SMDS_MeshElement*>
+{
+ public:
+  MyElemIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
+    :MyIterator<const SMDS_MeshElement*>( theSubMeshes ) {}
+  SMDS_ElemIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const
+  { return theSubMesh->GetElements(); }
+};
+
+// =====================
+// class MyNodeIterator
+// =====================
+
+class MyNodeIterator: public MyIterator<const SMDS_MeshNode*>
+{
+ public:
+  MyNodeIterator (const set<const SMESHDS_SubMesh*>& theSubMeshes)
+    :MyIterator<const SMDS_MeshNode*>( theSubMeshes ) {}
+  SMDS_NodeIteratorPtr getElements(const SMESHDS_SubMesh* theSubMesh) const
+  { return theSubMesh->GetNodes(); }
+};
+  
+//=======================================================================
+//function : GetElements
+//purpose  : 
+//=======================================================================
+
+SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const
+{
+  if ( IsComplexSubmesh() )
+    return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes ));
+
+  return SMDS_ElemIteratorPtr(new MySetIterator<SMDS_MeshElement>(myElements));
+}
+
+//=======================================================================
+//function : GetNodes
+//purpose  : 
+//=======================================================================
+
+SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const
+{
+  if ( IsComplexSubmesh() )
+    return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes ));
+
+  return SMDS_NodeIteratorPtr(new MySetIterator<SMDS_MeshNode>(myNodes));
+}
+
+//=======================================================================
+//function : Contains
+//purpose  : check if elem or node is in
+//=======================================================================
+
+bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const
+{
+  // DO NOT TRY TO FIND A REMOVED ELEMENT !!
+  if ( !ME )
+    return false;
+
+  if ( IsComplexSubmesh() )
+  {
+    set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
+    for ( ; aSubIt != mySubMeshes.end(); aSubIt++ )
+      if ( (*aSubIt)->Contains( ME ))
+        return true;
+    return false;
+  }
+
+  if ( ME->GetType() == SMDSAbs_Node )
+  {
+    const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( ME );
+    return ( myNodes.find( n ) != myNodes.end() );
+  }
+
+  return ( myElements.find( ME ) != myElements.end() );
+}
+
+//=======================================================================
+//function : AddSubMesh
+//purpose  : 
+//=======================================================================
+
+void SMESHDS_SubMesh::AddSubMesh( const SMESHDS_SubMesh* theSubMesh )
+{
+  ASSERT( theSubMesh );
+  mySubMeshes.insert( theSubMesh );
+}
+
+//=======================================================================
+//function : RemoveSubMesh
+//purpose  : 
+//=======================================================================
+
+bool SMESHDS_SubMesh::RemoveSubMesh( const SMESHDS_SubMesh* theSubMesh )
+{
+  return mySubMeshes.erase( theSubMesh );
+}
+
+//=======================================================================
+//function : ContainsSubMesh
+//purpose  : 
+//=======================================================================
+
+bool SMESHDS_SubMesh::ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const
+{
+  return mySubMeshes.find( theSubMesh ) != mySubMeshes.end();
+}
diff --git a/src/SMESHDS/SMESHDS_SubMesh.hxx b/src/SMESHDS/SMESHDS_SubMesh.hxx
new file mode 100644 (file)
index 0000000..ac3cd1c
--- /dev/null
@@ -0,0 +1,69 @@
+//  SMESH SMESHDS : management of mesh data and SMESH document
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESHDS_SubMesh.hxx
+//  Module : SMESH
+
+#ifndef _SMESHDS_SubMesh_HeaderFile
+#define _SMESHDS_SubMesh_HeaderFile
+
+#include "SMDS_Mesh.hxx"
+#include <set>
+
+#if defined WNT && defined WIN32 && defined SMESHDS_EXPORTS
+#define SMESHDS_WNT_EXPORT __declspec( dllexport )
+#else
+#define SMESHDS_WNT_EXPORT
+#endif
+
+class SMESHDS_WNT_EXPORT SMESHDS_SubMesh
+{
+ public:
+
+  bool IsComplexSubmesh() const { return !mySubMeshes.empty(); }
+
+  // if !IsComplexSubmesh()
+  void AddElement(const SMDS_MeshElement * ME);
+  bool RemoveElement(const SMDS_MeshElement * ME); // ret true if ME was in
+  void AddNode(const SMDS_MeshNode * ME);
+  bool RemoveNode(const SMDS_MeshNode * ME);       // ret true if ME was in
+
+  // if IsComplexSubmesh()
+  void AddSubMesh( const SMESHDS_SubMesh* theSubMesh );
+  bool RemoveSubMesh( const SMESHDS_SubMesh* theSubMesh );
+  bool ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const;
+
+  // for both types
+  int NbElements() const;
+  SMDS_ElemIteratorPtr GetElements() const;
+  int NbNodes() const;
+  SMDS_NodeIteratorPtr GetNodes() const;
+  bool Contains(const SMDS_MeshElement * ME) const;      // check if elem or node is in
+
+ private:
+  //const SMDS_Mesh * myMesh;
+  std::set<const SMDS_MeshElement*> myElements;
+  std::set<const SMDS_MeshNode*>    myNodes;
+  std::set<const SMESHDS_SubMesh*>  mySubMeshes;
+};
+#endif
diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx
new file mode 100644 (file)
index 0000000..349eb3e
--- /dev/null
@@ -0,0 +1,3059 @@
+//  SMESH SMESHGUI : GUI for SMESH component
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+//
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//  File   : SMESHGUI.cxx
+//  Author : Nicolas REJNERI
+//  Module : SMESH
+//  $Header$
+
+#include "SMESHGUI.h"
+
+#include "SMESHGUI_InitMeshDlg.h"
+#include "SMESHGUI_AddSubMeshDlg.h"
+#include "SMESHGUI_NodesDlg.h"
+#include "SMESHGUI_TransparencyDlg.h"
+#include "SMESHGUI_ClippingDlg.h"
+#include "SMESHGUI_GroupDlg.h"
+#include "SMESHGUI_RemoveNodesDlg.h"
+#include "SMESHGUI_RemoveElementsDlg.h"
+#include "SMESHGUI_MeshInfosDlg.h"
+#include "SMESHGUI_StandardMeshInfosDlg.h"
+#include "SMESHGUI_Preferences_ColorDlg.h"
+#include "SMESHGUI_Preferences_ScalarBarDlg.h"
+#include "SMESHGUI_Preferences_SelectionDlg.h"
+#include "SMESHGUI_Hypotheses.h"
+#include "SMESHGUI_MoveNodesDlg.h"
+#include "SMESHGUI_AddMeshElementDlg.h"
+#include "SMESHGUI_EditHypothesesDlg.h"
+#include "SMESHGUI_CreateHypothesesDlg.h"
+#include "SMESHGUI_FilterDlg.h"
+#include "SMESHGUI_FilterLibraryDlg.h"
+#include "SMESHGUI_SingleEditDlg.h"
+#include "SMESHGUI_MultiEditDlg.h"
+#include "SMESHGUI_GroupOpDlg.h"
+#include "SMESHGUI_DeleteGroupDlg.h"
+#include "SMESHGUI_SmoothingDlg.h"
+#include "SMESHGUI_RenumberingDlg.h"
+#include "SMESHGUI_ExtrusionDlg.h"
+#include "SMESHGUI_ExtrusionAlongPathDlg.h"
+#include "SMESHGUI_RevolutionDlg.h"
+#include "SMESHGUI_TranslationDlg.h"
+#include "SMESHGUI_RotationDlg.h"
+#include "SMESHGUI_SymmetryDlg.h"
+#include "SMESHGUI_SewingDlg.h"
+#include "SMESHGUI_MergeNodesDlg.h"
+#include "SMESHGUI_EditMeshDlg.h"
+#include "SMESHGUI_MeshPatternDlg.h"
+#include "SMESHGUI_PrecisionDlg.h"
+#include "SMESHGUI_Selection.h"
+#include "SMESHGUI_CreatePolyhedralVolumeDlg.h"
+#include "SMESHGUI_MeshOp.h"
+
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_GEOMGenUtils.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_GroupUtils.h"
+#include "SMESHGUI_FilterUtils.h"
+#include "SMESHGUI_PatternUtils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_HypothesesUtils.h"
+
+#include "SMESH_Actor.h"
+#include "SMESH_Object.h"
+#include "SMESH_TypeFilter.hxx"
+
+#include "SalomeApp_Tools.h"
+#include "SalomeApp_Study.h"
+#include "SalomeApp_NameDlg.h"
+#include "SalomeApp_DataOwner.h"
+#include "SalomeApp_Application.h"
+#include "SalomeApp_Preferences.h"
+#include "SalomeApp_VTKSelector.h"
+#include "SalomeApp_Operation.h"
+#include "SalomeApp_UpdateFlags.h"
+
+#include "SalomeApp_ImportOperation.h"
+
+#include <SVTK_ViewWindow.h>
+#include <SVTK_ViewModel.h>
+#include <SVTK_InteractorStyle.h>
+#include <SVTK_RenderWindowInteractor.h>
+
+#include <VTKViewer_ViewManager.h>
+
+#include "OB_Browser.h"
+
+#include "SUIT_Tools.h"
+#include "SUIT_MessageBox.h"
+#include "SUIT_ResourceMgr.h"
+#include "SUIT_FileDlg.h"
+#include "SUIT_Desktop.h"
+#include "SUIT_ResourceMgr.h"
+#include "SUIT_OverrideCursor.h"
+#include "SUIT_Study.h"
+#include "SUIT_Session.h"
+
+#include "QtxPopupMgr.h"
+
+#include "SALOME_ListIO.hxx"
+#include "SALOME_ListIteratorOfListIO.hxx"
+#include "SALOME_InteractiveObject.hxx"
+#include "SALOME_NamingService.hxx"
+#include "SALOME_LifeCycleCORBA.hxx"
+
+#include "SALOMEconfig.h"
+#include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
+
+// QT Includes
+#define         INCLUDE_MENUITEM_DEF
+#include <qpopupmenu.h>
+#include <qstring.h>
+#include <qwidget.h>
+#include <qaction.h>
+
+// BOOST Includes
+#include <boost/shared_ptr.hpp>
+
+// VTK Includes
+#include <vtkRenderer.h>
+#include <vtkRenderWindow.h>
+#include <vtkActorCollection.h>
+#include <vtkScalarBarActor.h>
+#include <vtkUnstructuredGrid.h>
+
+#include "utilities.h"
+
+#include "SALOMEDS_Study.hxx"
+#include "SALOMEDSClient_StudyBuilder.hxx"
+#include "SALOMEDSClient_SComponent.hxx"
+
+using namespace std;
+
+namespace{
+  // Decalarations
+  //=============================================================
+  void ImportMeshesFromFile(SMESH::SMESH_Gen_ptr theComponentMesh,
+                           int theCommandID);
+
+  void ExportMeshToFile(int theCommandID);
+
+  void SetDisplayMode(int theCommandID);
+
+  void SetDisplayEntity(int theCommandID);
+
+  void Control( int theCommandID );
+
+
+  // Definitions
+  //=============================================================
+  void ImportMeshesFromFile(SMESH::SMESH_Gen_ptr theComponentMesh,
+                           int theCommandID)
+  {
+    QStringList filter;
+    string myExtension;
+  
+    if(theCommandID == 113){
+      filter.append(QObject::tr("MED files (*.med)"));
+      filter.append(QObject::tr("All files (*)"));
+    }else if (theCommandID == 112){
+      filter.append(QObject::tr("IDEAS files (*.unv)"));
+    }else if (theCommandID == 111){
+      filter.append(QObject::tr("DAT files (*.dat)"));
+    }
+    QString filename = SUIT_FileDlg::getFileName(SMESHGUI::desktop(),
+                                               "",
+                                               filter,
+                                               QObject::tr("Import mesh"),
+                                               true);
+    if(!filename.isEmpty()) {
+      SUIT_OverrideCursor wc;
+      _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+      theComponentMesh->SetCurrentStudy( _CAST(Study,aStudy)->GetStudy() );
+
+      try {
+       SMESH::mesh_array_var aMeshes = new SMESH::mesh_array;
+       switch ( theCommandID ) {
+       case 112:
+         {
+           aMeshes->length( 1 );
+           aMeshes[0] = theComponentMesh->CreateMeshesFromUNV(filename.latin1());
+           break;
+         }
+       case 113:
+         {
+           SMESH::DriverMED_ReadStatus res;
+           aMeshes = theComponentMesh->CreateMeshesFromMED(filename.latin1(),res);
+           if ( res != SMESH::DRS_OK ) {
+             wc.suspend();
+             SUIT_MessageBox::warn1(SMESHGUI::desktop(),
+                                   QObject::tr("SMESH_WRN_WARNING"),
+                                   QObject::tr(QString("SMESH_DRS_%1").arg(res)),
+                                   QObject::tr("SMESH_BUT_OK"));
+             aMeshes->length( 0 );
+             wc.resume();
+           }
+           break;
+         }
+       }
+
+       bool isEmpty = false;
+       for ( int i = 0, iEnd = aMeshes->length(); i < iEnd; i++ ) {
+         _PTR(SObject) aMeshSO = SMESH::FindSObject( aMeshes[i] );
+         if ( aMeshSO ) {
+           _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
+           _PTR(AttributePixMap) aPixmap = aBuilder->FindOrCreateAttribute( aMeshSO, "AttributePixMap" );
+           aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_IMPORTED");
+           if ( theCommandID == 112 ) // mesh names aren't taken from the file for UNV import
+             SMESH::SetName( aMeshSO, QFileInfo(filename).fileName() );
+         } else
+           isEmpty = true;
+       }
+
+       if ( isEmpty ) {
+         wc.suspend();
+         SUIT_MessageBox::warn1(SMESHGUI::desktop(),
+                               QObject::tr("SMESH_WRN_WARNING"),
+                               QObject::tr("SMESH_DRS_EMPTY"),
+                               QObject::tr("SMESH_BUT_OK"));
+         wc.resume();
+       }
+
+       SMESHGUI::GetSMESHGUI()->updateObjBrowser();
+      }
+      catch (const SALOME::SALOME_Exception& S_ex){
+       wc.suspend();
+       SalomeApp_Tools::QtCatchCorbaException(S_ex);
+       wc.resume();
+      }
+    }
+  }
+
+
+  void ExportMeshToFile( int theCommandID )
+  {
+    SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+    SALOME_ListIO selected;
+    if( aSel )
+      aSel->selectedObjects( selected );
+
+    if(selected.Extent()){
+      Handle(SALOME_InteractiveObject) anIObject = selected.First();
+      SMESH::SMESH_Mesh_var aMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(anIObject);
+      if ( !aMesh->_is_nil() ) {
+       QString aFilter, aTitle = QObject::tr("Export mesh");
+       QMap<QString, SMESH::MED_VERSION> aFilterMap;
+       switch ( theCommandID ) {
+       case 125:
+       case 122:
+         aFilterMap.insert( QObject::tr("MED 2.1 (*.med)"), SMESH::MED_V2_1 );
+         aFilterMap.insert( QObject::tr("MED 2.2 (*.med)"), SMESH::MED_V2_2 );
+         break;
+       case 124:
+       case 121:
+         aFilter = QObject::tr("DAT files (*.dat)");
+         break;
+       case 126:
+       case 123: {
+         if(aMesh->NbPyramids()){
+           int aRet = SUIT_MessageBox::warn2(SMESHGUI::desktop(),
+                                            QObject::tr("SMESH_WRN_WARNING"),
+                                            QObject::tr("SMESH_EXPORT_UNV").arg(anIObject->getName()),
+                                            QObject::tr("SMESH_BUT_YES"),
+                                            QObject::tr("SMESH_BUT_NO"),
+                                            0,1,0);
+           if(aRet)
+             return;
+         }
+         aFilter = QObject::tr("IDEAS files (*.unv)");
+         break;
+       default:
+         return;
+       }}
+
+       QString aFilename;
+       SMESH::MED_VERSION aFormat;
+
+       if ( theCommandID != 122 && theCommandID != 125 )
+         aFilename = SUIT_FileDlg::getFileName(SMESHGUI::desktop(), "", aFilter, aTitle, false);
+       else
+         {
+           QStringList filters;
+           for ( QMap<QString, SMESH::MED_VERSION>::const_iterator it = aFilterMap.begin(); it != aFilterMap.end(); ++it )
+             filters.push_back( it.key() );
+           
+           SUIT_FileDlg* fd = new SUIT_FileDlg( SMESHGUI::desktop(), false, true, true );
+           fd->setCaption( aTitle );
+           fd->setFilters( filters );
+           bool is_ok = false;
+           while(!is_ok){
+             fd->exec();
+             aFilename = fd->selectedFile();
+             aFormat = aFilterMap[fd->selectedFilter()];
+             is_ok = true;
+             if( !aFilename.isEmpty()
+                 && (aMesh->NbPolygons()>0 or aMesh->NbPolyhedrons()>0) 
+                 && aFormat==SMESH::MED_V2_1){
+               int aRet = SUIT_MessageBox::warn2(SMESHGUI::desktop(),
+                                                 QObject::tr("SMESH_WRN_WARNING"),
+                                                 QObject::tr("SMESH_EXPORT_MED_V2_1").arg(anIObject->getName()),
+                                                 QObject::tr("SMESH_BUT_YES"),
+                                                 QObject::tr("SMESH_BUT_NO"),
+                                                 0,1,0);
+               if(aRet){
+                 is_ok = false;
+               }
+             }
+           }
+           delete fd;
+         }
+       if ( !aFilename.isEmpty() ) {
+         // Check whether the file already exists and delete it if yes
+         QFile aFile( aFilename );
+         if ( aFile.exists() )
+           aFile.remove();
+         SUIT_OverrideCursor wc;
+         switch ( theCommandID ) {
+         case 125:
+         case 122:
+           aMesh->ExportToMED( aFilename.latin1(), false, aFormat ); // currently, automatic groups are never created
+           break;
+         case 124:
+         case 121:
+           aMesh->ExportDAT( aFilename.latin1() );
+           break;
+         case 126:
+         case 123:
+           aMesh->ExportUNV( aFilename.latin1() );
+           break;
+         default:
+           break;
+         }
+       }
+      }
+    }
+  }
+
+  inline void InverseEntityMode(unsigned int& theOutputMode,
+                               unsigned int theMode)
+  {
+    bool anIsNotPresent = ~theOutputMode & theMode;
+    if(anIsNotPresent)
+      theOutputMode |= theMode;
+    else
+      theOutputMode &= ~theMode;
+  }
+
+  void SetDisplayEntity(int theCommandID){
+    SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+    SALOME_ListIO selected;
+    if( aSel )
+      aSel->selectedObjects( selected );
+
+    if(selected.Extent() >= 1){
+      SALOME_ListIteratorOfListIO It( selected );
+      for(; It.More(); It.Next()){
+       Handle(SALOME_InteractiveObject) IObject = It.Value();
+       if(IObject->hasEntry()){
+         if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
+           unsigned int aMode = anActor->GetEntityMode();
+           switch(theCommandID){
+           case 217:
+             InverseEntityMode(aMode,SMESH_Actor::eEdges);
+             break;
+           case 218:
+             InverseEntityMode(aMode,SMESH_Actor::eFaces);
+             break;
+           case 219:
+             InverseEntityMode(aMode,SMESH_Actor::eVolumes);
+             break;
+           case 220:
+             aMode = SMESH_Actor::eAllEntity;
+             break;
+           }
+           if(aMode)
+             anActor->SetEntityMode(aMode);
+         }
+       }
+      }
+    }
+  }
+
+  void SetDisplayMode(int theCommandID){
+    SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+    SALOME_ListIO selected;
+    if( aSel )
+      aSel->selectedObjects( selected );
+
+    if(selected.Extent() >= 1){
+      switch(theCommandID){
+      case 1134:{
+       SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
+       new SMESHGUI_ClippingDlg( SMESHGUI::GetSMESHGUI(), "", false );
+       return;
+      }
+      case 1133:{
+       SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog();
+       new SMESHGUI_TransparencyDlg( SMESHGUI::GetSMESHGUI(), "", false );
+       return;
+      }}
+      SALOME_ListIteratorOfListIO It( selected );
+      for(; It.More(); It.Next()){
+       Handle(SALOME_InteractiveObject) IObject = It.Value();
+       if(IObject->hasEntry()){
+         if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){
+           switch(theCommandID){
+           case 211:
+             anActor->SetRepresentation(SMESH_Actor::eEdge);
+             break;
+           case 212:
+             anActor->SetRepresentation(SMESH_Actor::eSurface);
+             break;
+           case 213:
+             if(anActor->IsShrunk())
+               anActor->UnShrink();
+             else
+               anActor->SetShrink();
+             break;
+           case 215:
+             anActor->SetRepresentation(SMESH_Actor::ePoint);
+             break;
+           case 1132:{
+             float color[3];
+             anActor->GetSufaceColor(color[0], color[1], color[2]);
+             int c0 = int (color[0] * 255);
+             int c1 = int (color[1] * 255);
+             int c2 = int (color[2] * 255);
+             QColor c(c0, c1, c2);
+
+             float edgecolor[3];
+             anActor->GetEdgeColor(edgecolor[0], edgecolor[1], edgecolor[2]);
+             c0 = int (edgecolor[0] * 255);
+             c1 = int (edgecolor[1] * 255);
+             c2 = int (edgecolor[2] * 255);
+             QColor e(c0, c1, c2);
+
+             float backfacecolor[3];
+             anActor->GetBackSufaceColor(backfacecolor[0], backfacecolor[1], backfacecolor[2]);
+             c0 = int (backfacecolor[0] * 255);
+             c1 = int (backfacecolor[1] * 255);
+             c2 = int (backfacecolor[2] * 255);
+             QColor b(c0, c1, c2);
+
+             float nodecolor[3];
+             anActor->GetNodeColor(nodecolor[0], nodecolor[1], nodecolor[2]);
+             c0 = int (nodecolor[0] * 255);
+             c1 = int (nodecolor[1] * 255);
+             c2 = int (nodecolor[2] * 255);
+             QColor n(c0, c1, c2);
+
+             int Edgewidth = (int)anActor->GetLineWidth();
+             if(Edgewidth == 0)
+               Edgewidth = 1;
+             int intValue = int(anActor->GetNodeSize());
+             float Shrink = anActor->GetShrinkFactor();
+
+             SMESHGUI_Preferences_ColorDlg *aDlg =
+               new SMESHGUI_Preferences_ColorDlg( SMESHGUI::GetSMESHGUI(), "" );
+             aDlg->SetColor(1, c);
+             aDlg->SetColor(2, e);
+             aDlg->SetColor(3, n);
+             aDlg->SetColor(4, b);
+             aDlg->SetIntValue(1, Edgewidth);
+             aDlg->SetIntValue(2, intValue);
+             aDlg->SetIntValue(3, int(Shrink*100.));
+             if(aDlg->exec()){
+               QColor color = aDlg->GetColor(1);
+               QColor edgecolor = aDlg->GetColor(2);
+               QColor nodecolor = aDlg->GetColor(3);
+               QColor backfacecolor = aDlg->GetColor(4);
+               /* actor color and backface color */
+               anActor->SetSufaceColor(float (color.red()) / 255.,
+                                        float (color.green()) / 255.,
+                                        float (color.blue()) / 255.);
+               anActor->SetBackSufaceColor(float (backfacecolor.red()) / 255.,
+                                            float (backfacecolor.green()) / 255.,
+                                            float (backfacecolor.blue()) / 255.);
+
+               /* edge color */
+               anActor->SetEdgeColor(float (edgecolor.red()) / 255.,
+                                      float (edgecolor.green()) / 255.,
+                                      float (edgecolor.blue()) / 255.);
+
+               /* Shrink factor and size edges */
+               anActor->SetShrinkFactor(aDlg->GetIntValue(3) / 100.);
+               anActor->SetLineWidth(aDlg->GetIntValue(1));
+
+               /* Nodes color and size */
+               anActor->SetNodeColor(float (nodecolor.red()) / 255.,
+                              float (nodecolor.green()) / 255.,
+                                      float (nodecolor.blue()) / 255.);
+               anActor->SetNodeSize(aDlg->GetIntValue(2));
+
+               delete aDlg;
+             }
+             break;
+           }}
+         }
+       }
+      }
+      SMESH::RepaintCurrentView();
+    }
+  }
+  
+  void Control( int theCommandID )
+  {
+    SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+    SALOME_ListIO selected;
+    if( aSel )
+      aSel->selectedObjects( selected );
+
+    if( !selected.IsEmpty() ){
+      Handle(SALOME_InteractiveObject) anIO = selected.First();
+      if(!anIO.IsNull()){
+       QString aTitle;
+       SMESH_Actor::eControl aControl = SMESH_Actor::eNone;
+       if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIO->getEntry())){
+         switch ( theCommandID ){
+         case 6001:
+           aTitle = QObject::tr( "LENGTH_EDGES" );
+           aControl = SMESH_Actor::eLength;
+           break;
+         case 6018:
+           aTitle = QObject::tr( "LENGTH2D_EDGES" );
+           aControl = SMESH_Actor::eLength2D;
+           break;
+         case 6002:
+           aTitle = QObject::tr( "FREE_EDGES" );
+           aControl = SMESH_Actor::eFreeEdges;
+           break;
+         case 6003:
+           aTitle = QObject::tr( "FREE_BORDERS" );
+           aControl = SMESH_Actor::eFreeBorders;
+           break;
+         case 6004:
+           aTitle = QObject::tr( "MULTI_BORDERS" );
+           aControl = SMESH_Actor::eMultiConnection;
+           break;
+         case 6019:
+           aTitle = QObject::tr( "MULTI2D_BORDERS" );
+           aControl = SMESH_Actor::eMultiConnection2D;
+           break;
+         case 6011:
+           aTitle = QObject::tr( "AREA_ELEMENTS" );
+           aControl = SMESH_Actor::eArea;
+           break;
+         case 6012:
+           aTitle = QObject::tr( "TAPER_ELEMENTS" );
+           aControl = SMESH_Actor::eTaper;
+           break;
+         case 6013:
+           aTitle = QObject::tr( "ASPECTRATIO_ELEMENTS" );
+           aControl = SMESH_Actor::eAspectRatio;
+           break;
+         case 6017:
+           aTitle = QObject::tr( "ASPECTRATIO_3D_ELEMENTS" );
+           aControl = SMESH_Actor::eAspectRatio3D;
+           break;
+         case 6014:
+           aTitle = QObject::tr( "MINIMUMANGLE_ELEMENTS" );
+           aControl = SMESH_Actor::eMinimumAngle;
+           break;
+         case 6015:
+           aTitle = QObject::tr( "WARP_ELEMENTS" );
+           aControl = SMESH_Actor::eWarping;
+           break;
+         case 6016:
+           aTitle = QObject::tr( "SKEW_ELEMENTS" );
+           aControl = SMESH_Actor::eSkew;
+           break;
+         }
+         anActor->SetControlMode(aControl);
+         anActor->GetScalarBarActor()->SetTitle(aTitle.latin1());
+         SMESH::RepaintCurrentView();
+       }
+      }
+    }
+  }
+
+
+  bool CheckOIType(const Handle(SALOME_InteractiveObject) & theIO,
+                  MeshObjectType                           theType,
+                  const QString                            theInTypeName,
+                  QString &                                theOutTypeName)
+  {
+    SMESH_TypeFilter aTypeFilter( theType );
+    QString entry;
+    if( !theIO.IsNull() )
+    {
+      entry = theIO->getEntry();
+      SalomeApp_DataOwner owner( entry );
+      if ( aTypeFilter.isOk( &owner )) {
+        theOutTypeName = theInTypeName;
+        return true;
+      }
+    }
+    return false;
+  }
+
+
+  QString CheckTypeObject(const Handle(SALOME_InteractiveObject) & theIO)
+  {
+    _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+    _PTR(SObject) aSObj = aStudy->FindObjectID(theIO->getEntry());
+    if (aSObj) {
+      _PTR(SComponent) aSComp = aSObj->GetFatherComponent();
+      CORBA::String_var anID = aSComp->GetID().c_str();
+      if (!strcmp(anID.in(),theIO->getEntry()))
+       return "Component";
+    }
+
+    QString aTypeName;
+    if (
+       CheckOIType ( theIO, HYPOTHESIS,    "Hypothesis", aTypeName ) ||
+       CheckOIType ( theIO, ALGORITHM,     "Algorithm",  aTypeName ) ||
+       CheckOIType ( theIO, MESH,          "Mesh",       aTypeName ) ||
+       CheckOIType ( theIO, SUBMESH,       "SubMesh",    aTypeName ) ||
+       CheckOIType ( theIO, GROUP,         "Group",      aTypeName )
+       )
+      return aTypeName;
+
+    return "NoType";
+  }
+
+
+  QString CheckHomogeneousSelection()
+  {
+    //SUIT_Study* aStudy = SMESH::GetActiveStudy();
+    SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+    SALOME_ListIO selected;
+    if( aSel )
+      aSel->selectedObjects( selected );
+
+    QString RefType = CheckTypeObject(selected.First());
+    SALOME_ListIteratorOfListIO It(selected);
+    for (; It.More(); It.Next())
+      {
+       Handle(SALOME_InteractiveObject) IObject = It.Value();
+       QString Type = CheckTypeObject(IObject);
+       if (Type.compare(RefType) != 0)
+         return "Heterogeneous Selection";
+      }
+
+    return RefType;
+  }
+
+
+  void SMESHGUI::OnEditDelete()
+  {
+    // VSR 17/11/04: check if all objects selected belong to SMESH component --> start
+    SalomeApp_SelectionMgr* aSel = SMESHGUI::selectionMgr();
+    SALOME_ListIO selected; aSel->selectedObjects( selected );
+
+    QString aParentComponent = QString::null;
+    for( SALOME_ListIteratorOfListIO anIt( selected ); anIt.More(); anIt.Next() )
+    {
+      QString cur = anIt.Value()->getComponentDataType();
+      if( aParentComponent.isNull() )
+        aParentComponent = cur;
+      else if( !aParentComponent.isEmpty() && aParentComponent!=cur )
+        aParentComponent = "";
+    }
+
+    if ( aParentComponent != SMESHGUI::GetSMESHGUI()->name() )  {
+      SUIT_MessageBox::warn1 ( SMESHGUI::desktop(),
+                             QObject::tr("ERR_ERROR"),
+                             QObject::tr("NON_SMESH_OBJECTS_SELECTED").arg( SMESHGUI::GetSMESHGUI()->moduleName() ),
+                             QObject::tr("BUT_OK") );
+      return;
+    }
+    // VSR 17/11/04: check if all objects selected belong to SMESH component <-- finish
+    if (SUIT_MessageBox::warn2
+       (SMESHGUI::desktop(),
+        QObject::tr("SMESH_WRN_WARNING"),
+        QObject::tr("SMESH_REALLY_DELETE"),
+        QObject::tr("SMESH_BUT_YES"), QObject::tr("SMESH_BUT_NO"), 1, 0, 0) != 1)
+      return;
+
+    SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
+    SUIT_ViewManager* vm = anApp->activeViewManager();
+    int nbSf = vm->getViewsCount();
+
+    _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+    _PTR(StudyBuilder) aStudyBuilder = aStudy->NewBuilder();
+    _PTR(GenericAttribute) anAttr;
+    _PTR(AttributeIOR) anIOR;
+
+    SALOME_ListIteratorOfListIO It(selected);
+
+    aStudyBuilder->NewCommand();  // There is a transaction
+    for(; It.More(); It.Next()){
+      Handle(SALOME_InteractiveObject) IObject = It.Value();
+      if(IObject->hasEntry()){
+       _PTR(SObject) SO = aStudy->FindObjectID(IObject->getEntry());
+
+       // disable removal of "SMESH" component object
+       if(SO->FindAttribute(anAttr, "AttributeIOR")){
+         anIOR = anAttr;
+         if ( !strcmp( (char*)anIOR->Value().c_str(), engineIOR().latin1() ) )
+           continue;
+       }
+
+       /* Erase child graphical objects */
+       _PTR(ChildIterator) it = aStudy->NewChildIterator(SO);
+       for(it->InitEx(true); it->More(); it->Next()){
+         _PTR(SObject) CSO = it->Value();
+         if(CSO->FindAttribute(anAttr, "AttributeIOR")){
+           anIOR = anAttr;
+
+           QPtrVector<SUIT_ViewWindow> aViews = vm->getViews();
+           for(int i = 0; i < nbSf; i++){
+             SUIT_ViewWindow *sf = aViews[i];
+             CORBA::String_var anEntry = CSO->GetID().c_str();
+             if(SMESH_Actor* anActor = SMESH::FindActorByEntry(sf,anEntry.in())){
+               SMESH::RemoveActor(sf,anActor);
+             }
+           }
+         }
+       }
+
+       /* Erase main graphical object */
+       QPtrVector<SUIT_ViewWindow> aViews = vm->getViews();
+       for(int i = 0; i < nbSf; i++){
+         SUIT_ViewWindow *sf = aViews[i];
+         if(SMESH_Actor* anActor = SMESH::FindActorByEntry(sf,IObject->getEntry())){
+           SMESH::RemoveActor(sf,anActor);
+         }
+       }
+
+       // Remove object(s) from data structures
+       _PTR(SObject) obj = aStudy->FindObjectID(IObject->getEntry());
+       if(obj){
+         SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( SMESH::SObjectToObject( obj ) );
+         SMESH::SMESH_subMesh_var   aSubMesh = SMESH::SMESH_subMesh::_narrow( SMESH::SObjectToObject( obj ) );
+          QString objType = CheckTypeObject(IObject);
+         if ( !aGroup->_is_nil() ) {                          // DELETE GROUP
+           SMESH::SMESH_Mesh_var aMesh = aGroup->GetMesh();
+           aMesh->RemoveGroup( aGroup );
+         }
+         else if ( !aSubMesh->_is_nil() ) {                   // DELETE SUBMESH
+           SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
+           aMesh->RemoveSubMesh( aSubMesh );
+         }
+         else if ( objType == "Hypothesis" || objType == "Algorithm" ) {// DELETE HYPOTHESIS
+            SMESH::RemoveHypothesisOrAlgorithmOnMesh(IObject);
+           aStudyBuilder->RemoveObjectWithChildren( obj );
+         }
+         else {// default action: remove SObject from the study
+           // san - it's no use opening a transaction here until UNDO/REDO is provided in SMESH
+           //SUIT_Operation *op = new SALOMEGUI_ImportOperation(myActiveStudy);
+           //op->start();
+           aStudyBuilder->RemoveObjectWithChildren( obj );
+           //op->finish();
+         }
+       }
+
+      } /* IObject->hasEntry() */
+    } /* more/next */
+    aStudyBuilder->CommitCommand();
+
+    /* Clear any previous selection */
+    SALOME_ListIO l1;
+    aSel->setSelectedObjects( l1 );
+
+    SMESHGUI::GetSMESHGUI()->updateObjBrowser();
+  }
+}
+
+extern "C" {
+  Standard_EXPORT CAM_Module* createModule()
+  {
+    return new SMESHGUI();
+  }
+}
+
+SMESH::SMESH_Gen_var SMESHGUI::myComponentSMESH = SMESH::SMESH_Gen::_nil();
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+SMESHGUI::SMESHGUI() :
+SalomeApp_Module( "SMESH" )
+{
+  if ( CORBA::is_nil( myComponentSMESH ) )
+  {
+    SALOME_LifeCycleCORBA* ls = new SALOME_LifeCycleCORBA( getApp()->namingService() );
+    Engines::Component_var comp = ls->FindOrLoad_Component( "FactoryServer", "SMESH" );
+    myComponentSMESH = SMESH::SMESH_Gen::_narrow( comp );
+  }
+
+  myActiveDialogBox = 0 ;
+  myState = -1 ;
+
+  SMESH::GetFilterManager();
+  SMESH::GetPattern();
+  
+  /* load resources for all available meshers */
+  SMESH::InitAvailableHypotheses();
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+SMESHGUI::~SMESHGUI()
+{
+  SMESH::GetFilterManager()->Destroy();
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+SalomeApp_SelectionMgr* SMESHGUI::selectionMgr()
+{
+  SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
+  if( anApp )
+    return dynamic_cast<SalomeApp_SelectionMgr*>( anApp->selectionMgr() );
+  else
+    return 0;
+}
+
+bool SMESHGUI::automaticUpdate()
+{
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+  if ( !resMgr )
+    return false;
+
+  return resMgr->booleanValue( "SMESH", "auto_update", false );
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+SUIT_ResourceMgr* SMESHGUI::resourceMgr()
+{
+  return dynamic_cast<SUIT_ResourceMgr*>( SUIT_Session::session()->resourceMgr() );
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+SMESHGUI* SMESHGUI::GetSMESHGUI()
+{
+  SMESHGUI* smeshMod = 0;
+  SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>(SUIT_Session::session()->activeApplication());
+  if ( app )
+  {
+    CAM_Module* module = app->module( "Mesh" );
+    smeshMod = dynamic_cast<SMESHGUI*>( module );
+  }
+
+  if ( smeshMod && smeshMod->application() && smeshMod->application()->activeStudy() )
+  {
+    SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( smeshMod->application()->activeStudy() );
+    if ( study )
+    {
+      _PTR(Study) aStudy = study->studyDS();
+      if ( aStudy )
+       GetSMESHGen()->SetCurrentStudy( _CAST(Study,aStudy)->GetStudy() );
+    }
+  }
+
+  return smeshMod;
+}
+
+extern "C"
+{
+  Standard_EXPORT SMESHGUI* GetComponentGUI()
+  {
+    return SMESHGUI::GetSMESHGUI();
+  }
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+void SMESHGUI::SetState(int aState)
+{
+  myState = aState;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+void SMESHGUI::ResetState()
+{
+  myState = -1;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+void SMESHGUI::EmitSignalDeactivateDialog()
+{
+  emit SignalDeactivateActiveDialog();
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+void SMESHGUI::EmitSignalStudyFrameChanged()
+{
+  emit SignalStudyFrameChanged();
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+void SMESHGUI::EmitSignalCloseAllDialogs()
+{
+  emit SignalCloseAllDialogs();
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+QDialog *SMESHGUI::GetActiveDialogBox()
+{
+  return myActiveDialogBox;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+void SMESHGUI::SetActiveDialogBox(QDialog * aDlg)
+{
+  myActiveDialogBox = (QDialog *) aDlg;
+  return;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+SUIT_Desktop* SMESHGUI::desktop()
+{
+  SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
+  if( app )
+    return app->desktop();
+  else
+    return 0;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+SalomeApp_Study* SMESHGUI::activeStudy()
+{
+  SUIT_Application* app = SUIT_Session::session()->activeApplication();
+  if( app )
+    return dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
+  else
+    return NULL;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+bool SMESHGUI::DefineDlgPosition(QWidget * aDlg, int &x, int &y)
+{
+  /* Here the position is on the bottom right corner - 10 */
+  // aDlg->resize(QSize().expandedTo(aDlg->minimumSizeHint()));
+  aDlg->adjustSize();
+  SUIT_Desktop *PP = desktop();
+  x = abs(PP->x() + PP->size().width() - aDlg->size().width() - 10);
+  y = abs(PP->y() + PP->size().height() - aDlg->size().height() - 10);
+  return true;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+static int isStudyLocked(_PTR(Study) theStudy){
+  return theStudy->GetProperties()->IsLocked();
+}
+
+static bool checkLock(_PTR(Study) theStudy) {
+  if (isStudyLocked(theStudy)) {
+    SUIT_MessageBox::warn1 ( SMESHGUI::desktop(),
+                          QObject::tr("WRN_WARNING"),
+                          QObject::tr("WRN_STUDY_LOCKED"),
+                          QObject::tr("BUT_OK") );
+    return true;
+  }
+  return false;
+}
+
+//=======================================================================
+//function : CheckActiveStudyLocked
+//purpose  :
+//=======================================================================
+
+bool SMESHGUI::isActiveStudyLocked()
+{
+  _PTR(Study) aStudy = activeStudy()->studyDS();
+  return checkLock( aStudy );
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+bool SMESHGUI::OnGUIEvent( int theCommandID )
+{
+  SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( application() );
+  if( !anApp )
+    return false;
+
+  _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); //Document OCAF de l'etude active
+  SUIT_ResourceMgr* mgr = resourceMgr();
+  if( !mgr )
+    return false;
+
+  SUIT_ViewWindow* view = application()->desktop()->activeWindow();
+  SVTK_ViewWindow* vtkwnd = dynamic_cast<SVTK_ViewWindow*>( view );
+
+  //QAction* act = action( theCommandID );
+
+  switch (theCommandID)        {
+  case 33:                                     // DELETE
+    if(checkLock(aStudy)) break;
+    OnEditDelete();
+    break;
+
+  case 113:                                    // IMPORT
+  case 112:
+  case 111:
+    {
+      if(checkLock(aStudy)) break;
+      ::ImportMeshesFromFile(GetSMESHGen(),theCommandID);
+      break;
+    }
+
+  case 122:                                    // EXPORT MED
+  case 121:
+  case 123:
+  case 124:
+  case 125:
+  case 126:
+    {
+      ::ExportMeshToFile(theCommandID);
+      break;
+    }
+
+  case 200:                                    // SCALAR BAR
+    {
+      SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+      SALOME_ListIO selected;
+      if( aSel )
+        aSel->selectedObjects( selected );
+
+      if( selected.Extent() ) {
+       Handle(SALOME_InteractiveObject) anIO = selected.First();
+       if( anIO->hasEntry() ) {
+         if( SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() ) ) {
+           anActor->SetControlMode( SMESH_Actor::eNone );
+         }
+       }
+      }
+      break;
+    }
+  case 201:
+    {
+      SMESHGUI_Preferences_ScalarBarDlg::ScalarBarProperties( this );
+      break;
+    }
+
+  case 1134: // Clipping
+  case 1133: // Tranparency
+  case 1132: // Colors / Size
+
+    // Display Mode
+  case 215: // Nodes
+  case 213: // Nodes
+  case 212: // Nodes
+  case 211: // Nodes
+    ::SetDisplayMode(theCommandID);
+  break;
+
+    // Display Entity
+  case 217: // Edges
+  case 218: // Faces
+  case 219: // Volumes
+  case 220: // All Entity
+    ::SetDisplayEntity(theCommandID);
+  break;
+
+  case 214:                                    // UPDATE
+    {
+      if(checkLock(aStudy)) break;
+      SMESH::UpdateView();
+
+      SALOME_ListIO l;
+      SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+      aSel->setSelectedObjects( l );
+      break;
+    }
+
+  case 300:                                    // ERASE
+  case 301:                                    // DISPLAY
+  case 302:                                    // DISPLAY ONLY
+    {
+      SMESH::EDisplaing anAction;
+      switch (theCommandID) {
+      case 300:        anAction = SMESH::eErase; break;
+      case 301:        anAction = SMESH::eDisplay; break;
+      case 302:        anAction = SMESH::eDisplayOnly; break;
+      }
+
+      SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+      SALOME_ListIO selected;
+      if (aSel)
+        aSel->selectedObjects( selected );
+
+      if (vtkwnd) {
+       SALOME_ListIteratorOfListIO It (selected);
+       for (; It.More(); It.Next()) {
+         Handle(SALOME_InteractiveObject) IOS = It.Value();
+         if (IOS->hasEntry()) {
+            SMESH::UpdateView(anAction, IOS->getEntry());
+            if (anAction == SMESH::eDisplayOnly)
+              anAction = SMESH::eDisplay;
+         }
+       }
+      }
+      
+      if (anAction == SMESH::eErase) {
+       SALOME_ListIO l1;
+       aSel->setSelectedObjects( l1 );
+      }
+      else
+       aSel->setSelectedObjects( selected );
+      break;
+    }
+
+  case 400:                                    // NODES
+    {
+      if(checkLock(aStudy)) break;
+
+      if ( vtkwnd ) {
+       EmitSignalDeactivateDialog();
+
+       new SMESHGUI_NodesDlg(this);
+      }
+      else {
+       SUIT_MessageBox::warn1(desktop(),
+                             tr("SMESH_WRN_WARNING"), 
+                             tr("SMESH_WRN_VIEWER_VTK"),
+                             tr("SMESH_BUT_OK"));
+      }
+      break;
+    }
+
+  case 2151:  // FILTER
+  {
+    if ( vtkwnd )
+    {
+      EmitSignalDeactivateDialog();
+      new SMESHGUI_FilterDlg( this, SMESH::EDGE );
+    }
+    break;
+  }
+
+  case 406:                                    // MOVE NODE
+    {
+      if ( !vtkwnd )
+      {
+        SUIT_MessageBox::warn1( desktop(), tr( "SMESH_WRN_WARNING" ),
+          tr( "NOT_A_VTK_VIEWER" ),tr( "SMESH_BUT_OK" ) );
+        break;
+      }
+
+      if(checkLock(aStudy)) break;
+      new SMESHGUI_MoveNodesDlg(this);
+      break;
+    }
+
+  case 701:                                    // COMPUTE MESH
+    {
+      if(checkLock(aStudy)) break;
+      if ( vtkwnd ) {
+       SalomeApp_SelectionMgr *Sel = selectionMgr();
+       SALOME_ListIO selected; Sel->selectedObjects( selected );
+
+       int nbSel = selected.Extent();
+       if (nbSel != 1){
+         break;
+       }
+
+       SMESH::SMESH_Mesh_var aMesh;
+       SMESH::SMESH_subMesh_var aSubMesh;
+       Handle(SALOME_InteractiveObject) IObject = selected.First();
+       if (IObject->hasEntry()){
+         _PTR(SObject) aMeshSObj = aStudy->FindObjectID(IObject->getEntry());
+         GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh( aMeshSObj );
+         if ( aShapeObject->_is_nil() ) {
+           // imported mesh
+           break;
+         }
+         if( aMeshSObj ) {
+           SMESH::SMESH_Mesh_var aMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>(aMeshSObj);
+           SMESH::SMESH_subMesh_var aSubMesh = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>(aMeshSObj);
+
+           if (!aMesh->_is_nil()){
+             GEOM::GEOM_Object_var refShapeObject = SMESH::GetShapeOnMeshOrSubMesh(aMeshSObj);
+             if (!refShapeObject->_is_nil()) {
+               if(!GetSMESHGen()->IsReadyToCompute(aMesh,refShapeObject)){
+                 SUIT_MessageBox::warn1(desktop(),
+                                       tr("SMESH_WRN_WARNING"),
+                                       tr("SMESH_WRN_MISSING_PARAMETERS"),
+                                       tr("SMESH_BUT_OK"));
+                 break;
+               }
+               try{
+                 if (GetSMESHGen()->Compute(aMesh,refShapeObject))
+                    SMESH::ModifiedMesh(aMeshSObj,true);
+                 // TO Do : change icon of all submeshes
+                  else
+                    SUIT_MessageBox::warn1(desktop(), 
+                                          tr("SMESH_WRN_WARNING"),
+                                          tr("SMESH_WRN_COMPUTE_FAILED"),
+                                          tr("SMESH_BUT_OK"));
+               }
+               catch(const SALOME::SALOME_Exception & S_ex){
+                 SalomeApp_Tools::QtCatchCorbaException(S_ex);
+               }
+             }
+           }else if(!aSubMesh->_is_nil()){
+             aMesh = aSubMesh->GetFather();
+             GEOM::GEOM_Object_var refShapeObject = SMESH::GetShapeOnMeshOrSubMesh(aMeshSObj);
+             if(!refShapeObject->_is_nil()){
+               bool compute = GetSMESHGen()->IsReadyToCompute(aMesh,refShapeObject);
+               if(!compute){
+                 SUIT_MessageBox::warn1(desktop(), 
+                                       tr("SMESH_WRN_WARNING"),
+                                       tr("SMESH_WRN_MISSING_PARAMETERS"),
+                                       tr("SMESH_BUT_OK"));
+                 break;
+               }
+               try{
+                 if ( GetSMESHGen()->Compute(aMesh,refShapeObject) )
+                    SMESH::ModifiedMesh(aMeshSObj,true);
+                 // TO Do : change icon of all submeshes
+                  else
+                    SUIT_MessageBox::warn1(desktop(),
+                                          tr("SMESH_WRN_WARNING"),
+                                          tr("SMESH_WRN_COMPUTE_FAILED"),
+                                          tr("SMESH_BUT_OK"));
+               }catch(const SALOME::SALOME_Exception & S_ex){
+                 SalomeApp_Tools::QtCatchCorbaException(S_ex);
+               }
+             }
+           }
+         }
+       }
+       CORBA::Long anId = aStudy->StudyId();
+       TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,IObject->getEntry());
+       if ( automaticUpdate() && aVisualObj){
+         aVisualObj->Update();
+         SMESH_Actor* anActor = SMESH::FindActorByEntry(IObject->getEntry());
+         if(!anActor){
+           anActor = SMESH::CreateActor(aStudy,IObject->getEntry());
+           if(anActor){
+             SMESH::DisplayActor(view,anActor); //apo
+             SMESH::FitAll();
+           }
+         }
+         SMESH::RepaintCurrentView();
+       }
+      }else{
+       SUIT_MessageBox::warn1(desktop(),
+                             tr("SMESH_WRN_WARNING"), 
+                             tr("SMESH_WRN_VIEWER_VTK"),
+                             tr("SMESH_BUT_OK"));
+      }
+      updateObjBrowser();
+      break;
+    }
+
+  case 702:  // Create mesh
+    startOperation( 702 );
+    break;
+  case 703:  // Create sub-mesh
+    startOperation( 703 );
+    break;
+  case 704: // Edit mesh/sub-mesh
+    startOperation( 704 );
+    break;
+  case 407: // DIAGONAL INVERSION
+  case 408: // Delete diagonal
+    {
+      if ( !vtkwnd )
+      {
+        SUIT_MessageBox::warn1( desktop(), tr( "SMESH_WRN_WARNING" ),
+          tr( "NOT_A_VTK_VIEWER" ),tr( "SMESH_BUT_OK" ) );
+        break;
+      }
+
+      if ( checkLock( aStudy ) )
+        break;
+
+      /*Standard_Boolean aRes;
+      SMESH::SMESH_Mesh_var aMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IObject);
+      if ( aMesh->_is_nil() )
+      {
+        SUIT_MessageBox::warn1(GetDesktop(), tr( "SMESH_WRN_WARNING" ),
+          tr( "SMESH_BAD_SELECTION" ), tr( "SMESH_BUT_OK" ) );
+        break;
+      }
+      */
+      EmitSignalDeactivateDialog();
+      if ( theCommandID == 407 )
+        new SMESHGUI_TrianglesInversionDlg(this);
+      else
+        new SMESHGUI_UnionOfTwoTrianglesDlg(this);
+      break;
+    }
+    case 409: // Change orientation
+    case 410: // Union of triangles
+    case 411: // Cutting of quadrangles
+    {
+      if ( !vtkwnd )
+      {
+        SUIT_MessageBox::warn1( desktop(), tr( "SMESH_WRN_WARNING" ),
+          tr( "NOT_A_VTK_VIEWER" ),tr( "SMESH_BUT_OK" ) );
+        break;
+      }
+
+      if ( checkLock( aStudy ) )
+        break;
+
+      EmitSignalDeactivateDialog();
+      SMESHGUI_MultiEditDlg* aDlg = NULL;
+      if ( theCommandID == 409 )
+        aDlg = new SMESHGUI_ChangeOrientationDlg(this);
+      else if ( theCommandID == 410 )
+        aDlg = new SMESHGUI_UnionOfTrianglesDlg(this);
+      else
+        aDlg = new SMESHGUI_CuttingOfQuadsDlg(this);
+
+      int x, y ;
+      DefineDlgPosition( aDlg, x, y );
+      aDlg->move( x, y );
+      aDlg->show();
+      break;
+    }
+  case 412: // Smoothing
+    {
+      if(checkLock(aStudy)) break;
+      if( vtkwnd ) {
+       EmitSignalDeactivateDialog();
+       new SMESHGUI_SmoothingDlg( this );
+      }
+      else {
+       SUIT_MessageBox::warn1(desktop(),
+                             tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+                             tr("SMESH_BUT_OK"));
+      }
+      break;
+    }
+  case 413: // Extrusion
+    {
+      if (checkLock(aStudy)) break;
+      if (vtkwnd) {
+       EmitSignalDeactivateDialog();
+       new SMESHGUI_ExtrusionDlg ( this );
+      } else {
+       SUIT_MessageBox::warn1(desktop(),
+                               tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+                               tr("SMESH_BUT_OK"));
+      }
+      break;
+    }
+  case 414: // Revolution
+    {
+      if(checkLock(aStudy)) break;
+      if( vtkwnd ) {
+       EmitSignalDeactivateDialog();
+       new SMESHGUI_RevolutionDlg( this );
+      }
+      else {
+       SUIT_MessageBox::warn1(desktop(),
+                             tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+                             tr("SMESH_BUT_OK"));
+      }
+      break;
+    }
+  case 415: // Pattern mapping
+    {
+      if ( checkLock( aStudy ) )
+        break;
+      if ( vtkwnd )
+      {
+        EmitSignalDeactivateDialog();
+        new SMESHGUI_MeshPatternDlg( this );
+      }
+      else {
+       SUIT_MessageBox::warn1(desktop(),
+                             tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+                             tr("SMESH_BUT_OK"));
+      }
+      break;
+    }
+  case 416: // Extrusion along a path
+    {
+      if (checkLock(aStudy)) break;
+      if (vtkwnd) {
+       EmitSignalDeactivateDialog();
+       new SMESHGUI_ExtrusionAlongPathDlg( this );
+      } else {
+       SUIT_MessageBox::warn1(desktop(),
+                               tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+                               tr("SMESH_BUT_OK"));
+      }
+      break;
+    }
+  case 801:                                     // CREATE GROUP
+    {
+      if ( !vtkwnd )
+      {
+        SUIT_MessageBox::warn1( desktop(), tr( "SMESH_WRN_WARNING" ),
+          tr( "NOT_A_VTK_VIEWER" ),tr( "SMESH_BUT_OK" ) );
+        break;
+      }
+
+      if(checkLock(aStudy)) break;
+      EmitSignalDeactivateDialog();
+      SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_nil();
+
+      SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+      SALOME_ListIO selected;
+      if( aSel )
+        aSel->selectedObjects( selected );
+
+      int nbSel = selected.Extent();
+      if (nbSel == 1) {
+       // check if mesh is selected
+        aMesh = SMESH::GetMeshByIO( selected.First() );
+      }
+      SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, "", aMesh);
+      aDlg->show();
+      break;
+    }
+
+  case 802:                                     // CONSTRUCT GROUP
+    {
+      if ( !vtkwnd )
+      {
+        SUIT_MessageBox::warn1( desktop(), tr( "SMESH_WRN_WARNING" ),
+          tr( "NOT_A_VTK_VIEWER" ),tr( "SMESH_BUT_OK" ) );
+        break;
+      }
+
+      if(checkLock(aStudy)) break;
+      EmitSignalDeactivateDialog();
+
+      SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+      SALOME_ListIO selected;
+      if( aSel )
+        aSel->selectedObjects( selected );
+
+      int nbSel = selected.Extent();
+      if (nbSel == 1) {
+       // check if submesh is selected
+       Handle(SALOME_InteractiveObject) IObject = selected.First();
+       if (IObject->hasEntry()) {
+         _PTR(SObject) aSObj = aStudy->FindObjectID(IObject->getEntry());
+         if( aSObj ) {
+           SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( SMESH::SObjectToObject( aSObj ) );
+           if (!aSubMesh->_is_nil()) {
+             try {
+               SMESH::SMESH_Mesh_var aMesh = aSubMesh->GetFather();
+               // get submesh elements list by types
+               SMESH::long_array_var aNodes = aSubMesh->GetElementsByType(SMESH::NODE);
+               SMESH::long_array_var aEdges = aSubMesh->GetElementsByType(SMESH::EDGE);
+               SMESH::long_array_var aFaces = aSubMesh->GetElementsByType(SMESH::FACE);
+               SMESH::long_array_var aVolumes = aSubMesh->GetElementsByType(SMESH::VOLUME);
+               // create group for each type o elements
+               QString aName = IObject->getName();
+               if (aNodes->length() > 0) {
+                 SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::NODE, aName + "_Nodes");
+                 aGroup->Add(aNodes.inout());
+               }
+               if (aEdges->length() > 0) {
+                 SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::EDGE, aName + "_Edges");
+                 aGroup->Add(aEdges.inout());
+               }
+               if (aFaces->length() > 0) {
+                 SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::FACE, aName + "_Faces");
+                 aGroup->Add(aFaces.inout());
+               }
+               if (aVolumes->length() > 0) {
+                 SMESH::SMESH_Group_var aGroup = SMESH::AddGroup(aMesh, SMESH::VOLUME, aName + "_Volumes");
+                 aGroup->Add(aVolumes.inout());
+               }
+               updateObjBrowser();
+               
+             }catch(const SALOME::SALOME_Exception & S_ex){
+               SalomeApp_Tools::QtCatchCorbaException(S_ex);
+             }
+           }
+         }
+       }
+      }
+      break;
+    }
+
+  case 803:                                     // EDIT GROUP
+    {
+      if ( !vtkwnd )
+      {
+        SUIT_MessageBox::warn1( desktop(), tr( "SMESH_WRN_WARNING" ),
+          tr( "NOT_A_VTK_VIEWER" ),tr( "SMESH_BUT_OK" ) );
+        break;
+      }
+
+      if(checkLock(aStudy)) break;
+      EmitSignalDeactivateDialog();
+
+      SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+      SALOME_ListIO selected;
+      if( aSel )
+        aSel->selectedObjects( selected );
+
+      SALOME_ListIteratorOfListIO It (selected);
+      int nbSelectedGroups = 0;
+      for ( ; It.More(); It.Next() )
+      {
+        SMESH::SMESH_Group_var aGroup =
+          SMESH::IObjectToInterface<SMESH::SMESH_Group>(It.Value());
+        if (!aGroup->_is_nil()) {
+         nbSelectedGroups++;
+          SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, "", aGroup);
+          aDlg->show();
+       }
+      }
+      if (nbSelectedGroups == 0)
+       {
+         SMESHGUI_GroupDlg *aDlg = new SMESHGUI_GroupDlg( this, "", SMESH::SMESH_Group::_nil());
+         aDlg->show();
+       }
+      break;
+    }
+
+  case 804:                                     // Add elements to group
+    {
+      if(checkLock(aStudy)) break;
+      if (myState == 800) {
+       SMESHGUI_GroupDlg *aDlg = (SMESHGUI_GroupDlg*) myActiveDialogBox;
+       if (aDlg) aDlg->onAdd();
+      }
+      break;
+    }
+
+  case 805:                                     // Remove elements from group
+    {
+      if(checkLock(aStudy)) break;
+      if (myState == 800) {
+       SMESHGUI_GroupDlg *aDlg = (SMESHGUI_GroupDlg*) myActiveDialogBox;
+       if (aDlg) aDlg->onRemove();
+      }
+      break;
+    }
+
+    case 810: // Union Groups
+    case 811: // Intersect groups
+    case 812: // Cut groups
+    {
+      if ( !vtkwnd )
+      {
+        SUIT_MessageBox::warn1( desktop(), tr( "SMESH_WRN_WARNING" ),
+          tr( "NOT_A_VTK_VIEWER" ),tr( "SMESH_BUT_OK" ) );
+        break;
+      }
+
+      if ( checkLock( aStudy ) )
+        break;
+
+      EmitSignalDeactivateDialog();
+
+      int aMode;
+      if      ( theCommandID == 810 ) aMode = SMESHGUI_GroupOpDlg::UNION;
+      else if ( theCommandID == 811 ) aMode = SMESHGUI_GroupOpDlg::INTERSECT;
+      else                            aMode = SMESHGUI_GroupOpDlg::CUT;
+
+      ( new SMESHGUI_GroupOpDlg( this, aMode ) )->show();
+      break;
+    }
+
+    case 813: // Delete groups with their contents
+    {
+      if ( !vtkwnd )
+      {
+        SUIT_MessageBox::warn1( desktop(), tr( "SMESH_WRN_WARNING" ),
+          tr( "NOT_A_VTK_VIEWER" ),tr( "SMESH_BUT_OK" ) );
+        break;
+      }
+
+      if ( checkLock( aStudy ) )
+        break;
+
+      EmitSignalDeactivateDialog();
+
+      new SMESHGUI_DeleteGroupDlg( this );
+      break;
+    }
+
+  case 900:                                    // MESH INFOS
+    {
+      EmitSignalDeactivateDialog();
+      SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+      SALOME_ListIO selected;
+      if( aSel )
+        aSel->selectedObjects( selected );
+
+      if ( selected.Extent() > 1 ) { // a dlg for each IO
+        SALOME_ListIO IOs;
+        SALOME_ListIteratorOfListIO It (selected);
+        for ( ; It.More(); It.Next() ) {
+         IOs.Clear(); IOs.Append( It.Value() );
+         aSel->setSelectedObjects( IOs );
+          new SMESHGUI_MeshInfosDlg(this, "", false);
+        }
+        // restore selection
+        aSel->setSelectedObjects( selected );
+      }
+      else
+        new SMESHGUI_MeshInfosDlg(this, "", false);
+      break;
+    }
+
+  case 902:                                    // STANDARD MESH INFOS
+    {
+      EmitSignalDeactivateDialog();
+      SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+      SALOME_ListIO selected;
+      if( aSel )
+        aSel->selectedObjects( selected );
+
+      if ( selected.Extent() > 1 ) { // a dlg for each IO
+        SALOME_ListIO IOs;
+        SALOME_ListIteratorOfListIO It (selected);
+        for ( ; It.More(); It.Next() ) {
+         IOs.Clear();
+         IOs.Append( It.Value() );
+         aSel->setSelectedObjects( IOs );
+          new SMESHGUI_StandardMeshInfosDlg( this, "", false);
+        }
+        // restore selection
+       aSel->setSelectedObjects( selected );
+      }
+      else
+        new SMESHGUI_StandardMeshInfosDlg( this, "", false);
+      break;
+    } 
+    
+  case 1100:                                   // EDIT HYPOTHESIS
+    {
+      if(checkLock(aStudy)) break;
+
+      SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+      SALOME_ListIO selected;
+      if( aSel )
+        aSel->selectedObjects( selected );
+
+      int nbSel = selected.Extent();
+
+      if (nbSel == 1) {
+       SMESH::SMESH_Hypothesis_var Hyp = SMESH::IObjectToInterface<SMESH::SMESH_Hypothesis>(selected.First());
+
+        /* Look for all mesh objects that have this hypothesis affected in order to flag as ModifiedMesh */
+        /* At end below '...->updateObjBrowser(true)' will change icon of mesh objects                   */
+        /* Warning : however by internal mechanism all subMeshes icons are changed !                     */
+        if ( !Hyp->_is_nil() )
+        {
+          char* sName = Hyp->GetName();
+          SMESHGUI_GenericHypothesisCreator* aCreator = SMESH::GetHypothesisCreator(sName);
+          if (aCreator)
+          {
+            aCreator->EditHypothesis(Hyp);
+          }
+          else
+          {
+            // report error
+          }
+        }
+      }
+      updateObjBrowser( true );
+      break;
+    }
+
+  case 1101:                                   // RENAME
+    {
+      if ( checkLock( aStudy ) )
+        break;
+
+      SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+      SALOME_ListIO selected;
+      if( aSel )
+        aSel->selectedObjects( selected );
+
+      SALOME_ListIteratorOfListIO It( selected );
+      for ( ; It.More(); It.Next() )
+      {
+        Handle(SALOME_InteractiveObject) IObject = It.Value();
+        _PTR(SObject) obj = aStudy->FindObjectID( IObject->getEntry() );
+        _PTR(GenericAttribute) anAttr;
+        _PTR(AttributeName) aName;
+        if ( obj )
+        {
+          if ( obj->FindAttribute(anAttr, "AttributeName") )
+          {
+            aName = anAttr;
+            QString newName = QString(aName->Value().c_str());
+            newName = SalomeApp_NameDlg::getName( desktop(), newName );
+            if ( !newName.isEmpty() )
+            {
+              //old source: aStudy->renameIObject( IObject, newName );
+             aName->SetValue( newName.latin1() );
+
+              // if current object is group update group's name
+             SMESH::SMESH_GroupBase_var aGroup =
+                SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IObject);
+              if (!aGroup->_is_nil() )
+                aGroup->SetName( newName.latin1() );
+               
+             updateObjBrowser();
+            }
+          }
+        }
+      }
+      break;
+    }
+
+  case 1102:                                   // REMOVE HYPOTHESIS / ALGORITHMS
+    {
+      if(checkLock(aStudy)) break;
+      SUIT_OverrideCursor wc;
+
+      SalomeApp_SelectionMgr *aSel = SMESHGUI::selectionMgr();
+      SALOME_ListIO selected;
+      if( aSel )
+        aSel->selectedObjects( selected );
+
+      SALOME_ListIteratorOfListIO It(selected);
+      for (int i = 0; It.More(); It.Next(), i++) {
+       Handle(SALOME_InteractiveObject) IObject = It.Value();
+       SMESH::RemoveHypothesisOrAlgorithmOnMesh(IObject);
+      }
+      SALOME_ListIO l1;
+      aSel->setSelectedObjects( l1 );
+      updateObjBrowser();
+      break;
+    }
+
+  case 401:                                    // GEOM::EDGE
+  case 4021:                                   // TRIANGLE
+  case 4022:                                   // QUAD
+  case 4023:                                   // POLYGON
+  case 4031:                                   // TETRA
+  case 4032:                                   // HEXA
+    {
+      if(checkLock(aStudy)) break;
+      if ( vtkwnd ) {
+       EmitSignalDeactivateDialog();
+        SMDSAbs_ElementType type    = SMDSAbs_Edge;
+        int                 nbNodes = 2;
+        switch (theCommandID) {
+        case 4021:                                      // TRIANGLE
+          type = SMDSAbs_Face; nbNodes = 3; break;
+        case 4022:                                      // QUAD
+          type = SMDSAbs_Face; nbNodes = 4; break;
+        case 4031:                                      // TETRA
+          type = SMDSAbs_Volume; nbNodes = 4; break;
+       case 4023:                                      // POLYGON
+         type = SMDSAbs_Face; nbNodes = 5; break;     // 5 - identificator for POLYGON
+        case 4032:                                      // HEXA
+          type = SMDSAbs_Volume; nbNodes = 8; break;
+       case 4033:                                      // POLYHEDRE
+         type = SMDSAbs_Volume; nbNodes = 9; break; // 9 - identificator for POLYHEDRE
+        default:;
+        }
+       new SMESHGUI_AddMeshElementDlg( this, "", type, nbNodes);
+      }
+      else {
+       SUIT_MessageBox::warn1(desktop(),
+                             tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+                             tr("SMESH_BUT_OK"));
+      }
+      break;
+    }
+  case 4033:                                   // POLYHEDRON
+    {
+      if(checkLock(aStudy)) break;
+      if ( vtkwnd ) {
+       EmitSignalDeactivateDialog();
+       new SMESHGUI_CreatePolyhedralVolumeDlg(this, "", FALSE );
+      }
+      else {
+       SUIT_MessageBox::warn1(SMESHGUI::desktop(),
+                             tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+                             tr("SMESH_BUT_OK"));
+      }
+      break;
+    }
+  case 4041:                                   // REMOVES NODES
+    {
+      if(checkLock(aStudy)) break;
+      if ( vtkwnd ) {
+       EmitSignalDeactivateDialog();
+       new SMESHGUI_RemoveNodesDlg(this);
+      }
+      else {
+       SUIT_MessageBox::warn1(desktop(),
+                             tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+                             tr("SMESH_BUT_OK"));
+      }
+      break;
+    }
+  case 4042:                                   // REMOVES ELEMENTS
+    {
+      if(checkLock(aStudy)) break;
+      if( vtkwnd ) {
+       EmitSignalDeactivateDialog();
+       new SMESHGUI_RemoveElementsDlg(this);
+      }
+      else
+       {
+         SUIT_MessageBox::warn1(desktop(),
+                               tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+                               tr("SMESH_BUT_OK"));
+       }
+      break;
+    }
+  case 4051:                                   // RENUMBERING NODES
+    {
+      if(checkLock(aStudy)) break;
+      if( vtkwnd ) {
+       EmitSignalDeactivateDialog();
+       new SMESHGUI_RenumberingDlg( this, "", 0);
+      }
+      else
+       {
+         SUIT_MessageBox::warn1(desktop(),
+                               tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+                               tr("SMESH_BUT_OK"));
+       }
+      break;
+    }
+  case 4052:                                   // RENUMBERING ELEMENTS
+    {
+      if(checkLock(aStudy)) break;
+      if ( vtkwnd ) {
+       EmitSignalDeactivateDialog();
+       new SMESHGUI_RenumberingDlg( this, "", 1);
+      }
+      else
+       {
+         SUIT_MessageBox::warn1(desktop(),
+                               tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+                               tr("SMESH_BUT_OK"));
+       }
+      break;
+    }
+  case 4061:                                   // TRANSLATION
+    {
+      if(checkLock(aStudy)) break;
+      if ( vtkwnd ) {
+       EmitSignalDeactivateDialog();
+       new SMESHGUI_TranslationDlg( this );
+      }
+      else {
+       SUIT_MessageBox::warn1(desktop(),
+                             tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+                             tr("SMESH_BUT_OK"));
+      }
+      break;
+    }
+  case 4062:                                   // ROTATION
+    {
+      if(checkLock(aStudy)) break;
+      if( vtkwnd ) {
+       EmitSignalDeactivateDialog();
+       new SMESHGUI_RotationDlg( this );
+      }
+      else {
+       SUIT_MessageBox::warn1(desktop(),
+                             tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+                             tr("SMESH_BUT_OK"));
+      }
+      break;
+    }
+  case 4063:                                   // SYMMETRY 
+    {
+      if(checkLock(aStudy)) break;
+      if(vtkwnd) {
+       EmitSignalDeactivateDialog();
+       new SMESHGUI_SymmetryDlg( this );
+      }
+      else {
+       SUIT_MessageBox::warn1(desktop(),
+                             tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+                             tr("SMESH_BUT_OK"));
+      }
+      break;
+    }
+  case 4064:                                   // SEWING
+    {
+      if(checkLock(aStudy)) break;
+      if(vtkwnd) {
+       EmitSignalDeactivateDialog();
+       new SMESHGUI_SewingDlg( this );
+      }
+      else {
+       SUIT_MessageBox::warn1(desktop(),
+                             tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+                             tr("SMESH_BUT_OK"));
+      }
+      break;
+    }
+  case 4065:                                   // MERGE NODES
+    {
+      if(checkLock(aStudy)) break;
+      if(vtkwnd) {
+       EmitSignalDeactivateDialog();
+       new SMESHGUI_MergeNodesDlg( this );
+      }
+      else {
+       SUIT_MessageBox::warn1(desktop(),
+                             tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+                             tr("SMESH_BUT_OK"));
+      }
+      break;
+    }
+  case 4066: // MERGE EQUAL ELEMENTS
+    {
+      if (checkLock(aStudy)) break;
+      if (vtkwnd) {
+       EmitSignalDeactivateDialog();
+       new SMESHGUI_EditMeshDlg(this,
+                                 "SMESH_MERGE_ELEMENTS_TITLE",
+                                 "ICON_DLG_MERGE_ELEMENTS",
+                                 1); // MergeEqualElemets
+      } else {
+       SUIT_MessageBox::warn1(desktop(),
+                             tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
+                             tr("SMESH_BUT_OK"));
+      }
+      break;
+    }
+    
+  case 5105: // Library of selection filters
+  {
+    static QValueList<int> aTypes;
+    if ( aTypes.isEmpty() )
+    {
+      aTypes.append( SMESH::NODE );
+      aTypes.append( SMESH::EDGE );
+      aTypes.append( SMESH::FACE );
+      aTypes.append( SMESH::VOLUME );
+    }
+    new SMESHGUI_FilterLibraryDlg( this, SMESH::GetDesktop( this ), aTypes, SMESHGUI_FilterLibraryDlg::EDIT );
+  }
+  break;
+
+  case 6017:                                   // CONTROLS
+  case 6016:
+  case 6015:
+  case 6014:
+  case 6013:
+  case 6012:
+  case 6011:
+  case 6001:
+  case 6018:
+  case 6019:
+  case 6002:
+  case 6003:
+  case 6004:
+    if ( vtkwnd ) {
+
+      SalomeApp_SelectionMgr* mgr = selectionMgr();
+      SALOME_ListIO selected; mgr->selectedObjects( selected );
+
+      if ( selected.Extent() == 1 && selected.First()->hasEntry() ) {
+       _PTR(SObject) SO = aStudy->FindObjectID( selected.First()->getEntry() );
+       if ( SO ) {
+         CORBA::Object_var aObject = SMESH::SObjectToObject( SO );
+         SMESH::SMESH_Mesh_var      aMesh    = SMESH::SMESH_Mesh::_narrow( aObject );
+         SMESH::SMESH_subMesh_var   aSubMesh = SMESH::SMESH_subMesh::_narrow( aObject );
+         SMESH::SMESH_GroupBase_var aGroup   = SMESH::SMESH_GroupBase::_narrow( aObject );
+         if ( !aMesh->_is_nil() || !aSubMesh->_is_nil() || !aGroup->_is_nil() ) {
+           ::Control( theCommandID );
+           break;
+         }
+       }
+      }
+      SUIT_MessageBox::warn1(desktop(),
+                           tr( "SMESH_WRN_WARNING" ),
+                           tr( "SMESH_BAD_SELECTION" ),
+                           tr( "SMESH_BUT_OK" ) );
+      break;
+    }
+    else {
+      SUIT_MessageBox::warn1(desktop(),
+                           tr( "SMESH_WRN_WARNING" ),
+                           tr( "NOT_A_VTK_VIEWER" ), 
+                           tr( "SMESH_BUT_OK" ) );
+    }
+    break;
+  case 9010:
+    {
+      SalomeApp_SelectionMgr* mgr = selectionMgr();
+      SALOME_ListIO selected; mgr->selectedObjects( selected );
+
+      if (selected.Extent() == 1)      {
+       Handle(SALOME_InteractiveObject) anIObject = selected.First();
+       if(anIObject->hasEntry())
+         if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){
+           anActor->SetPointsLabeled( !anActor->GetPointsLabeled() );
+         }
+      }
+      break;
+    }
+  case 9011:
+    {
+      SalomeApp_SelectionMgr* mgr = selectionMgr();
+      SALOME_ListIO selected; mgr->selectedObjects( selected );
+
+      if (selected.Extent() == 1)      {
+       Handle(SALOME_InteractiveObject) anIObject = selected.First();
+       if(anIObject->hasEntry())
+         if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){
+           anActor->SetCellsLabeled( !anActor->GetCellsLabeled() );
+         }
+      }
+      break;
+    }
+  }
+
+  anApp->updateActions(); //SRN: To update a Save button in the toolbar
+  //updateObjBrowser();
+  return true;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+bool SMESHGUI::OnMousePress( QMouseEvent * pe, SUIT_ViewWindow * wnd )
+{
+  return false;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+bool SMESHGUI::OnMouseMove( QMouseEvent * pe, SUIT_ViewWindow * wnd )
+{
+  return true;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+bool SMESHGUI::OnKeyPress( QKeyEvent * pe, SUIT_ViewWindow * wnd )
+{
+  return true;
+}
+
+//=============================================================================
+/*! Method:  BuildPresentation(const Handle(SALOME_InteractiveObject)& theIO)
+ *  Purpose: ensures that the actor for the given <theIO> exists in the active VTK view
+ */
+//=============================================================================
+void SMESHGUI::BuildPresentation( const Handle(SALOME_InteractiveObject) & theIO,
+                                  SUIT_ViewWindow* wnd )
+{
+  if(theIO->hasEntry()){
+    //SUIT_ViewWindow* wnd = SMESH::GetActiveWindow();
+    SMESH::UpdateView(wnd,SMESH::eDisplay,theIO->getEntry());
+  }
+}
+
+//=======================================================================
+// function : createSMESHAction
+// purpose  :
+//=======================================================================
+void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QString& icon_id, const int key, const bool toggle  )
+{
+  QIconSet icon;
+  QWidget* parent = application()->desktop();
+  SUIT_ResourceMgr* resMgr = resourceMgr();
+  QPixmap pix;
+  if ( icon_id.length() )
+    pix = resMgr->loadPixmap( "SMESH", tr( icon_id ) );
+  else
+    pix = resMgr->loadPixmap( "SMESH", tr( QString( "ICO_" )+po_id ), false );
+  if ( !pix.isNull() )
+    icon = QIconSet( pix );
+
+  QString tooltip    = tr( QString( "TOP_" )+po_id ),
+          menu       = tr( QString( "MEN_" )+po_id ),
+          status_bar = tr( QString( "STB_" )+po_id );
+
+  createAction( id, tooltip, icon, menu, status_bar, key, parent, toggle, this, SLOT( OnGUIEvent() )  );
+}
+
+//=======================================================================
+// function : createPopupItem
+// purpose  :
+//=======================================================================
+void SMESHGUI::createPopupItem( const int id,
+                                const QString& clients,
+                                const QString& types,
+                                const QString& theRule,
+                               const int pId )
+{
+  int parentId = pId;
+  if( pId!=-1 )
+    parentId = popupMgr()->actionId( action( pId ) );
+
+  if( !popupMgr()->contains( popupMgr()->actionId( action( id ) ) ) )
+    popupMgr()->insert( action( id ), parentId, 0 );
+
+  QChar lc = QtxPopupMgr::Selection::defEquality();
+  QString rule = "(%1) and (%2) and (%3)";
+  rule = rule.arg( QString( "%1>0" ).arg( QtxPopupMgr::Selection::defSelCountParam() ) );
+  rule = rule.arg( QString( "%1client in {%2}" ).arg( lc ).arg( clients ) );
+  rule = rule.arg( QString( "%1type in {%2}" ).arg( lc ).arg( types ) );
+  rule += theRule;
+
+  bool cont = myRules.contains( id );
+  if( cont )
+    rule = QString( "%1 or (%2)" ).arg( myRules[ id ] ).arg( rule );
+
+  popupMgr()->setRule( action( id ), rule, true );
+  myRules[ id ] = QString( cont ? "%1" : "(%1)" ).arg( rule );
+}
+
+//=======================================================================
+// function : initialize
+// purpose  :
+//=======================================================================
+void SMESHGUI::initialize( CAM_Application* app )
+{
+  SalomeApp_Module::initialize( app );
+
+//   SUIT_ResourceMgr* mgr = app->resourceMgr();
+//   if ( mgr )
+  /* Automatic Update flag */
+//     myAutomaticUpdate = mgr->booleanValue( "SMESH", "AutomaticUpdate", myAutomaticUpdate );
+
+  // ----- create actions --------------
+
+  createSMESHAction(  111, "DAT", "", (CTRL+Key_B) );
+  createSMESHAction(  112, "UNV", "", (CTRL+Key_U) );
+  createSMESHAction(  113, "MED", "", (CTRL+Key_M) );
+  createSMESHAction(  114, "NUM" );
+  createSMESHAction(  121, "DAT" );
+  createSMESHAction(  122, "MED" );
+  createSMESHAction(  123, "UNV" );
+  createSMESHAction(  124, "EXPORT_DAT" );
+  createSMESHAction(  125, "EXPORT_MED" );
+  createSMESHAction(  126, "EXPORT_UNV" );
+  createSMESHAction(   33, "DELETE",          "ICON_DELETE" );
+  createSMESHAction( 5105, "SEL_FILTER_LIB" );
+  createSMESHAction(  701, "COMPUTE",         "ICON_COMPUTE" );
+  createSMESHAction(  702, "CREATE_MESH",     "ICON_DLG_INIT_MESH" );
+  createSMESHAction(  703, "CREATE_SUBMESH",  "ICON_DLG_ADD_SUBMESH" );
+  createSMESHAction(  704, "EDIT_MESHSUBMESH","ICON_DLG_EDIT_MESH" );
+  createSMESHAction(  801, "CREATE_GROUP",    "ICON_SMESH_TREE_GROUP" );
+  createSMESHAction(  802, "CONSTRUCT_GROUP", "ICON_CONSTRUCT_GROUP" );
+  createSMESHAction(  803, "EDIT_GROUP",      "ICON_EDIT_GROUP" );
+  createSMESHAction(  804, "ADD" );
+  createSMESHAction(  805, "REMOVE" );
+  createSMESHAction(  810, "UN_GROUP",        "ICON_UNION" );
+  createSMESHAction(  811, "INT_GROUP",       "ICON_INTERSECT" );
+  createSMESHAction(  812, "CUT_GROUP",       "ICON_CUT" );
+  createSMESHAction(  813, "DEL_GROUP",       "ICON_DEL_GROUP" );
+  createSMESHAction(  900, "ADV_INFO",        "ICON_ADV_INFO" );
+  createSMESHAction(  902, "STD_INFO",        "ICON_STD_INFO" );
+  createSMESHAction( 6001, "LENGTH",          "ICON_LENGTH" ,       0, true );
+  createSMESHAction( 6002, "FREE_EDGE",       "ICON_FREE_EDGE" ,    0, true );
+  createSMESHAction( 6003, "FREE_BORDER",     "ICON_FREE_EDGE_2D" , 0, true );
+  createSMESHAction( 6004, "CONNECTION",      "ICON_CONNECTION" ,   0, true );
+  createSMESHAction( 6011, "AREA",            "ICON_AREA" ,         0, true );
+  createSMESHAction( 6012, "TAPER",           "ICON_TAPER" ,        0, true );
+  createSMESHAction( 6013, "ASPECT",          "ICON_ASPECT" ,       0, true );
+  createSMESHAction( 6014, "MIN_ANG",         "ICON_ANGLE" ,        0, true );
+  createSMESHAction( 6015, "WARP",            "ICON_WARP" ,         0, true );
+  createSMESHAction( 6016, "SKEW",            "ICON_SKEW",          0, true );
+  createSMESHAction( 6017, "ASPECT_3D",       "ICON_ASPECT_3D",     0, true );
+  createSMESHAction( 6018, "LENGTH_2D",       "ICON_LENGTH_2D",     0, true );
+  createSMESHAction( 6019, "CONNECTION_2D",   "ICON_CONNECTION_2D", 0, true );
+  createSMESHAction(  400, "NODE",            "ICON_DLG_NODE" );
+  createSMESHAction(  401, "EDGE",            "ICON_DLG_EDGE" );
+  createSMESHAction( 4021, "TRIANGLE",        "ICON_DLG_TRIANGLE" );
+  createSMESHAction( 4022, "QUAD",            "ICON_DLG_QUADRANGLE" );
+  createSMESHAction( 4023, "POLYGON",         "ICON_DLG_POLYGON" );
+  createSMESHAction( 4031, "TETRA",           "ICON_DLG_TETRAS" );
+  createSMESHAction( 4032, "HEXA",            "ICON_DLG_HEXAS" );
+  createSMESHAction( 4041, "REMOVE_NODES",    "ICON_DLG_REM_NODE" );
+  createSMESHAction( 4042, "REMOVE_ELEMENTS", "ICON_DLG_REM_ELEMENT" );
+  createSMESHAction( 4051, "RENUM_NODES",     "ICON_DLG_RENUMBERING_NODES" );
+  createSMESHAction( 4052, "RENUM_ELEMENTS",  "ICON_DLG_RENUMBERING_ELEMENTS" );
+  createSMESHAction( 4061, "TRANS",           "ICON_SMESH_TRANSLATION_VECTOR" );
+  createSMESHAction( 4062, "ROT",             "ICON_DLG_ROTATION" );
+  createSMESHAction( 4063, "SYM",             "ICON_SMESH_SYMMETRY_PLANE" );
+  createSMESHAction( 4064, "SEW",             "ICON_SMESH_SEWING_FREEBORDERS" );
+  createSMESHAction( 4065, "MERGE",           "ICON_SMESH_MERGE_NODES" );
+  createSMESHAction( 4066, "MERGE_ELEMENTS",  "ICON_DLG_MERGE_ELEMENTS" );
+  createSMESHAction(  406, "MOVE",            "ICON_DLG_MOVE_NODE" );
+  createSMESHAction(  407, "INV",             "ICON_DLG_MESH_DIAGONAL" );
+  createSMESHAction(  408, "UNION2",          "ICON_UNION2TRI" );
+  createSMESHAction(  409, "ORIENT",          "ICON_DLG_MESH_ORIENTATION" );
+  createSMESHAction(  410, "UNION",           "ICON_UNIONTRI" );
+  createSMESHAction(  411, "CUT",             "ICON_CUTQUAD" );
+  createSMESHAction(  412, "SMOOTH",          "ICON_DLG_SMOOTHING" );
+  createSMESHAction(  413, "EXTRUSION",       "ICON_EXTRUSION" );
+  createSMESHAction(  414, "REVOLUTION",      "ICON_REVOLUTION" );
+  createSMESHAction(  415, "MAP",             "ICON_MAP" );
+  createSMESHAction(  416, "EXTRUSION_ALONG", "ICON_EXTRUSION_ALONG" );
+  createSMESHAction(  200, "RESET" );
+  createSMESHAction(  201, "SCALAR_BAR_PROP" );
+  createSMESHAction(  211, "WIRE",           "ICON_WIRE", 0, true );
+  createSMESHAction(  212, "SHADE",          "ICON_SHADE", 0, true );
+  createSMESHAction(  213, "SHRINK",         "ICON_SHRINK", 0, true );
+  createSMESHAction(  214, "UPDATE",         "ICON_UPDATE" );
+  createSMESHAction(  215, "NODES",          "ICON_POINTS", 0, true );
+  createSMESHAction(  217, "EDGES",          "ICON_DLG_EDGE", 0, true );
+  createSMESHAction(  218, "FACES",          "ICON_DLG_TRIANGLE", 0, true );
+  createSMESHAction(  219, "VOLUMES",        "ICON_DLG_TETRAS", 0, true );
+  createSMESHAction(  220, "ALL" );
+  createSMESHAction( 1100, "EDIT_HYPO" );
+  createSMESHAction( 1101, "RENAME" );
+  createSMESHAction( 1102, "UNASSIGN" );
+  createSMESHAction( 9010, "NUM_NODES", "", 0, true );
+  createSMESHAction( 9011, "NUM_ELEMENTS", "", 0, true );
+  createSMESHAction( 1131, "DISPMODE" );
+  createSMESHAction( 1132, "COLORS" );
+  createSMESHAction( 1133, "TRANSP" );
+  createSMESHAction( 1134, "CLIP" );
+  createSMESHAction( 1135, "DISP_ENT" );
+  createSMESHAction( 2000, "CTRL" );
+  
+  createSMESHAction( 300, "ERASE" );
+  createSMESHAction( 301, "DISPLAY" );
+  createSMESHAction( 302, "DISPLAY_ONLY" );
+  createSMESHAction( 4033, "POLYHEDRON", "ICON_DLG_POLYHEDRON" );
+
+  // ----- create menu --------------
+  int fileId   = createMenu( tr( "MEN_FILE" ),   -1,  1 ),
+      editId   = createMenu( tr( "MEN_EDIT" ),   -1,  3 ),
+      toolsId  = createMenu( tr( "MEN_TOOLS" ),  -1,  5, 50 ),
+      meshId   = createMenu( tr( "MEN_MESH" ),   -1, 70, 10 ),
+      ctrlId   = createMenu( tr( "MEN_CTRL" ),   -1, 60, 10 ),
+      modifyId = createMenu( tr( "MEN_MODIFY" ), -1, 40, 10 ),
+      viewId   = createMenu( tr( "MEN_VIEW" ),   -1,  2 );
+
+  createMenu( separator(), fileId );
+
+  int importId = createMenu( tr( "MEN_IMPORT" ), fileId, 11, 10 ),
+      exportId = createMenu( tr( "MEN_EXPORT" ), fileId, 12, 10 ),
+      addId    = createMenu( tr( "MEN_ADD" ),    modifyId, 402 ),
+      removeId = createMenu( tr( "MEN_REMOVE" ), modifyId, 403 ),
+      renumId  = createMenu( tr( "MEN_RENUM" ),  modifyId, 404 ),
+      transfId = createMenu( tr( "MEN_TRANSF" ), modifyId, 405 );
+
+  createMenu( 111, importId, -1 );
+  createMenu( 112, importId, -1 );
+  createMenu( 113, importId, -1 );
+
+  createMenu( 121, exportId, -1 );
+  createMenu( 122, exportId, -1 );
+  createMenu( 123, exportId, -1 );
+
+  createMenu( separator(), fileId, 10 );
+
+  createMenu( 33, editId, -1 );
+
+  createMenu( 5105, toolsId, -1 );
+
+  createMenu( 702, meshId, -1 );
+  createMenu( 703, meshId, -1 );
+  createMenu( 704, meshId, -1 );
+  createMenu( separator(), meshId, -1 );
+  createMenu( 701, meshId, -1 );
+  createMenu( separator(), meshId, -1 );
+  createMenu( 801, meshId, -1 );
+  createMenu( 802, meshId, -1 );
+  createMenu( 803, meshId, -1 );
+  createMenu( separator(), meshId, -1 );
+  createMenu( 810, meshId, -1 );
+  createMenu( 811, meshId, -1 );
+  createMenu( 812, meshId, -1 );
+  createMenu( separator(), meshId, -1 );
+  createMenu( 813, meshId, -1 );
+  createMenu( separator(), meshId, -1 );
+  createMenu( 900, meshId, -1 );
+  createMenu( 902, meshId, -1 );
+  createMenu( separator(), meshId, -1 );
+
+  createMenu( 6003, ctrlId, -1 );
+  createMenu( 6001, ctrlId, -1 );
+  createMenu( 6004, ctrlId, -1 );
+  createMenu( separator(), ctrlId, -1 );
+  createMenu( 6002, ctrlId, -1 );
+  createMenu( 6018, ctrlId, -1 );
+  createMenu( 6019, ctrlId, -1 );
+  createMenu( 6011, ctrlId, -1 );
+  createMenu( 6012, ctrlId, -1 );
+  createMenu( 6013, ctrlId, -1 );
+  createMenu( 6014, ctrlId, -1 );
+  createMenu( 6015, ctrlId, -1 );
+  createMenu( 6016, ctrlId, -1 );
+  createMenu( separator(), ctrlId, -1 );
+  createMenu( 6017, ctrlId, -1 );
+  createMenu( separator(), ctrlId, -1 );
+
+  createMenu( 400, addId, -1 );
+  createMenu( 401, addId, -1 );
+  createMenu( 4021, addId, -1 );
+  createMenu( 4022, addId, -1 );
+  createMenu( 4023, addId, -1 );
+  createMenu( 4031, addId, -1 );
+  createMenu( 4032, addId, -1 );
+  createMenu( 4033, addId, -1 );
+
+  createMenu( 4041, removeId, -1 );
+  createMenu( 4042, removeId, -1 );
+
+  createMenu( 4051, renumId, -1 );
+  createMenu( 4052, renumId, -1 );
+
+  createMenu( 4061, transfId, -1 );
+  createMenu( 4062, transfId, -1 );
+  createMenu( 4063, transfId, -1 );
+  createMenu( 4064, transfId, -1 );
+  createMenu( 4065, transfId, -1 );
+  createMenu( 4066, transfId, -1 );
+
+  createMenu( 406, modifyId, -1 );
+  createMenu( 407, modifyId, -1 );
+  createMenu( 408, modifyId, -1 );
+  createMenu( 409, modifyId, -1 );
+  createMenu( 410, modifyId, -1 );
+  createMenu( 411, modifyId, -1 );
+  createMenu( 412, modifyId, -1 );
+  createMenu( 413, modifyId, -1 );
+  createMenu( 416, modifyId, -1 );
+  createMenu( 414, modifyId, -1 );
+  createMenu( 415, modifyId, -1 );
+
+  createMenu( 214, viewId, -1 );
+
+  // ----- create toolbars --------------
+  int meshTb     = createTool( tr( "TB_MESH" ) ),
+      ctrlTb     = createTool( tr( "TB_CTRL" ) ),
+      addRemTb   = createTool( tr( "TB_ADD_REMOVE" ) ),
+      modifyTb   = createTool( tr( "TB_MODIFY" ) ),
+      dispModeTb = createTool( tr( "TB_DISP_MODE" ) );
+
+  createTool( 702, meshTb );
+  createTool( 703, meshTb );
+  createTool( 704, meshTb );
+  createTool( separator(), meshTb );
+  createTool( 701, meshTb );
+  createTool( separator(), meshTb );
+  createTool( 801, meshTb );
+  createTool( 802, meshTb );
+  createTool( 803, meshTb );
+  createTool( separator(), meshTb );
+  createTool( 900, meshTb );
+  createTool( 902, meshTb );
+  createTool( separator(), meshTb );
+
+  createTool( 6001, ctrlTb );
+  createTool( 6003, ctrlTb );
+  createTool( 6004, ctrlTb );
+  createTool( separator(), ctrlTb );
+  createTool( 6002, ctrlTb );
+  createTool( 6018, ctrlTb );
+  createTool( 6019, ctrlTb );
+  createTool( 6011, ctrlTb );
+  createTool( 6012, ctrlTb );
+  createTool( 6013, ctrlTb );
+  createTool( 6014, ctrlTb );
+  createTool( 6015, ctrlTb );
+  createTool( 6016, ctrlTb );
+  createTool( separator(), ctrlTb );
+  createTool( 6017, ctrlTb );
+  createTool( separator(), ctrlTb );
+
+  createTool( 400, addRemTb );
+  createTool( 401, addRemTb );
+  createTool( 4021, addRemTb );
+  createTool( 4022, addRemTb );
+  createTool( 4023, addRemTb );
+  createTool( 4031, addRemTb );
+  createTool( 4032, addRemTb );
+  createTool( 4033, addRemTb );
+  createTool( separator(), addRemTb );
+  createTool( 4041, addRemTb );
+  createTool( 4042, addRemTb );
+  createTool( separator(), addRemTb );
+  createTool( 4051, addRemTb );
+  createTool( 4052, addRemTb );
+  createTool( separator(), addRemTb );
+  createTool( 4061, addRemTb );
+  createTool( 4062, addRemTb );
+  createTool( 4063, addRemTb );
+  createTool( 4064, addRemTb );
+  createTool( 4065, addRemTb );
+  createTool( 4066, addRemTb );
+  createTool( separator(), addRemTb );
+
+  createTool( 406, modifyTb );
+  createTool( 407, modifyTb );
+  createTool( 408, modifyTb );
+  createTool( 409, modifyTb );
+  createTool( 410, modifyTb );
+  createTool( 411, modifyTb );
+  createTool( 412, modifyTb );
+  createTool( 413, modifyTb );
+  createTool( 416, modifyTb );
+  createTool( 414, modifyTb );
+  createTool( 415, modifyTb );
+
+  createTool( 214, dispModeTb );
+
+
+  myRules.clear();
+  QString OB = "'ObjectBrowser'",
+         View = "'" + SVTK_Viewer::Type() + "'",
+         pat = "'%1'",
+         mesh    = pat.arg( SMESHGUI_Selection::typeName( MESH ) ),
+         group   = pat.arg( SMESHGUI_Selection::typeName( GROUP ) ),
+         hypo    = pat.arg( SMESHGUI_Selection::typeName( HYPOTHESIS ) ),
+         algo    = pat.arg( SMESHGUI_Selection::typeName( ALGORITHM ) ),
+         elems   = QString( "'%1' '%2' '%3' '%4' '%5'" ).
+                       arg( SMESHGUI_Selection::typeName( SUBMESH_VERTEX ) ).
+                      arg( SMESHGUI_Selection::typeName( SUBMESH_EDGE ) ).
+                      arg( SMESHGUI_Selection::typeName( SUBMESH_FACE ) ).
+                      arg( SMESHGUI_Selection::typeName( SUBMESH_SOLID ) ).
+                      arg( SMESHGUI_Selection::typeName( SUBMESH_COMPOUND ) ),
+          subMesh = elems,
+         mesh_group = mesh + " " + subMesh + " " + group,
+         hyp_alg = hypo + " " + algo;
+
+  // popup for object browser
+
+  createPopupItem( 704, OB, mesh, "&& isComputable");      // EDIT_MESHSUBMESH
+  createPopupItem( 704, OB, subMesh, "&& isComputable" );  // EDIT_MESHSUBMESH
+  createPopupItem( 803, OB, group );                       // EDIT_GROUP
+  popupMgr()->insert( separator(), -1, 0 );
+  createPopupItem( 701, OB, mesh, "&& isComputable" );     // COMPUTE
+  createPopupItem( 214, OB, mesh_group );                  // UPDATE
+  createPopupItem( 900, OB, mesh_group );                  // ADV_INFO
+  createPopupItem( 902, OB, mesh );                        // STD_INFO
+  popupMgr()->insert( separator(), -1, 0 );
+  createPopupItem( 801, OB, mesh );                        // CREATE_GROUP
+  createPopupItem( 802, OB, subMesh );                     // CONSTRUCT_GROUP
+  popupMgr()->insert( separator(), -1, 0 );
+  createPopupItem( 1100, OB, hypo, "&& $hasReference={false}" );   // EDIT HYPOTHESIS
+  createPopupItem( 1102, OB, hyp_alg ); // REMOVE HYPOTHESIS / ALGORITHMS
+  createPopupItem( 1101, OB, mesh_group + " " + hyp_alg, "&& $hasReference={false}" ); // RENAME
+  popupMgr()->insert( separator(), -1, 0 );
+  createPopupItem( 125, OB, mesh );                        // EXPORT_MED
+  createPopupItem( 126, OB, mesh );                        // EXPORT_UNV
+  createPopupItem( 33, OB, subMesh + " " + group );        // DELETE
+  popupMgr()->insert( separator(), -1, 0 );
+
+  // popup for viewer
+  createPopupItem( 803, View, group ); // EDIT_GROUP
+  createPopupItem( 804, View, elems ); // ADD
+  createPopupItem( 805, View, elems ); // REMOVE
+  popupMgr()->insert( separator(), -1, 0 );
+  createPopupItem( 214, View, mesh_group ); // UPDATE
+  createPopupItem( 900, View, mesh_group ); // ADV_INFO
+  createPopupItem( 902, View, mesh );       // STD_INFO
+  popupMgr()->insert( separator(), -1, 0 );
+
+  int anId;
+  QString
+    isInvisible("not( isVisible )"),
+    isEmpty("numberOfNodes = 0"),
+    isNotEmpty("numberOfNodes <> 0"),
+
+    // has nodes, edges, etc in VISIBLE! actor
+    hasNodes("(numberOfNodes > 0 )"),//&& isVisible)"),
+    hasElems("(count( elemTypes ) > 0)"),
+    hasDifferentElems("(count( elemTypes ) > 1)"),
+    hasEdges("({'Edge'} in elemTypes)"),
+    hasFaces("({'Face'} in elemTypes)"),
+    hasVolumes("({'Volume'} in elemTypes)");
+
+  QString lc = QtxPopupMgr::Selection::defEquality();
+  QString aClient = QString( "%1client in {%2}" ).arg( lc ).arg( "'VTKViewer'" );
+  QString aType = QString( "%1type in {%2}" ).arg( QtxPopupMgr::Selection::defEquality() ).arg( mesh_group );
+  QString aMeshInVTK = aClient + "&&" + aType;
+  
+  //-------------------------------------------------
+  // Numbering
+  //-------------------------------------------------
+  anId = popupMgr()->insert( tr( "MEN_NUM" ), -1, -1 );
+  
+  popupMgr()->insert( action( 9010 ), anId, -1 );
+  popupMgr()->setRule( action( 9010 ), aMeshInVTK + "&& isVisible &&" + hasNodes, true );
+  popupMgr()->setRule( action( 9010 ), "{'Point'} in labeledTypes", false );
+
+  popupMgr()->insert( action( 9011 ), anId, -1 );
+  popupMgr()->setRule( action( 9011 ), aMeshInVTK + "&& isVisible &&" + hasElems, true );
+  popupMgr()->setRule( action( 9011 ), "{'Cell'} in labeledTypes", false );
+
+  popupMgr()->insert( separator(), -1, -1 );
+
+  //-------------------------------------------------
+  // Display Mode
+  //-------------------------------------------------
+  anId = popupMgr()->insert( tr( "MEN_DISPMODE" ), -1, -1 );
+
+  popupMgr()->insert( action( 211 ), anId, -1 ); // WIRE
+  popupMgr()->setRule( action( 211 ), aMeshInVTK + "&&" + hasElems, true );
+  popupMgr()->setRule( action( 211 ), "displayMode = 'eEdge'", false );
+
+  popupMgr()->insert( action( 212 ), anId, -1 ); // SHADE
+  popupMgr()->setRule( action( 212 ),aMeshInVTK+ "&& (" + hasFaces + "||" + hasVolumes + ")",true);
+  popupMgr()->setRule( action( 212 ), "displayMode = 'eSurface'", false );
+
+  popupMgr()->insert( action( 215 ), anId, -1 ); // POINTS
+  popupMgr()->setRule( action( 215 ), aMeshInVTK + "&&" + hasNodes, true );
+  popupMgr()->setRule( action( 215 ), "displayMode = 'ePoint'", false );
+
+  popupMgr()->insert( separator(), anId, -1 );
+
+  popupMgr()->insert( action( 213 ), anId, -1 ); // SHRINK
+  popupMgr()->setRule( action( 213 ), aMeshInVTK + "&& shrinkMode <> 'IsNotShrinkable' && displayMode <> 'ePoint'",true);
+  popupMgr()->setRule( action( 213 ), "shrinkMode = 'IsShrunk'", false );
+
+  //-------------------------------------------------
+  // Display Entity
+  //-------------------------------------------------
+  QString aDiffElemsInVTK = aMeshInVTK + "&&" + hasDifferentElems;
+
+  anId = popupMgr()->insert( tr( "MEN_DISP_ENT" ), -1, -1 );
+
+  popupMgr()->insert( action( 217 ), anId, -1 ); // EDGES
+  popupMgr()->setRule( action( 217 ), aDiffElemsInVTK + "&& isVisible &&" + hasEdges, true );
+  popupMgr()->setRule( action( 217 ), "{'Edge'} in entityMode", false );
+
+  popupMgr()->insert( action( 218 ), anId, -1 ); // FACES
+  popupMgr()->setRule( action( 218 ), aDiffElemsInVTK + "&& isVisible &&" + hasFaces, true );
+  popupMgr()->setRule( action( 218 ), "{'Face'} in entityMode", false );
+
+  popupMgr()->insert( action( 219 ), anId, -1 ); // VOLUMES
+  popupMgr()->setRule( action( 219 ), aDiffElemsInVTK + "&& isVisible &&" + hasVolumes, true );
+  popupMgr()->setRule( action( 219 ), "{'Volume'} in entityMode", false );
+
+  popupMgr()->insert( separator(), anId, -1 );
+
+  popupMgr()->insert( action( 220 ), anId, -1 ); // ALL
+  popupMgr()->setRule( action( 220 ), aDiffElemsInVTK + "&& isVisible && not( elemTypes in entityMode )", true );
+
+  //-------------------------------------------------
+  // Color / Size
+  //-------------------------------------------------
+  popupMgr()->insert( action( 1132 ), -1, -1 );
+  popupMgr()->setRule( action( 1132 ), aMeshInVTK + "&& isVisible", true );
+
+  //-------------------------------------------------
+  // Transparency
+  //-------------------------------------------------
+  popupMgr()->insert( action( 1133 ), -1, -1 );
+  popupMgr()->setRule( action( 1133 ), aMeshInVTK + "&& isVisible", true );
+
+  //-------------------------------------------------
+  // Clipping
+  //-------------------------------------------------
+  popupMgr()->insert( action( 1134 ), -1, -1 );
+  popupMgr()->setRule( action( 1134 ), aMeshInVTK + "&& isVisible", true );
+
+  popupMgr()->insert( separator(), -1, -1 );
+
+  //-------------------------------------------------
+  // Controls
+  //-------------------------------------------------
+  QString
+    aMeshInVtkHasEdges = aMeshInVTK + "&&" + hasEdges,
+    aMeshInVtkHasFaces = aMeshInVTK + "&&" + hasFaces,
+    aMeshInVtkHasVolumes = aMeshInVTK + "&&" + hasVolumes;
+
+  anId = popupMgr()->insert( tr( "MEN_CTRL" ), -1, -1 );
+
+  popupMgr()->insert( action( 200 ), anId, -1 ); // RESET
+  popupMgr()->setRule( action( 200 ), aMeshInVTK + "&& controlMode <> 'eNone'", true );
+
+  popupMgr()->insert( separator(), anId, -1 );
+
+  popupMgr()->insert( action( 6003 ), anId, -1 ); // FREE_BORDER
+  popupMgr()->setRule( action( 6003 ), aMeshInVtkHasEdges, true );
+  popupMgr()->setRule( action( 6003 ), "controlMode = 'eFreeEdges'", false );
+
+  popupMgr()->insert( action( 6001 ), anId, -1 ); // LENGTH
+  popupMgr()->setRule( action( 6001 ), aMeshInVtkHasEdges, true );
+  popupMgr()->setRule( action( 6001 ), "controlMode = 'eLength'", false );
+
+  popupMgr()->insert( action( 6004 ), anId, -1 ); // CONNECTION
+  popupMgr()->setRule( action( 6004 ), aMeshInVtkHasEdges, true );
+  popupMgr()->setRule( action( 6004 ), "controlMode = 'eMultiConnection'", false );
+
+  popupMgr()->insert( separator(), anId, -1 );
+
+  popupMgr()->insert( action( 6002 ), anId, -1 ); // FREE_EDGE
+  popupMgr()->setRule( action( 6002 ), aMeshInVtkHasFaces, true );
+  popupMgr()->setRule( action( 6002 ), "controlMode = 'eFreeBorders'", false );
+
+  popupMgr()->insert( action( 6018 ), anId, -1 ); // LENGTH_2D
+  popupMgr()->setRule( action( 6018 ), aMeshInVtkHasFaces, true );
+  popupMgr()->setRule( action( 6018 ), "controlMode = 'eLength2D'", false );
+
+  popupMgr()->insert( action( 6019 ), anId, -1 ); // CONNECTION_2D
+  popupMgr()->setRule( action( 6019 ), aMeshInVtkHasFaces, true );
+  popupMgr()->setRule( action( 6019 ), "controlMode = 'eMultiConnection2D'", false );
+
+  popupMgr()->insert( action( 6011 ), anId, -1 ); // AREA
+  popupMgr()->setRule( action( 6011 ), aMeshInVtkHasFaces, true );
+  popupMgr()->setRule( action( 6011 ), "controlMode = 'eArea'", false );
+
+  popupMgr()->insert( action( 6012 ), anId, -1 ); // TAPER
+  popupMgr()->setRule( action( 6012 ), aMeshInVtkHasFaces, true );
+  popupMgr()->setRule( action( 6012 ), "controlMode = 'eTaper'", false );
+
+  popupMgr()->insert( action( 6013 ), anId, -1 ); // ASPECT
+  popupMgr()->setRule( action( 6013 ), aMeshInVtkHasFaces, true );
+  popupMgr()->setRule( action( 6013 ), "controlMode = 'eAspectRatio'", false );
+
+  popupMgr()->insert( action( 6014 ), anId, -1 ); // MIN_ANG
+  popupMgr()->setRule( action( 6014 ), aMeshInVtkHasFaces, true );
+  popupMgr()->setRule( action( 6014 ), "controlMode = 'eMinimumAngle'", false );
+
+  popupMgr()->insert( action( 6015 ), anId, -1 ); // WARP
+  popupMgr()->setRule( action( 6015 ), aMeshInVtkHasFaces, true );
+  popupMgr()->setRule( action( 6015 ), "controlMode = 'eWarping'", false );
+
+  popupMgr()->insert( action( 6016 ), anId, -1 ); // SKEW
+  popupMgr()->setRule( action( 6016 ), aMeshInVtkHasFaces, true );
+  popupMgr()->setRule( action( 6016 ), "controlMode = 'eSkew'", false );
+
+  popupMgr()->insert( separator(), anId, -1 );
+
+  popupMgr()->insert( action( 6017 ), anId, -1 ); // ASPECT_3D
+  popupMgr()->setRule( action( 6017 ), aMeshInVtkHasVolumes, true );
+  popupMgr()->setRule( action( 6017 ), "controlMode = 'eAspectRatio3D'", false );
+
+  popupMgr()->insert( separator(), anId, -1 );
+
+  popupMgr()->insert( action( 201 ), anId, -1 ); // SCALAR_BAR_PROP
+  popupMgr()->setRule( action( 201 ), aMeshInVTK + "&& controlMode <> 'eNone'", true );
+
+  popupMgr()->insert( separator(), -1, -1 );
+
+  //-------------------------------------------------
+  // Display / Erase
+  //-------------------------------------------------
+  aClient = "($client in {'VTKViewer' 'ObjectBrowser'})";
+  QString anActiveVTK = QString("activeView = '%1'").arg(VTKViewer_Viewer::Type());
+  QString aSelCount = QString( "%1 > 0" ).arg( QtxPopupMgr::Selection::defSelCountParam() );
+  QString aRule = aClient + " and " + aType + " and " + aSelCount + " and " + anActiveVTK;
+  popupMgr()->insert( action( 301 ), -1, -1 ); // DISPLAY
+  popupMgr()->setRule( action( 301 ), aRule + "&&" + isNotEmpty + "&&" + isInvisible, true);
+
+  popupMgr()->insert( action( 300 ), -1, -1 ); // ERASE
+  popupMgr()->setRule( action( 300 ), aRule + "&&" + isNotEmpty + "&& isVisible", true );
+
+  popupMgr()->insert( action( 302 ), -1, -1 ); // DISPLAY_ONLY
+  popupMgr()->setRule( action( 302 ), aRule + "&&" + isNotEmpty, true );
+
+  popupMgr()->insert( separator(), -1, -1 );
+
+  connect( application(), SIGNAL( viewManagerAdded( SUIT_ViewManager* ) ), 
+          this, SLOT( onViewManagerAdded( SUIT_ViewManager* ) ) );
+}
+
+bool SMESHGUI::activateModule( SUIT_Study* study )
+{
+  bool res = SalomeApp_Module::activateModule( study );
+
+  setMenuShown( true );
+  setToolShown( true );
+
+  return res;
+}
+
+bool SMESHGUI::deactivateModule( SUIT_Study* study )
+{
+  setMenuShown( false );
+  setToolShown( false );
+
+  EmitSignalCloseAllDialogs();
+  
+  return SalomeApp_Module::deactivateModule( study );
+}
+
+void SMESHGUI::OnGUIEvent()
+{
+  const QObject* obj = sender();
+  if ( !obj || !obj->inherits( "QAction" ) )
+    return;
+  int id = actionId((QAction*)obj);
+  if ( id != -1 )
+    OnGUIEvent( id );
+}
+
+SMESH::SMESH_Gen_var SMESHGUI::GetSMESHGen()
+{
+  if ( CORBA::is_nil( myComponentSMESH ) )
+    {
+      SMESHGUI aGUI; //SRN BugID: IPAL9186: Create an instance of SMESHGUI to initialize myComponentSMESH
+      return aGUI.myComponentSMESH;
+    }  
+  return myComponentSMESH;
+}
+
+QString SMESHGUI::engineIOR() const
+{
+  CORBA::ORB_var anORB = getApp()->orb();
+  CORBA::String_var anIOR = anORB->object_to_string(GetSMESHGen());
+  return anIOR.in();
+}
+
+void SMESHGUI::contextMenuPopup( const QString& client, QPopupMenu* menu, QString& /*title*/ )
+{
+  SMESHGUI_Selection sel;
+  sel.init( client, selectionMgr() );
+  popupMgr()->updatePopup( menu, &sel );
+}
+
+void SMESHGUI::windows( QMap<int, int>& aMap ) const
+{
+  aMap.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::DockLeft );
+  aMap.insert( SalomeApp_Application::WT_PyConsole, Qt::DockBottom );
+}
+
+void SMESHGUI::viewManagers( QStringList& list ) const
+{
+  list.append( SVTK_Viewer::Type() );
+}
+
+void SMESHGUI::onViewManagerAdded( SUIT_ViewManager* mgr )
+{
+  if ( dynamic_cast<VTKViewer_ViewManager*>( mgr ) )
+    SMESH::UpdateSelectionProp( this );
+}
+
+void SMESHGUI::createPreferences()
+{
+  int genTab = addPreference( tr( "PREF_TAB_GENERAL" ) );
+
+  int updateGroup = addPreference( tr( "PREF_GROUP_UPDATE" ), genTab );
+  addPreference( tr( "PREF_AUTO_UPDATE" ), updateGroup, SalomeApp_Preferences::Bool, "SMESH", "auto_update" );
+
+  int qaGroup = addPreference( tr( "PREF_GROUP_QUALITY" ), genTab );
+  addPreference( tr( "PREF_DISPLAY_ENTITY" ), qaGroup, SalomeApp_Preferences::Bool, "SMESH", "display_entity" );
+  addPreference( tr( "PREF_PRECISION_USE" ), qaGroup, SalomeApp_Preferences::Bool, "SMESH", "use_precision" );
+  
+  int precGroup = addPreference( tr( "PREF_GROUP_PRECISION" ), genTab );
+  setPreferenceProperty( precGroup, "columns", 1 );
+
+  int prec = addPreference( tr( "PREF_PRECISION_VALUE" ), precGroup, SalomeApp_Preferences::IntSpin, "SMESH", "controls_precision" );
+
+  setPreferenceProperty( prec, "min", 0 );
+  setPreferenceProperty( prec, "max", 16 );
+
+  int dispgroup = addPreference( tr( "PREF_DISPLAY_MODE" ), genTab );
+  int dispmode = addPreference( tr( "PREF_DISPLAY_MODE" ), dispgroup, SalomeApp_Preferences::Selector, "SMESH", "display_mode" );
+  QStringList modes;
+  modes.append( "Wireframe" );
+  modes.append( "Shading" );
+  modes.append( "Nodes" );
+  modes.append( "Shrink" );
+  QValueList<QVariant> indices; 
+  indices.append( 0 ); 
+  indices.append( 1 );
+  indices.append( 2 );
+  indices.append( 3 );
+  setPreferenceProperty( dispmode, "strings", modes );
+  setPreferenceProperty( dispmode, "indexes", indices );
+  
+  int meshTab = addPreference( tr( "PREF_TAB_MESH" ) );
+  int nodeGroup = addPreference( tr( "PREF_GROUP_NODES" ), meshTab );
+
+  addPreference( tr( "PREF_COLOR" ), nodeGroup, SalomeApp_Preferences::Color, "SMESH", "node_color" );
+  int nodeSz = addPreference( tr( "PREF_SIZE" ), nodeGroup, SalomeApp_Preferences::IntSpin, "SMESH", "node_size" );
+
+  setPreferenceProperty( nodeSz, "min", 1 );
+  setPreferenceProperty( nodeSz, "max", 5 );
+
+  int elemGroup = addPreference( tr( "PREF_GROUP_ELEMENTS" ), meshTab );
+
+  addPreference( tr( "PREF_FILL" ), elemGroup, SalomeApp_Preferences::Color, "SMESH", "fill_color" );
+  addPreference( tr( "PREF_OUTLINE" ), elemGroup, SalomeApp_Preferences::Color, "SMESH", "outline_color" );
+  addPreference( tr( "PREF_BACKFACE" ), elemGroup, SalomeApp_Preferences::Color, "SMESH", "backface_color" );
+  addPreference( "", elemGroup, SalomeApp_Preferences::Space );
+
+  int elemW = addPreference( tr( "PREF_WIDTH" ), elemGroup, SalomeApp_Preferences::IntSpin, "SMESH", "element_width" );
+  int shrink = addPreference( tr( "PREF_SHRINK_COEFF" ), elemGroup, SalomeApp_Preferences::IntSpin, "SMESH", "shrink_coeff" );
+
+  setPreferenceProperty( elemW, "min", 1 );
+  setPreferenceProperty( elemW, "max", 5 );
+
+  setPreferenceProperty( shrink, "min", 0 );
+  setPreferenceProperty( shrink, "max", 100 );
+
+  int selTab = addPreference( tr( "PREF_TAB_SELECTION" ) );
+
+  int selGroup = addPreference( tr( "PREF_GROUP_SELECTION" ), selTab );
+
+  addPreference( tr( "PREF_OBJECT_COLOR" ), selGroup, SalomeApp_Preferences::Color, "SMESH", "selection_object_color" );
+  addPreference( tr( "PREF_ELEMENT_COLOR" ), selGroup, SalomeApp_Preferences::Color, "SMESH", "selection_element_color" );
+  int selW = addPreference( tr( "PREF_WIDTH" ), selGroup, SalomeApp_Preferences::IntSpin, "SMESH", "selection_width" );
+  
+  setPreferenceProperty( selW, "min", 1 );
+  setPreferenceProperty( selW, "max", 5 );
+  
+  int preGroup = addPreference( tr( "PREF_GROUP_PRESELECTION" ), selTab );
+
+  addPreference( tr( "PREF_HIGHLIGHT_COLOR" ), preGroup, SalomeApp_Preferences::Color, "SMESH", "highlight_color" );
+  int preW = addPreference( tr( "PREF_WIDTH" ), preGroup, SalomeApp_Preferences::IntSpin, "SMESH", "highlight_width" );
+
+  setPreferenceProperty( preW, "min", 1 );
+  setPreferenceProperty( preW, "max", 5 );
+
+  int precSelGroup = addPreference( tr( "PREF_GROUP_PRECISION" ), selTab );
+
+  addPreference( tr( "PREF_NODES" ), precSelGroup, SalomeApp_Preferences::Double, "SMESH", "selection_precision_node" );
+  addPreference( tr( "PREF_ELEMENTS" ), precSelGroup, SalomeApp_Preferences::Double, "SMESH", "selection_precision_element" );
+
+  int sbarTab = addPreference( tr( "SMESH_SCALARBAR" ) );
+  int fontGr = addPreference( tr( "SMESH_FONT_SCALARBAR" ), sbarTab );
+
+  int tfont = addPreference( tr( "SMESH_TITLE" ), fontGr, SalomeApp_Preferences::Font, "SMESH", "scalar_bar_title_font" );
+  addPreference( tr( "SMESH_TITLE" ), fontGr, SalomeApp_Preferences::Color, "SMESH", "scalar_bar_title_color" );
+  int lfont = addPreference( tr( "SMESH_LABELS" ), fontGr, SalomeApp_Preferences::Font, "SMESH", "scalar_bar_label_font" );
+  addPreference( tr( "SMESH_LABELS" ), fontGr, SalomeApp_Preferences::Color, "SMESH", "scalar_bar_label_color" );
+
+  QStringList fam;
+  fam.append( tr( "SMESH_FONT_ARIAL" ) );
+  fam.append( tr( "SMESH_FONT_COURIER" ) );
+  fam.append( tr( "SMESH_FONT_TIMES" ) );
+  int wflag = ( QtxListResourceEdit::FontItem::All & ( ~( QtxListResourceEdit::FontItem::Size | QtxListResourceEdit::FontItem::UserSize ) ) );
+
+  setPreferenceProperty( tfont, "families", fam );
+  setPreferenceProperty( tfont, "system", false );
+  setPreferenceProperty( tfont, "widget_flags", wflag );  
+  setPreferenceProperty( lfont, "families", fam );
+  setPreferenceProperty( lfont, "system", false );
+  setPreferenceProperty( lfont, "widget_flags", wflag );
+  
+  int colorsLabelsGr = addPreference( tr( "SMESH_LABELS_COLORS_SCALARBAR" ), sbarTab );
+
+  int numcol = addPreference( tr( "SMESH_NUMBEROFCOLORS" ), colorsLabelsGr, SalomeApp_Preferences::IntSpin, "SMESH", "scalar_bar_num_colors" );
+  setPreferenceProperty( numcol, "min", 2 );
+  setPreferenceProperty( numcol, "max", 256 );  
+  
+  int numlab = addPreference( tr( "SMESH_NUMBEROFLABELS" ), colorsLabelsGr, SalomeApp_Preferences::IntSpin, "SMESH", "scalar_bar_num_labels" );
+  setPreferenceProperty( numlab, "min", 2 );
+  setPreferenceProperty( numlab, "max", 65 );
+
+  int orientGr = addPreference( tr( "SMESH_ORIENTATION" ), sbarTab );
+  int orient = addPreference( tr( "SMESH_ORIENTATION" ), orientGr, SalomeApp_Preferences::Selector, "SMESH", "scalar_bar_orientation" );
+  QStringList orients;
+  orients.append( tr( "SMESH_VERTICAL" ) );
+  orients.append( tr( "SMESH_HORIZONTAL" ) );
+  indices.clear(); indices.append( 0 ); indices.append( 1 );
+  setPreferenceProperty( orient, "strings", orients );
+  setPreferenceProperty( orient, "indexes", indices );
+  
+  int posVSizeGr = addPreference( tr( "SMESH_POSITION_SIZE_SCALARBAR" ) + " " + tr( "SMESH_VERTICAL" ), sbarTab );
+  int xv = addPreference( tr( "SMESH_X_SCALARBAR" ), posVSizeGr, SalomeApp_Preferences::DblSpin, "SMESH", "scalar_bar_vertical_x" );
+  int yv = addPreference( tr( "SMESH_Y_SCALARBAR" ), posVSizeGr, SalomeApp_Preferences::DblSpin, "SMESH", "scalar_bar_vertical_y" );  
+  int wv = addPreference( tr( "SMESH_WIDTH" ), posVSizeGr, SalomeApp_Preferences::DblSpin, "SMESH", "scalar_bar_vertical_width" );
+  int hv = addPreference( tr( "SMESH_HEIGHT" ), posVSizeGr, SalomeApp_Preferences::DblSpin, "SMESH", "scalar_bar_vertical_height" );
+  setPreferenceProperty( xv, "step", 0.1 );
+  setPreferenceProperty( xv, "min", 0.0 );
+  setPreferenceProperty( xv, "max", 1.0 );
+  setPreferenceProperty( yv, "step", 0.1 );
+  setPreferenceProperty( yv, "min", 0.0 );
+  setPreferenceProperty( yv, "max", 1.0 );
+  setPreferenceProperty( wv, "step", 0.1 );
+  setPreferenceProperty( wv, "min", 0.0 );
+  setPreferenceProperty( wv, "max", 1.0 );
+  setPreferenceProperty( hv, "min", 0.0 );
+  setPreferenceProperty( hv, "max", 1.0 );
+  setPreferenceProperty( hv, "step", 0.1 );    
+
+  int posHSizeGr = addPreference( tr( "SMESH_POSITION_SIZE_SCALARBAR" ) + " " + tr( "SMESH_HORIZONTAL" ), sbarTab );
+  int xh = addPreference( tr( "SMESH_X_SCALARBAR" ), posHSizeGr, SalomeApp_Preferences::DblSpin, "SMESH", "scalar_bar_horizontal_x" );
+  int yh = addPreference( tr( "SMESH_Y_SCALARBAR" ), posHSizeGr, SalomeApp_Preferences::DblSpin, "SMESH", "scalar_bar_horizontal_y" );
+  int wh = addPreference( tr( "SMESH_WIDTH" ), posHSizeGr, SalomeApp_Preferences::DblSpin, "SMESH", "scalar_bar_horizontal_width" );
+  int hh = addPreference( tr( "SMESH_HEIGHT" ), posHSizeGr, SalomeApp_Preferences::DblSpin, "SMESH", "scalar_bar_horizontal_height" );
+  setPreferenceProperty( xv, "min", 0.0 );
+  setPreferenceProperty( xv, "max", 1.0 );
+  setPreferenceProperty( xv, "step", 0.1 );
+  setPreferenceProperty( xh, "min", 0.0 );
+  setPreferenceProperty( xh, "max", 1.0 );
+  setPreferenceProperty( xh, "step", 0.1 );
+  setPreferenceProperty( yh, "min", 0.0 );
+  setPreferenceProperty( yh, "max", 1.0 );
+  setPreferenceProperty( yh, "step", 0.1 );
+  setPreferenceProperty( wh, "min", 0.0 );
+  setPreferenceProperty( wh, "max", 1.0 );
+  setPreferenceProperty( wh, "step", 0.1 );
+  setPreferenceProperty( hh, "min", 0.0 );
+  setPreferenceProperty( hh, "max", 1.0 );
+  setPreferenceProperty( hh, "step", 0.1 );
+}
+
+void SMESHGUI::preferencesChanged( const QString& sect, const QString& name )
+{
+}
+
+//================================================================================
+/*!
+ * \brief Update something in accordance with update flags
+  * \param theFlags - update flags
+*
+* Update viewer or/and object browser etc. in accordance with update flags ( see
+* SalomeApp_UpdateFlags enumeration ). 
+*/
+//================================================================================
+void SMESHGUI::update( const int flags )
+{
+  if ( flags & UF_Viewer | flags & UF_Forced )
+    SMESH::UpdateView();
+  else
+    SalomeApp_Module::update( flags );
+}
+
+//================================================================================
+/*!
+ * \brief Set default selection mode
+*
+* SLOT called when operation commited. Sets default selection mode
+*/
+//================================================================================
+void SMESHGUI::onOperationCommited( SUIT_Operation* )
+{
+  SVTK_ViewWindow* vtkWnd =
+    dynamic_cast<SVTK_ViewWindow*>( application()->desktop()->activeWindow() );
+  if ( vtkWnd )
+    vtkWnd->SetSelectionMode( ActorSelection );
+}
+
+//================================================================================
+/*!
+ * \brief Set default selection mode
+*
+* SLOT called when operation aborted. Sets default selection mode
+*/
+//================================================================================
+void SMESHGUI::onOperationAborted( SUIT_Operation* )
+{
+  SVTK_ViewWindow* vtkWnd =
+    dynamic_cast<SVTK_ViewWindow*>( application()->desktop()->activeWindow() );
+  if ( vtkWnd )
+    vtkWnd->SetSelectionMode( ActorSelection );
+}
+
+//================================================================================
+/*!
+ * \brief Creates operation with given identifier
+  * \param id - identifier of operation to be started
+  * \return Pointer on created operation or NULL if operation is not created
+*
+* Virtual method redefined from the base class creates operation with given id. 
+* It is called called automatically from startOperation method of base class. 
+*/
+//================================================================================
+SalomeApp_Operation* SMESHGUI::createOperation( const int id ) const
+{
+  SalomeApp_Operation* op = 0;
+  // to do : create operation here
+  switch( id )
+  {
+    case 702: // Create mesh
+      op = new SMESHGUI_MeshOp( true, true );
+    break;
+    case 703: // Create sub-mesh
+      op = new SMESHGUI_MeshOp( true, false );
+    break;
+    case 704: // Edit mesh/sub-mesh
+      op = new SMESHGUI_MeshOp( false );
+    break;
+    default:
+    break;
+  }
+  
+  return op;
+}
+
+
+
+
+
+
+
+
diff --git a/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx b/src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx
new file mode 100644 (file)
index 0000000..c2d0185
--- /dev/null
@@ -0,0 +1,963 @@
+//  SMESH SMESHGUI : GUI for SMESH component
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+//  File   : SMESHGUI_EditHypothesesDlg.cxx
+//  Author : Nicolas REJNERI
+//  Module : SMESH
+//  $Header$
+
+#include "SMESHGUI_EditHypothesesDlg.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_GEOMGenUtils.h"
+#include "SMESHGUI_HypothesesUtils.h"
+
+#include "SMESH_TypeFilter.hxx"
+#include "SMESH_NumberFilter.hxx"
+
+#include "SALOME_ListIO.hxx"
+#include "SALOME_ListIteratorOfListIO.hxx"
+
+#include "SALOMEDSClient_Study.hxx"
+#include "SALOMEDSClient_AttributeIOR.hxx"
+#include "SALOMEDSClient_AttributeName.hxx"
+
+#include "SUIT_Session.h"
+#include "SUIT_OverrideCursor.h"
+#include "SUIT_Operation.h"
+#include "SUIT_Desktop.h"
+
+#include "utilities.h"
+
+#include "SVTK_ViewModel.h"
+
+// QT Includes
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qpixmap.h>
+
+using namespace std;
+
+//VRV: porting on Qt 3.0.5
+#if QT_VERSION >= 0x030005
+#include <qlistbox.h>
+#endif
+//VRV: porting on Qt 3.0.5
+
+class ListBoxIOR : public QListBoxText
+{
+public:
+  enum { RTTI_IOR = 1000 };
+
+public:
+  ListBoxIOR (QListBox* listbox,
+              const char* ior,
+              const QString& text = QString::null)
+  : QListBoxText(listbox, text), myIOR(ior) {}
+  virtual ~ListBoxIOR() {};
+  virtual int rtti() const { return RTTI_IOR; }
+  const char* GetIOR() { return myIOR.c_str(); }
+
+private:
+  string myIOR;
+};
+
+#define ALLOW_CHANGE_SHAPE 0
+
+int findItem (QListBox* listBox, const string& ior)
+{
+  for (int i = 0; i < listBox->count(); i++) {
+    if (listBox->item(i)->rtti() == ListBoxIOR::RTTI_IOR) {
+      ListBoxIOR* anItem = (ListBoxIOR*)(listBox->item(i));
+      if (anItem && ior == string(anItem->GetIOR()))
+       return i;
+    }
+  }
+  return -1;
+}
+
+//=================================================================================
+// function : SMESHGUI_EditHypothesesDlg()
+// purpose  : Constructs a SMESHGUI_EditHypothesesDlg which is a child of 'parent', with the
+//            name 'name' and widget flags set to 'f'.
+//            The dialog will by default be modeless, unless you set 'modal' to
+//            TRUE to construct a modal dialog.
+//=================================================================================
+SMESHGUI_EditHypothesesDlg::SMESHGUI_EditHypothesesDlg (SMESHGUI* theModule, const char* name,
+                                                        bool modal, WFlags fl)
+     : QDialog( SMESH::GetDesktop( theModule ), name, modal, WStyle_Customize | WStyle_NormalBorder |
+                WStyle_Title | WStyle_SysMenu | WDestructiveClose),
+    myImportedMesh(false),
+    mySMESHGUI( theModule ),
+    mySelectionMgr( SMESH::GetSelectionMgr( theModule ) )
+{
+    QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
+    if (!name)
+      setName("SMESHGUI_EditHypothesesDlg");
+    setCaption(tr("SMESH_EDIT_HYPOTHESES"));
+    setSizeGripEnabled(TRUE);
+    QGridLayout* SMESHGUI_EditHypothesesDlgLayout = new QGridLayout(this);
+    SMESHGUI_EditHypothesesDlgLayout->setSpacing(6);
+    SMESHGUI_EditHypothesesDlgLayout->setMargin(11);
+
+    /***************************************************************/
+    GroupC1 = new QGroupBox(tr("SMESH_ARGUMENTS"), this, "GroupC1");
+    GroupC1->setColumnLayout(0, Qt::Vertical);
+    GroupC1->layout()->setSpacing(0);
+    GroupC1->layout()->setMargin(0);
+    QGridLayout* GroupC1Layout = new QGridLayout(GroupC1->layout());
+    GroupC1Layout->setAlignment(Qt::AlignTop);
+    GroupC1Layout->setSpacing(6);
+    GroupC1Layout->setMargin(11);
+
+    TextLabelC1A1 = new QLabel(tr("SMESH_OBJECT_MESHorSUBMESH"), GroupC1, "TextLabelC1A1");
+    GroupC1Layout->addWidget(TextLabelC1A1, 0, 0);
+    SelectButtonC1A1 = new QPushButton(GroupC1, "SelectButtonC1A1");
+    SelectButtonC1A1->setPixmap(image0);
+    GroupC1Layout->addWidget(SelectButtonC1A1, 0, 1);
+    LineEditC1A1 = new QLineEdit(GroupC1, "LineEditC1A1");
+    LineEditC1A1->setReadOnly(true);
+    GroupC1Layout->addWidget(LineEditC1A1, 0, 2);
+
+    TextLabelC1A2 = new QLabel(tr("SMESH_OBJECT_GEOM"), GroupC1, "TextLabelC1A2");
+    GroupC1Layout->addWidget(TextLabelC1A2, 1, 0);
+    SelectButtonC1A2 = new QPushButton(GroupC1, "SelectButtonC1A2");
+    SelectButtonC1A2->setPixmap(image0);
+    SelectButtonC1A2->setToggleButton(FALSE);
+    GroupC1Layout->addWidget(SelectButtonC1A2, 1, 1);
+    LineEditC1A2 = new QLineEdit(GroupC1, "LineEditC1A2");
+    LineEditC1A2->setReadOnly(true);
+    GroupC1Layout->addWidget(LineEditC1A2, 1, 2);
+
+    SMESHGUI_EditHypothesesDlgLayout->addWidget(GroupC1, 0, 0);
+
+    /***************************************************************/
+    GroupHypotheses = new QGroupBox(tr("SMESH_HYPOTHESES"), this, "GroupHypotheses");
+    GroupHypotheses->setColumnLayout(0, Qt::Vertical);
+    GroupHypotheses->layout()->setSpacing(0);
+    GroupHypotheses->layout()->setMargin(0);
+    QGridLayout* grid_3 = new QGridLayout(GroupHypotheses->layout());
+    grid_3->setAlignment(Qt::AlignTop);
+    grid_3->setSpacing(6);
+    grid_3->setMargin(11);
+
+    TextHypDefinition = new QLabel(tr("SMESH_AVAILABLE"), GroupHypotheses, "TextHypDefinition");
+    grid_3->addWidget(TextHypDefinition, 0, 0);
+
+    ListHypDefinition = new QListBox(GroupHypotheses, "ListHypDefinition");
+    ListHypDefinition->setMinimumSize(100, 100);
+    grid_3->addWidget(ListHypDefinition, 1, 0);
+
+    TextHypAssignation = new QLabel(tr("SMESH_EDIT_USED"), GroupHypotheses, "TextHypAssignation");
+    grid_3->addWidget(TextHypAssignation, 0, 1);
+
+    ListHypAssignation = new QListBox(GroupHypotheses, "ListHypAssignation");
+    ListHypAssignation->setMinimumSize(100, 100);
+    grid_3->addWidget(ListHypAssignation, 1, 1);
+
+    SMESHGUI_EditHypothesesDlgLayout->addWidget(GroupHypotheses, 1, 0);
+
+    /***************************************************************/
+    GroupAlgorithms = new QGroupBox(tr("SMESH_ADD_ALGORITHM"), this, "GroupAlgorithms");
+    GroupAlgorithms->setColumnLayout(0, Qt::Vertical);
+    GroupAlgorithms->layout()->setSpacing(0);
+    GroupAlgorithms->layout()->setMargin(0);
+    QGridLayout* grid_4 = new QGridLayout(GroupAlgorithms->layout());
+    grid_4->setAlignment(Qt::AlignTop);
+    grid_4->setSpacing(6);
+    grid_4->setMargin(11);
+
+    TextAlgoDefinition = new QLabel(tr("SMESH_AVAILABLE"), GroupAlgorithms, "TextAlgoDefinition");
+    grid_4->addWidget(TextAlgoDefinition, 0, 0);
+
+    ListAlgoDefinition = new QListBox(GroupAlgorithms, "ListAlgoDefinition");
+    ListAlgoDefinition->setMinimumSize(100, 100);
+    grid_4->addWidget(ListAlgoDefinition, 1, 0);
+
+    TextAlgoAssignation = new QLabel(tr("SMESH_EDIT_USED"), GroupAlgorithms, "TextAlgoAssignation");
+    grid_4->addWidget(TextAlgoAssignation, 0, 1);
+
+    ListAlgoAssignation = new QListBox(GroupAlgorithms, "ListAlgoAssignation");
+    ListAlgoAssignation ->setMinimumSize(100, 100);
+    grid_4->addWidget(ListAlgoAssignation, 1, 1);
+
+    SMESHGUI_EditHypothesesDlgLayout->addWidget(GroupAlgorithms, 2, 0);
+
+    /***************************************************************/
+    GroupButtons = new QGroupBox(this, "GroupButtons");
+    GroupButtons->setColumnLayout(0, Qt::Vertical);
+    GroupButtons->layout()->setSpacing(0);
+    GroupButtons->layout()->setMargin(0);
+    QGridLayout* GroupButtonsLayout = new QGridLayout(GroupButtons->layout());
+    GroupButtonsLayout->setAlignment(Qt::AlignTop);
+    GroupButtonsLayout->setSpacing(6);
+    GroupButtonsLayout->setMargin(11);
+
+    buttonOk = new QPushButton(tr("SMESH_BUT_OK"), GroupButtons, "buttonOk");
+    buttonOk->setAutoDefault(TRUE);
+    buttonOk->setDefault(FALSE);
+    GroupButtonsLayout->addWidget(buttonOk, 0, 0);
+
+    buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons, "buttonApply");
+    buttonApply->setAutoDefault(TRUE);
+    buttonApply->setDefault(FALSE);
+    GroupButtonsLayout->addWidget(buttonApply, 0, 1);
+
+    GroupButtonsLayout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 2);
+
+    buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons, "buttonCancel");
+    buttonCancel->setAutoDefault(TRUE);
+    buttonCancel->setDefault(TRUE);
+    buttonCancel->setEnabled(TRUE);
+    GroupButtonsLayout->addWidget(buttonCancel, 0, 3);
+
+    SMESHGUI_EditHypothesesDlgLayout->addWidget(GroupButtons, 4, 0);
+
+    /***************************************************************/
+    Init();
+}
+
+//=================================================================================
+// function : ~SMESHGUI_EditHypothesesDlg()
+// purpose  : Destroys the object and frees any allocated resources
+//=================================================================================
+SMESHGUI_EditHypothesesDlg::~SMESHGUI_EditHypothesesDlg()
+{
+  // no need to delete child widgets, Qt does it all for us
+}
+
+//=================================================================================
+// function : Init()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditHypothesesDlg::Init()
+{
+  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+
+  InitHypDefinition();
+  InitAlgoDefinition();
+
+  //myGeomFilter = new SALOME_TypeFilter ("GEOM");
+  TColStd_MapOfInteger allTypesMap;
+  for (int i = 0; i < 10; i++)
+    allTypesMap.Add(i);
+  myGeomFilter          = new SMESH_NumberFilter ("GEOM", TopAbs_SHAPE, 0, allTypesMap);
+  myMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH);
+
+  myGeomShape = GEOM::GEOM_Object::_nil();
+  myMesh = SMESH::SMESH_Mesh::_nil();
+  mySubMesh = SMESH::SMESH_subMesh::_nil();
+
+  /* signals and slots connections */
+  connect(buttonOk,     SIGNAL(clicked()), this, SLOT(ClickOnOk()));
+  connect(buttonApply,  SIGNAL(clicked()), this, SLOT(ClickOnApply()));
+  connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
+
+  connect(SelectButtonC1A1, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument()));
+  connect(SelectButtonC1A2, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument()));
+
+  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()),      this, SLOT(SelectionIntoArgument()));
+  connect(mySMESHGUI,     SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
+  connect(mySMESHGUI,     SIGNAL(SignalCloseAllDialogs()),        this, SLOT(ClickOnCancel()));
+
+  connect(ListHypAssignation,  SIGNAL(doubleClicked(QListBoxItem*)), this, SLOT(removeItem(QListBoxItem*)));
+  connect(ListAlgoAssignation, SIGNAL(doubleClicked(QListBoxItem*)), this, SLOT(removeItem(QListBoxItem*)));
+
+  connect(ListHypDefinition,  SIGNAL(doubleClicked(QListBoxItem*)), this, SLOT(addItem(QListBoxItem*)));
+  connect(ListAlgoDefinition, SIGNAL(doubleClicked(QListBoxItem*)), this, SLOT(addItem(QListBoxItem*)));
+
+  int x, y;
+  mySMESHGUI->DefineDlgPosition(this, x, y);
+  this->move(x, y);
+  this->show();
+
+  LineEditC1A1->setFocus();
+  myEditCurrentArgument = LineEditC1A1;
+  mySelectionMgr->clearFilters();
+  mySelectionMgr->installFilter(myMeshOrSubMeshFilter);
+
+  SelectionIntoArgument();
+
+  UpdateControlState();
+}
+
+//=================================================================================
+// function : ClickOnOk()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditHypothesesDlg::ClickOnOk()
+{
+  if (ClickOnApply())
+    ClickOnCancel();
+}
+
+//=================================================================================
+// function : ClickOnApply()
+// purpose  :
+//=================================================================================
+bool SMESHGUI_EditHypothesesDlg::ClickOnApply()
+{
+  if (mySMESHGUI->isActiveStudyLocked())
+    return false;
+
+  bool aRes = false;
+
+  SUIT_OverrideCursor wc;
+
+  SUIT_Operation* op = new SUIT_Operation
+    (SUIT_Session::session()->activeApplication());
+
+  // start transaction
+  op->start();
+
+  if (!myMesh->_is_nil())
+    aRes = StoreMesh();
+  else if (!mySubMesh->_is_nil())
+    aRes = StoreSubMesh();
+
+  if (true/*aRes*/) { // abort desynchronizes contents of a Study and a mesh on server
+    // commit transaction
+    op->commit();
+    InitHypAssignation();
+    InitAlgoAssignation();
+  } else {
+    // abort transaction
+    op->abort();
+  }
+
+  UpdateControlState();
+  mySMESHGUI->updateObjBrowser();
+
+  return aRes;
+}
+
+//=================================================================================
+// function : ClickOnCancel()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditHypothesesDlg::ClickOnCancel()
+{
+  close();
+}
+
+//=================================================================================
+// function : SelectionIntoArgument()
+// purpose  : Called when selection as changed or other case
+//=================================================================================
+void SMESHGUI_EditHypothesesDlg::SelectionIntoArgument()
+{
+  QString aString = "";
+
+  SALOME_ListIO aList;
+  mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
+
+  int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
+
+  if (myEditCurrentArgument == LineEditC1A1) {
+    if (nbSel != 1) {
+      myMesh    = SMESH::SMESH_Mesh::_nil();
+      mySubMesh = SMESH::SMESH_subMesh::_nil();
+      aString   = "";
+    } else {
+      Handle(SALOME_InteractiveObject) IO = aList.First();
+      myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
+      if (myMesh->_is_nil()) {
+       mySubMesh = SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO);
+       if (mySubMesh->_is_nil()) {
+         aString = "";
+       }
+      }
+    }
+    myEditCurrentArgument->setText(aString);
+
+    // InitGeom() will try to retrieve a shape from myMesh or mySubMesh
+    myGeomShape = GEOM::GEOM_Object::_nil();
+    InitGeom();
+
+    myImportedMesh = myGeomShape->_is_nil();
+
+    InitHypAssignation();
+    InitAlgoAssignation();
+
+  } else if (myEditCurrentArgument == LineEditC1A2) {
+    if (nbSel != 1) {
+      myGeomShape = GEOM::GEOM_Object::_nil();
+    } else {
+      Handle(SALOME_InteractiveObject) IO = aList.First();
+      myGeomShape = SMESH::IObjectToInterface<GEOM::GEOM_Object>(IO);
+    }
+    InitGeom();
+  }
+
+  UpdateControlState();
+}
+
+//=================================================================================
+// function : SetEditCurrentArgument()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditHypothesesDlg::SetEditCurrentArgument()
+{
+  QPushButton* send = (QPushButton*)sender();
+  if(send == SelectButtonC1A1) {
+    LineEditC1A1->setFocus();
+    myEditCurrentArgument = LineEditC1A1;
+    mySelectionMgr->clearFilters();
+    mySelectionMgr->installFilter(myMeshOrSubMeshFilter);
+  } else if (send == SelectButtonC1A2) {
+    LineEditC1A2->setFocus();
+    myEditCurrentArgument = LineEditC1A2;
+    mySelectionMgr->clearFilters();
+    mySelectionMgr->installFilter(myGeomFilter);
+  }
+  SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : DeactivateActiveDialog()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditHypothesesDlg::DeactivateActiveDialog()
+{
+  if (GroupC1->isEnabled()) {
+    disconnect(mySelectionMgr, 0, this, 0);
+    GroupC1->setEnabled(false);
+    GroupButtons->setEnabled(false);
+  }
+}
+
+//=================================================================================
+// function : ActivateThisDialog()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditHypothesesDlg::ActivateThisDialog()
+{
+  mySMESHGUI->EmitSignalDeactivateDialog();
+  GroupC1->setEnabled(true);
+  GroupButtons->setEnabled(true);
+  connect (mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+}
+
+//=================================================================================
+// function : enterEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditHypothesesDlg::enterEvent (QEvent*)
+{
+  if (!GroupC1->isEnabled())
+    ActivateThisDialog();
+}
+
+//=================================================================================
+// function : closeEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditHypothesesDlg::closeEvent (QCloseEvent* e)
+{
+  disconnect(mySelectionMgr, 0, this, 0);
+  mySMESHGUI->ResetState();
+  mySelectionMgr->clearFilters();
+  QDialog::closeEvent(e);
+}
+
+//=======================================================================
+// function : IsOld()
+// purpose  :
+//=======================================================================
+bool SMESHGUI_EditHypothesesDlg::IsOld (QListBoxItem* hypItem)
+{
+  if (hypItem->rtti() == ListBoxIOR::RTTI_IOR) {
+    ListBoxIOR* hyp = (ListBoxIOR*) hypItem;
+    return (myMapOldHypos.find(hyp->GetIOR()) != myMapOldHypos.end() ||
+            myMapOldAlgos.find(hyp->GetIOR()) != myMapOldAlgos.end());
+  }
+
+  return false;
+}
+
+//=================================================================================
+// function : removeItem()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditHypothesesDlg::removeItem (QListBoxItem* item)
+{
+  const QObject* aSender = sender();
+
+  if (!item) return;
+
+  if (aSender == ListHypAssignation) {
+    myNbModification += IsOld(item) ? 1 : -1;
+    ListHypAssignation->removeItem(ListHypAssignation->index(item));
+  }
+  else if (aSender == ListAlgoAssignation) {
+    myNbModification += IsOld(item) ? 1 : -1;
+    ListAlgoAssignation->removeItem(ListAlgoAssignation->index(item));
+  }
+
+  UpdateControlState();
+}
+
+//=================================================================================
+// function : addItem()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditHypothesesDlg::addItem (QListBoxItem* item)
+{
+  const QObject* aSender = sender();
+
+  if (!item) return;
+
+  ListBoxIOR* i = 0;
+  if (item->rtti() == ListBoxIOR::RTTI_IOR)
+    i = (ListBoxIOR*)item;
+  if (!i) return;
+
+  bool isFound = false;
+
+  ListBoxIOR* anItem;
+  if (aSender == ListHypDefinition) {
+    for (int j = 0, n = ListHypAssignation->count(); !isFound && j < n; j++) {
+      if (ListHypAssignation->item(j)->rtti() == ListBoxIOR::RTTI_IOR) {
+       anItem = (ListBoxIOR*)ListHypAssignation->item(j);
+       isFound = !strcmp(anItem->GetIOR(), i->GetIOR());
+      }
+    }
+    if (!isFound)
+      anItem = new ListBoxIOR (ListHypAssignation,
+                               CORBA::string_dup(i->GetIOR()),
+                               CORBA::string_dup(i->text().latin1()));
+
+  } else if (aSender == ListAlgoDefinition) {
+    for (int j = 0, n = ListAlgoAssignation->count(); !isFound && j < n; j++) {
+      if (ListAlgoAssignation->item(j)->rtti() == ListBoxIOR::RTTI_IOR) {
+       anItem = (ListBoxIOR*)ListAlgoAssignation->item(j);
+       isFound = !strcmp(anItem->GetIOR(), i->GetIOR());
+      }
+    }
+    if (!isFound)
+      anItem = new ListBoxIOR (ListAlgoAssignation,
+                               CORBA::string_dup(i->GetIOR()),
+                               CORBA::string_dup(i->text().latin1()));
+  } else {
+  }
+
+  if (!isFound)
+    myNbModification += IsOld(item) ? -1 : 1;
+
+  UpdateControlState();
+}
+
+//=================================================================================
+// function : InitHypDefinition()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditHypothesesDlg::InitHypDefinition()
+{
+  ListHypDefinition->clear();
+
+  _PTR(SComponent) father = SMESH::GetActiveStudyDocument()->FindComponent("SMESH");
+  if (!father)
+    return;
+
+  _PTR(SObject)          HypothesisRoot;
+  _PTR(GenericAttribute) anAttr;
+  _PTR(AttributeName)    aName;
+  _PTR(AttributeIOR)     anIOR;
+
+  //int Tag_HypothesisRoot = 1;
+  if (father->FindSubObject(1, HypothesisRoot)) {
+    _PTR(ChildIterator) it =
+      SMESH::GetActiveStudyDocument()->NewChildIterator(HypothesisRoot);
+    ListBoxIOR* anItem;
+    for (; it->More();it->Next()) {
+      _PTR(SObject) Obj = it->Value();
+      if (Obj->FindAttribute(anAttr, "AttributeName")) {
+        aName = anAttr;
+        if (Obj->FindAttribute(anAttr, "AttributeIOR")) {
+          anIOR = anAttr;
+          anItem = new ListBoxIOR (ListHypDefinition,
+                                   anIOR->Value().c_str(),
+                                   aName->Value().c_str());
+        }
+      }
+    }
+  }
+}
+
+//=================================================================================
+// function : InitHypAssignation()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditHypothesesDlg::InitHypAssignation()
+{
+  myNbModification = 0;
+
+  myMapOldHypos.clear();
+  ListHypAssignation->clear();
+  if (myImportedMesh)
+    return;
+
+  _PTR(SObject)          aMorSM, AHR, aRef;
+  _PTR(GenericAttribute) anAttr;
+  _PTR(AttributeName)    aName;
+  _PTR(AttributeIOR)     anIOR;
+
+  if (!myMesh->_is_nil())
+    aMorSM = SMESH::FindSObject(myMesh);
+  else if (!mySubMesh->_is_nil())
+    aMorSM = SMESH::FindSObject(mySubMesh);
+
+  if (aMorSM && aMorSM->FindSubObject(2, AHR)) {
+    _PTR(ChildIterator) it =
+      SMESH::GetActiveStudyDocument()->NewChildIterator(AHR);
+    for (; it->More();it->Next()) {
+      _PTR(SObject) Obj = it->Value();
+      if (Obj->ReferencedObject(aRef)) {
+        if (aRef->FindAttribute(anAttr, "AttributeName")) {
+          aName = anAttr;
+         if (aRef->FindAttribute(anAttr, "AttributeIOR")) {
+            anIOR = anAttr;
+           ListBoxIOR* anItem = new ListBoxIOR (ListHypAssignation,
+                                                anIOR->Value().c_str(),
+                                                aName->Value().c_str());
+           myMapOldHypos[ anIOR->Value() ] = ListHypAssignation->index(anItem);
+         }
+       }
+      }
+    }
+  }
+}
+
+//=================================================================================
+// function : InitAlgoDefinition()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditHypothesesDlg::InitAlgoDefinition()
+{
+  ListAlgoDefinition->clear();
+
+  _PTR(SComponent) father = SMESH::GetActiveStudyDocument()->FindComponent("SMESH");
+  if (!father)
+    return;
+
+  _PTR(SObject)          AlgorithmsRoot;
+  _PTR(GenericAttribute) anAttr;
+  _PTR(AttributeName)    aName;
+  _PTR(AttributeIOR)     anIOR;
+
+  if (father->FindSubObject (2, AlgorithmsRoot)) {
+    _PTR(ChildIterator) it =
+      SMESH::GetActiveStudyDocument()->NewChildIterator(AlgorithmsRoot);
+    ListBoxIOR* anItem;
+    for (; it->More();it->Next()) {
+      _PTR(SObject) Obj = it->Value();
+      if (Obj->FindAttribute(anAttr, "AttributeName")) {
+        aName = anAttr;
+        if (Obj->FindAttribute(anAttr, "AttributeIOR")) {
+          anIOR = anAttr;
+          anItem = new ListBoxIOR (ListAlgoDefinition,
+                                   anIOR->Value().c_str(),
+                                   aName->Value().c_str());
+        }
+      }
+    }
+  }
+}
+
+//=================================================================================
+// function : InitAlgoAssignation()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditHypothesesDlg::InitAlgoAssignation()
+{
+  myMapOldAlgos.clear();
+  ListAlgoAssignation->clear();
+  if (myImportedMesh)
+    return;
+
+  _PTR(SObject)          aMorSM, AHR, aRef;
+  _PTR(GenericAttribute) anAttr;
+  _PTR(AttributeName)    aName;
+  _PTR(AttributeIOR)     anIOR;
+
+  if (!myMesh->_is_nil())
+    aMorSM = SMESH::FindSObject(myMesh);
+  else if (!mySubMesh->_is_nil())
+    aMorSM = SMESH::FindSObject(mySubMesh);
+
+  if (aMorSM && aMorSM->FindSubObject(3, AHR)) {
+    _PTR(ChildIterator) it =
+      SMESH::GetActiveStudyDocument()->NewChildIterator(AHR);
+    for (; it->More();it->Next()) {
+      _PTR(SObject) Obj = it->Value();
+      if (Obj->ReferencedObject(aRef)) {
+        if (aRef->FindAttribute(anAttr, "AttributeName")) {
+         aName = anAttr;
+         if (aRef->FindAttribute(anAttr, "AttributeIOR")) {
+           anIOR = anAttr;
+           ListBoxIOR* anItem = new ListBoxIOR (ListAlgoAssignation,
+                                                anIOR->Value().c_str(),
+                                                aName->Value().c_str());
+           myMapOldAlgos[ anIOR->Value() ] = ListAlgoAssignation->index(anItem);
+         }
+       }
+      }
+    }
+  }
+}
+
+//=================================================================================
+// function : InitGeom()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditHypothesesDlg::InitGeom()
+{
+  LineEditC1A2->setText("");
+
+  if (myGeomShape->_is_nil() && !myMesh->_is_nil()) {
+    _PTR(SObject) aMesh = SMESH::FindSObject(myMesh);
+    if (aMesh)
+      myGeomShape = SMESH::GetShapeOnMeshOrSubMesh(aMesh);
+  }
+  if (myGeomShape->_is_nil() && !mySubMesh->_is_nil()) {
+    _PTR(SObject) aSubMesh = SMESH::FindSObject(mySubMesh);
+    if (aSubMesh)
+      myGeomShape = SMESH::GetShapeOnMeshOrSubMesh(aSubMesh);
+  }
+
+  _PTR(GenericAttribute) anAttr;
+  _PTR(AttributeName)    aName;
+  if (!myGeomShape->_is_nil() && (!myMesh->_is_nil() || !mySubMesh->_is_nil())) {
+    _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+    //_PTR(SObject) aSO = aStudy->FindObjectIOR(aStudy->ConvertObjectToIOR(myGeomShape));
+    _PTR(SObject) aSO = aStudy->FindObjectID(myGeomShape->GetStudyEntry());
+    if (aSO) {
+      if (aSO->FindAttribute(anAttr, "AttributeName")) {
+       aName = anAttr;
+       LineEditC1A2->setText(QString(aName->Value().c_str()));
+      }
+    }
+  }
+}
+
+//=================================================================================
+// function : UpdateControlState()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditHypothesesDlg::UpdateControlState()
+{
+  // asl the check of "count" is commented because of PAL9787
+  bool isEnabled = (!myMesh->_is_nil() && !myGeomShape->_is_nil() /*&&
+                    ListHypAssignation->count() && ListAlgoAssignation->count()*/ )
+    ||
+      (!mySubMesh->_is_nil() && !myGeomShape->_is_nil() /*&&
+       (ListHypAssignation->count() || ListAlgoAssignation->count())*/);
+
+  buttonOk   ->setEnabled(myNbModification && isEnabled && !myImportedMesh);
+  buttonApply->setEnabled(myNbModification && isEnabled && !myImportedMesh);
+
+  SelectButtonC1A2   ->setEnabled(ALLOW_CHANGE_SHAPE && !myImportedMesh);
+  LineEditC1A2       ->setEnabled(ALLOW_CHANGE_SHAPE && !myImportedMesh);
+  ListHypDefinition  ->setEnabled(!myImportedMesh);
+  ListHypAssignation ->setEnabled(!myImportedMesh);
+  ListAlgoDefinition ->setEnabled(!myImportedMesh);
+  ListAlgoAssignation->setEnabled(!myImportedMesh);
+}
+
+//=================================================================================
+// function : StoreMesh()
+// purpose  :
+//=================================================================================
+bool SMESHGUI_EditHypothesesDlg::StoreMesh()
+{
+  MapIOR anOldHypos, aNewHypos;
+  if (myGeomShape->_is_nil())
+    return false;
+
+  // 1. Check whether the geometric shape has changed
+  _PTR(SObject) aMeshSO = SMESH::FindSObject(myMesh);
+  GEOM::GEOM_Object_var aIniGeomShape = SMESH::GetShapeOnMeshOrSubMesh(aMeshSO);
+  bool bShapeChanged = aIniGeomShape->_is_nil() ||
+                       !aIniGeomShape->_is_equivalent(myGeomShape);
+  if (bShapeChanged) {
+    // VSR : TODO : Set new shape - not supported yet by SMESH engine
+    // 1. remove all old hypotheses and algorithms and also submeshes
+    // 2. set new shape
+  }
+
+  int nbFail = 0;
+  MapIOR::iterator it;
+
+  // 2. remove not used hypotheses from the mesh
+  for (it = myMapOldHypos.begin(); it != myMapOldHypos.end(); ++it) {
+    string ior = it->first;
+    int index = findItem(ListHypAssignation, ior);
+    if (index < 0) {
+      SMESH::SMESH_Hypothesis_var aHyp =
+        SMESH::IORToInterface<SMESH::SMESH_Hypothesis>(ior.c_str());
+      if (!aHyp->_is_nil()) {
+       if (!SMESH::RemoveHypothesisOrAlgorithmOnMesh(aMeshSO, aHyp))
+         nbFail++;
+      }
+    }
+  }
+
+  // 3. remove not used algorithms from the mesh
+  for (it = myMapOldAlgos.begin(); it != myMapOldAlgos.end(); ++it) {
+    string ior = it->first;
+    int index = findItem(ListAlgoAssignation, ior);
+    if (index < 0) {
+      SMESH::SMESH_Hypothesis_var aHyp =
+        SMESH::IORToInterface<SMESH::SMESH_Hypothesis>(ior.c_str());
+      if (!aHyp->_is_nil()) {
+       if (!SMESH::RemoveHypothesisOrAlgorithmOnMesh(aMeshSO, aHyp))
+         nbFail++;
+      }
+    }
+  }
+
+  // 4. Add new algorithms
+  for (int i = 0; i < ListAlgoAssignation->count(); i++) {
+    if (ListAlgoAssignation->item(i)->rtti() == ListBoxIOR::RTTI_IOR) {
+      ListBoxIOR* anItem = (ListBoxIOR*)(ListAlgoAssignation->item(i));
+      if (anItem) {
+       string ior = anItem->GetIOR();
+       if (myMapOldAlgos.find(ior) == myMapOldAlgos.end()) {
+         SMESH::SMESH_Hypothesis_var aHyp =
+            SMESH::IORToInterface<SMESH::SMESH_Hypothesis>(ior.c_str());
+         if (!aHyp->_is_nil()) {
+           if (!SMESH::AddHypothesisOnMesh(myMesh, aHyp))
+             nbFail++;
+         }
+       }
+      }
+    }
+  }
+
+  // 5. Add new hypotheses
+  for (int i = 0; i < ListHypAssignation->count(); i++) {
+    if (ListHypAssignation->item(i)->rtti() == ListBoxIOR::RTTI_IOR) {
+      ListBoxIOR* anItem = (ListBoxIOR*)(ListHypAssignation->item(i));
+      if (anItem) {
+       string ior = anItem->GetIOR();
+       if (myMapOldHypos.find(ior) == myMapOldHypos.end()) {
+         SMESH::SMESH_Hypothesis_var aHyp =
+            SMESH::IORToInterface<SMESH::SMESH_Hypothesis>(ior.c_str());
+         if (!aHyp->_is_nil()) {
+           if (!SMESH::AddHypothesisOnMesh(myMesh, aHyp))
+             nbFail++;
+         }
+       }
+      }
+    }
+  }
+  return (nbFail == 0);
+}
+
+//=================================================================================
+// function : StoreSubMesh()
+// purpose  :
+//=================================================================================
+bool SMESHGUI_EditHypothesesDlg::StoreSubMesh()
+{
+  MapIOR anOldHypos, aNewHypos;
+  if (myGeomShape->_is_nil())
+    return false;
+
+  // 1. Check whether the geometric shape has changed
+  _PTR(SObject) aSubMeshSO = SMESH::FindSObject(mySubMesh);
+  GEOM::GEOM_Object_var aIniGeomShape = SMESH::GetShapeOnMeshOrSubMesh(aSubMeshSO);
+  bool bShapeChanged = aIniGeomShape->_is_nil() || !aIniGeomShape->_is_equivalent(myGeomShape);
+  if (bShapeChanged) {
+    // VSR : TODO : Set new shape - not supported yet by engine
+    // 1. remove all old hypotheses and algorithms
+    // 2. set new shape
+  }
+  int nbFail = 0;
+  MapIOR::iterator it;
+
+  // 2. remove not used hypotheses from the submesh
+  for (it = myMapOldHypos.begin(); it != myMapOldHypos.end(); ++it) {
+    string ior = it->first;
+    int index = findItem(ListHypAssignation, ior);
+    if (index < 0) {
+      SMESH::SMESH_Hypothesis_var aHyp = SMESH::IORToInterface<SMESH::SMESH_Hypothesis>(ior.c_str());
+      if (!aHyp->_is_nil()) {
+       if (!SMESH::RemoveHypothesisOrAlgorithmOnMesh(aSubMeshSO, aHyp))
+         nbFail++;
+      }
+    }
+  }
+
+  // 3. remove not used algorithms from the submesh
+  for (it = myMapOldAlgos.begin(); it != myMapOldAlgos.end(); ++it) {
+    string ior = it->first;
+    int index = findItem(ListAlgoAssignation, ior);
+    if (index < 0) {
+      SMESH::SMESH_Hypothesis_var aHyp = SMESH::IORToInterface<SMESH::SMESH_Hypothesis>(ior.c_str());
+      if (!aHyp->_is_nil()){
+       if (!SMESH::RemoveHypothesisOrAlgorithmOnMesh(aSubMeshSO, aHyp))
+         nbFail++;
+      }
+    }
+  }
+
+  // 4. Add new algorithms
+  for (int i = 0; i < ListAlgoAssignation->count(); i++) {
+    if (ListAlgoAssignation->item(i)->rtti() == ListBoxIOR::RTTI_IOR) {
+      ListBoxIOR* anItem = (ListBoxIOR*)(ListAlgoAssignation->item(i));
+      if (anItem) {
+       string ior = anItem->GetIOR();
+       if (myMapOldAlgos.find(ior) == myMapOldAlgos.end()) {
+         SMESH::SMESH_Hypothesis_var aHyp = SMESH::IORToInterface<SMESH::SMESH_Hypothesis>(ior.c_str());
+         if (!aHyp->_is_nil()){
+           if (!SMESH::AddHypothesisOnSubMesh(mySubMesh, aHyp))
+             nbFail++;
+         }
+       }
+      }
+    }
+  }
+
+  // 5. Add new hypotheses
+  for (int i = 0; i < ListHypAssignation->count(); i++) {
+    if (ListHypAssignation->item(i)->rtti() == ListBoxIOR::RTTI_IOR) {
+      ListBoxIOR* anItem = (ListBoxIOR*)(ListHypAssignation->item(i));
+      if (anItem) {
+       string ior = anItem->GetIOR();
+       if (myMapOldHypos.find(ior) == myMapOldHypos.end()) {
+         SMESH::SMESH_Hypothesis_var aHyp = SMESH::IORToInterface<SMESH::SMESH_Hypothesis>(ior.c_str());
+         if (!aHyp->_is_nil()){
+           if (!SMESH::AddHypothesisOnSubMesh(mySubMesh, aHyp))
+             nbFail++;
+         }
+       }
+      }
+    }
+  }
+  return (nbFail == 0);
+}
diff --git a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx
new file mode 100644 (file)
index 0000000..9bf9e43
--- /dev/null
@@ -0,0 +1,1448 @@
+//  SMESH SMESHGUI : GUI for SMESH component
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+//  File   : SMESHGUI_GroupDlg.cxx
+//  Author : Natalia KOPNOVA
+//  Module : SMESH
+//  $Header$
+
+#include "SMESHGUI_GroupDlg.h"
+#include "SMESHGUI_FilterDlg.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_GroupUtils.h"
+#include "SMESHGUI_FilterUtils.h"
+#include "SMESHGUI_GEOMGenUtils.h"
+
+#include "SMESH_TypeFilter.hxx"
+#include "SMESH_Actor.h"
+#include "GEOMBase.h"
+
+#include "SUIT_Desktop.h"
+#include "SUIT_ResourceMgr.h"
+
+#include "SalomeApp_Tools.h"
+#include "SALOMEDSClient_Study.hxx"
+#include "SALOME_ListIO.hxx"
+#include "SALOME_ListIteratorOfListIO.hxx"
+
+#include "SVTK_ViewWindow.h"
+#include "SVTK_Selector.h"
+
+#include "utilities.h"
+
+// OCCT Includes
+#include <TColStd_MapOfInteger.hxx>
+
+// QT Includes
+#include <qbuttongroup.h>
+#include <qgroupbox.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qcheckbox.h>
+#include <qlayout.h>
+#include <qlistbox.h>
+#include <qimage.h>
+#include <qpixmap.h>
+#include <qmemarray.h>
+#include <qwidgetstack.h>
+
+// STL includes
+#include <vector>
+#include <algorithm>
+
+using namespace std;
+
+//=================================================================================
+// function : SMESHGUI_GroupDlg()
+// purpose  :
+//=================================================================================
+SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule, const char* name,
+                                     SMESH::SMESH_Mesh_ptr theMesh, bool modal, WFlags fl)
+     : QDialog( SMESH::GetDesktop( theModule ), name, modal, WStyle_Customize | WStyle_NormalBorder |
+                WStyle_Title | WStyle_SysMenu | WDestructiveClose),
+     mySMESHGUI( theModule ),
+     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+     myIsBusy( false ),
+     myActor( 0 )
+{
+  if (!name) setName("SMESHGUI_GroupDlg");
+  initDialog(true);
+  if (!theMesh->_is_nil())
+    init(theMesh);
+  else {
+    mySelectSubMesh->setEnabled(false);
+    mySelectGroup->setEnabled(false);
+    myGeomGroupBtn->setEnabled(false);
+    myGeomGroupLine->setEnabled(false);
+  }
+
+  mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
+
+  /* Move widget on the botton right corner of main widget */
+  int x, y ;
+  mySMESHGUI->DefineDlgPosition(this, x, y);
+  this->move(x, y);
+}
+
+//=================================================================================
+// function : SMESHGUI_GroupDlg()
+// purpose  :
+//=================================================================================
+SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule, const char* name,
+                                     SMESH::SMESH_Group_ptr theGroup, bool modal, WFlags fl)
+     : QDialog( SMESH::GetDesktop( theModule ), name, modal, WStyle_Customize | WStyle_NormalBorder |
+                WStyle_Title | WStyle_SysMenu | WDestructiveClose),
+     mySMESHGUI( theModule ),
+     mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+     myIsBusy( false )
+{
+  if (!name) setName("SMESHGUI_GroupDlg");
+
+  mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
+
+  initDialog(false);
+  if (!theGroup->_is_nil())
+    init(theGroup);
+  else {
+    mySelectSubMesh->setEnabled(false);
+    mySelectGroup->setEnabled(false);
+
+    myCurrentLineEdit = myMeshGroupLine;
+    setSelectionMode(5);
+  }
+  
+  /* Move widget on the botton right corner of main widget */
+  int x, y ;
+  mySMESHGUI->DefineDlgPosition(this, x, y);
+  this->move(x, y);
+}
+
+//=================================================================================
+// function : SMESHGUI_GroupDlg()
+// purpose  :
+//=================================================================================
+void SMESHGUI_GroupDlg::initDialog(bool create)
+{
+  myFilterDlg = 0;
+  myCreate = create;
+  myCurrentLineEdit = 0;
+
+  QPixmap image0 (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
+
+  if (create)
+    setCaption(tr("SMESH_CREATE_GROUP_TITLE"));
+  else
+    setCaption(tr("SMESH_EDIT_GROUP_TITLE"));
+
+  setSizeGripEnabled(TRUE);
+
+  QGridLayout* aMainLayout = new QGridLayout(this, 7, 3, 11, 6);
+
+  /***************************************************************/
+  QLabel* meshGroupLab = new QLabel(this, "mesh/group label");
+  if (create)
+    meshGroupLab->setText(tr("SMESH_MESH"));
+  else
+    meshGroupLab->setText(tr("SMESH_GROUP"));
+  myMeshGroupBtn = new QPushButton(this, "mesh/group button");
+  myMeshGroupBtn->setPixmap(image0);
+  myMeshGroupLine = new QLineEdit(this, "mesh/group line");
+  myMeshGroupLine->setReadOnly(true);
+
+  /***************************************************************/
+  myTypeGroup = new QButtonGroup(1, Qt::Vertical, this, "Group types");
+  myTypeGroup->setTitle(tr("SMESH_ELEMENTS_TYPE"));
+  myTypeGroup->setExclusive(true);
+
+  QStringList types;
+  types.append(tr("MESH_NODE"));
+  types.append(tr("SMESH_EDGE"));
+  types.append(tr("SMESH_FACE"));
+  types.append(tr("SMESH_VOLUME"));
+  QRadioButton* rb;
+  for (int i = 0; i < types.count(); i++) {
+    rb = new QRadioButton(types[i], myTypeGroup);
+  }
+  myTypeGroup->setEnabled(create);
+  myTypeId = -1;
+
+  /***************************************************************/
+  QLabel* aName = new QLabel(this, "name label");
+  aName->setText(tr("SMESH_NAME"));
+  aName->setMinimumSize(50,0);
+  myName = new QLineEdit(this, "name");
+
+  /***************************************************************/
+  myGrpTypeGroup = new QButtonGroup(1, Qt::Vertical, this, "Type of group");
+  myGrpTypeGroup->setTitle(tr("SMESH_GROUP_TYPE"));
+  myGrpTypeGroup->setExclusive(true);
+  QRadioButton* rb1 = new QRadioButton( tr("SMESH_GROUP_STANDALONE"), myGrpTypeGroup);
+  QRadioButton* rb2 = new QRadioButton( tr("SMESH_GROUP_GEOMETRY"),   myGrpTypeGroup);
+  myGrpTypeGroup->setEnabled(create);
+  myGrpTypeId = -1;
+
+  /***************************************************************/
+  myWGStack = new QWidgetStack( this, "widget stack");
+  QWidget* wg1 = new QFrame( myWGStack, "first widget" );
+  QWidget* wg2 = new QFrame( myWGStack, "second widget" );
+
+  /***************************************************************/
+  QGroupBox* aContentBox = new QGroupBox(1, Qt::Horizontal, wg1, "content box");
+  aContentBox->setTitle(tr("SMESH_CONTENT"));
+  QFrame* aContent = new QFrame(aContentBox, "content");
+  QGridLayout* aLayout = new QGridLayout(aContent, 7, 4);
+  aLayout->setSpacing(6);
+  aLayout->setAutoAdd(false);
+
+  QLabel* aLabel = new QLabel(aContent, "elements label");
+  aLabel->setText(tr("SMESH_ID_ELEMENTS"));
+  myElements = new QListBox(aContent, "elements list");
+  myElements->setSelectionMode(QListBox::Extended);
+
+  myFilter = new QPushButton(aContent, "filter");
+  myFilter->setText(tr("SMESH_BUT_FILTER"));
+  QPushButton* aAddBtn = new QPushButton(aContent, "add");
+  aAddBtn->setText(tr("SMESH_BUT_ADD"));
+  QPushButton* aRemoveBtn = new QPushButton(aContent, "remove");
+  aRemoveBtn->setText(tr("SMESH_BUT_REMOVE"));
+  QPushButton* aSortBtn = new QPushButton(aContent, "sort");
+  aSortBtn->setText(tr("SMESH_BUT_SORT"));
+
+  aLayout->addWidget(aLabel, 0, 0);
+  aLayout->addMultiCellWidget(myElements, 1, 6, 0, 0);
+  aLayout->addWidget(myFilter, 1, 2);
+  aLayout->addWidget(aAddBtn, 3, 2);
+  aLayout->addWidget(aRemoveBtn, 4, 2);
+  aLayout->addWidget(aSortBtn, 6, 2);
+
+  aLayout->setColStretch(0, 1);
+  aLayout->addColSpacing(1, 20);
+  aLayout->addColSpacing(3, 20);
+  aLayout->setRowStretch(2, 1);
+  aLayout->setRowStretch(5, 1);
+
+  /***************************************************************/
+  QGroupBox* aSelectBox = new QGroupBox(3, Qt::Horizontal, wg1, "select box");
+  aSelectBox->setTitle(tr("SMESH_SELECT_FROM"));
+
+  mySelectSubMesh = new QCheckBox(aSelectBox, "submesh checkbox");
+  mySelectSubMesh->setText(tr("SMESH_SUBMESH"));
+  mySelectSubMesh->setMinimumSize(50, 0);
+  mySubMeshBtn = new QPushButton(aSelectBox, "submesh button");
+  mySubMeshBtn->setText("");
+  mySubMeshBtn->setPixmap(image0);
+  mySubMeshLine = new QLineEdit(aSelectBox, "submesh line");
+  mySubMeshLine->setReadOnly(true);
+  onSelectSubMesh(false);
+
+  mySelectGroup = new QCheckBox(aSelectBox, "group checkbox");
+  mySelectGroup->setText(tr("SMESH_GROUP"));
+  mySelectGroup->setMinimumSize(50, 0);
+  myGroupBtn = new QPushButton(aSelectBox, "group button");
+  myGroupBtn->setText("");
+  myGroupBtn->setPixmap(image0);
+  myGroupLine = new QLineEdit(aSelectBox, "group line");
+  myGroupLine->setReadOnly(true);
+  onSelectGroup(false);
+
+  /***************************************************************/
+  QGridLayout* wg1Layout = new QGridLayout( wg1, 3, 1, 0, 6 );
+  wg1Layout->addWidget(aContentBox, 0, 0);
+  wg1Layout->addWidget(aSelectBox, 1, 0);
+  wg1Layout->setRowStretch(2, 5);
+
+  /***************************************************************/
+  QLabel* geomObject = new QLabel(wg2, "geometry object label");
+  geomObject->setText(tr("SMESH_OBJECT_GEOM"));
+  myGeomGroupBtn = new QPushButton(wg2, "geometry group button");
+  myGeomGroupBtn->setText("");
+  myGeomGroupBtn->setPixmap(image0);
+  myGeomGroupLine = new QLineEdit(wg2, "geometry group line");
+  myGeomGroupLine->setReadOnly(true); //VSR ???
+  onSelectGeomGroup(false);
+
+  /***************************************************************/
+  QGridLayout* wg2Layout = new QGridLayout( wg2, 2, 3, 0, 6 );
+  wg2Layout->addWidget(geomObject,     0, 0);
+  wg2Layout->addWidget(myGeomGroupBtn, 0, 1);
+  wg2Layout->addWidget(myGeomGroupLine,0, 2);
+  wg2Layout->setRowStretch(1, 5);
+
+  /***************************************************************/
+  QVBoxLayout* dumb = new QVBoxLayout(myWGStack);
+  dumb->addWidget(wg1);
+  dumb->addWidget(wg2);
+  myWGStack->addWidget( wg1, myGrpTypeGroup->id(rb1) );
+  myWGStack->addWidget( wg2, myGrpTypeGroup->id(rb2) );
+
+  /***************************************************************/
+  QFrame* aButtons = new QFrame(this, "button box");
+  aButtons->setFrameStyle(QFrame::Box | QFrame::Sunken);
+  QHBoxLayout* aBtnLayout = new QHBoxLayout(aButtons, 11, 6);
+  aBtnLayout->setAutoAdd(false);
+
+  QPushButton* aOKBtn = new QPushButton(aButtons, "ok");
+  aOKBtn->setText(tr("SMESH_BUT_OK"));
+  aOKBtn->setAutoDefault(true);
+  aOKBtn->setDefault(true);
+  QPushButton* aApplyBtn = new QPushButton(aButtons, "apply");
+  aApplyBtn->setText(tr("SMESH_BUT_APPLY"));
+  aApplyBtn->setAutoDefault(true);
+  QPushButton* aCloseBtn = new QPushButton(aButtons, "close");
+  aCloseBtn->setText(tr("SMESH_BUT_CLOSE"));
+  aCloseBtn->setAutoDefault(true);
+
+  aBtnLayout->addWidget(aOKBtn);
+  aBtnLayout->addWidget(aApplyBtn);
+  aBtnLayout->addStretch();
+  aBtnLayout->addWidget(aCloseBtn);
+
+  /***************************************************************/
+  aMainLayout->addWidget(meshGroupLab,    0, 0);
+  aMainLayout->addWidget(myMeshGroupBtn,  0, 1);
+  aMainLayout->addWidget(myMeshGroupLine, 0, 2);
+  aMainLayout->addMultiCellWidget(myTypeGroup,    1, 1, 0, 2);
+  aMainLayout->addWidget(aName,      2, 0);
+  aMainLayout->addWidget(myName,     2, 2);
+  aMainLayout->addMultiCellWidget(myGrpTypeGroup, 3, 3, 0, 2);
+  aMainLayout->addMultiCellWidget(myWGStack,      4, 4, 0, 2);
+  aMainLayout->setRowStretch( 5, 5 );
+  aMainLayout->addMultiCellWidget(aButtons,       6, 6, 0, 2);
+
+  /* signals and slots connections */
+  connect(myMeshGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection()));
+
+  connect(myGrpTypeGroup, SIGNAL(clicked(int)), this, SLOT(onGrpTypeChanged(int)));
+
+  connect(myTypeGroup, SIGNAL(clicked(int)), this, SLOT(onTypeChanged(int)));
+
+  connect(myName, SIGNAL(textChanged(const QString&)), this, SLOT(onNameChanged(const QString&)));
+  connect(myElements, SIGNAL(selectionChanged()), this, SLOT(onListSelectionChanged()));
+
+  connect(myFilter, SIGNAL(clicked()), this, SLOT(setFilters()));
+  connect(aAddBtn, SIGNAL(clicked()), this, SLOT(onAdd()));
+  connect(aRemoveBtn, SIGNAL(clicked()), this, SLOT(onRemove()));
+  connect(aSortBtn, SIGNAL(clicked()), this, SLOT(onSort()));
+
+  connect(mySelectSubMesh, SIGNAL(toggled(bool)), this, SLOT(onSelectSubMesh(bool)));
+  connect(mySelectGroup, SIGNAL(toggled(bool)), this, SLOT(onSelectGroup(bool)));
+  connect(mySubMeshBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection()));
+  connect(myGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection()));
+  connect(myGeomGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection()));
+
+  connect(aOKBtn, SIGNAL(clicked()), this, SLOT(onOK()));
+  connect(aApplyBtn, SIGNAL(clicked()), this, SLOT(onApply()));
+  connect(aCloseBtn, SIGNAL(clicked()), this, SLOT(onClose()));
+
+  /* Init selection */
+  mySMESHGUI->SetActiveDialogBox(this);
+  mySMESHGUI->SetState(800);
+
+  mySelectionMode = -1;
+  myMeshFilter = new SMESH_TypeFilter(MESH);
+  mySubMeshFilter = new SMESH_TypeFilter(SUBMESH);
+  myGroupFilter = new SMESH_TypeFilter(GROUP);
+
+  connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(onDeactivate()));
+  connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(onClose()));
+  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onObjectSelectionChanged()));
+
+  myGrpTypeGroup->setButton(myGrpTypeGroup->id(rb1)); // VSR !!!
+  onGrpTypeChanged(myGrpTypeGroup->id(rb1)); // VSR!!!
+
+  if (myMesh->_is_nil() )
+    myTypeGroup->setButton(0);
+
+  updateButtons();
+}
+
+//=================================================================================
+// function : ~SMESHGUI_GroupDlg()
+// purpose  : Destroys the object and frees any allocated resources
+//=================================================================================
+SMESHGUI_GroupDlg::~SMESHGUI_GroupDlg()
+{
+  // no need to delete child widgets, Qt does it all for us
+  if ( myFilterDlg != 0 )
+  {
+    myFilterDlg->reparent( 0, QPoint() );
+    delete myFilterDlg;
+  }
+}
+
+//=================================================================================
+// function : Init()
+// purpose  :
+//=================================================================================
+void SMESHGUI_GroupDlg::init (SMESH::SMESH_Mesh_ptr theMesh)
+{
+  mySelectionMgr->installFilter(myMeshFilter);
+
+  /* init data from current selection */
+  myMesh = SMESH::SMESH_Mesh::_duplicate(theMesh);
+  myGroup = SMESH::SMESH_Group::_nil();
+
+  myActor = SMESH::FindActorByObject(myMesh);
+  SMESH::SetPickable(myActor);
+
+  SALOME_ListIO aList;
+  mySelectionMgr->selectedObjects( aList );
+  if( !aList.IsEmpty() )
+  {
+    QString aName = aList.First()->getName();
+    myMeshGroupLine->setText(aName) ;
+    myMeshGroupLine->home( false );
+  }
+
+  myCurrentLineEdit = 0;
+
+  myTypeGroup->setButton(0);
+  onTypeChanged(0);
+}
+
+//=================================================================================
+// function : Init()
+// purpose  :
+//=================================================================================
+void SMESHGUI_GroupDlg::init (SMESH::SMESH_Group_ptr theGroup)
+{
+  myMesh = theGroup->GetMesh();
+  myGroup = SMESH::SMESH_Group::_duplicate(theGroup);
+
+  myActor = SMESH::FindActorByObject(myMesh);
+  if ( !myActor )
+    myActor = SMESH::FindActorByObject(myGroup);
+  SMESH::SetPickable(myActor);
+
+  int aType = 0;
+  switch(theGroup->GetType()) {
+  case SMESH::NODE: aType= 0; break;
+  case SMESH::EDGE: aType = 1; break;
+  case SMESH::FACE: aType = 2; break;
+  case SMESH::VOLUME: aType = 3; break;
+  }
+
+  myName->setText(myGroup->GetName());
+  myName->home(false);
+  myMeshGroupLine->setText(myGroup->GetName());
+
+  myCurrentLineEdit = 0;
+  myTypeGroup->setButton(aType);
+  myElements->clear();
+  setSelectionMode(aType);
+  myTypeId = aType;
+
+  myIdList.clear();
+  if (!theGroup->IsEmpty()) {
+    SMESH::long_array_var anElements = myGroup->GetListOfID();
+    int k = anElements->length();
+    for (int i = 0; i < k; i++) {
+      myIdList.append(anElements[i]);
+      myElements->insertItem(QString::number(anElements[i]));
+    }
+    myElements->selectAll(true);
+  }
+}
+
+//=================================================================================
+// function : updateButtons()
+// purpose  :
+//=================================================================================
+void SMESHGUI_GroupDlg::updateButtons()
+{
+  bool enable;
+
+  if (myGrpTypeId == 0)
+    enable = !myName->text().stripWhiteSpace().isEmpty() && myElements->count() > 0;
+  else if (myGrpTypeId == 1)
+    enable = !myName->text().stripWhiteSpace().isEmpty() && !CORBA::is_nil( myGeomGroup );
+  QPushButton* aBtn;
+  aBtn = (QPushButton*) child("ok", "QPushButton");
+  if (aBtn) aBtn->setEnabled(enable);
+  aBtn = (QPushButton*) child("apply", "QPushButton");
+  if (aBtn) aBtn->setEnabled(enable);
+}
+
+//=================================================================================
+// function : onNameChanged()
+// purpose  :
+//=================================================================================
+void SMESHGUI_GroupDlg::onNameChanged (const QString& text)
+{
+  updateButtons();
+}
+
+//=================================================================================
+// function : onTypeChanged()
+// purpose  : Group elements type radio button management
+//=================================================================================
+void SMESHGUI_GroupDlg::onTypeChanged (int id)
+{
+  if (myTypeId != id) {
+    myElements->clear();
+    if (myCurrentLineEdit == 0)
+      setSelectionMode(id);
+  }
+  myTypeId = id;
+}
+
+//=================================================================================
+// function : onGrpTypeChanged()
+// purpose  : Group type radio button management
+//=================================================================================
+void SMESHGUI_GroupDlg::onGrpTypeChanged (int id)
+{
+  if (myGrpTypeId != id) {
+    myWGStack->raiseWidget( id );
+    onSelectGeomGroup(id == 1);
+  }
+  myGrpTypeId = id;
+}
+
+//=================================================================================
+// function : setSelectionMode()
+// purpose  : Radio button management
+//=================================================================================
+void SMESHGUI_GroupDlg::setSelectionMode (int theMode)
+{
+  // PAL7314
+  if (myMesh->_is_nil())
+    return;
+
+  if (mySelectionMode != theMode) {
+    mySelectionMgr->clearSelected();
+    mySelectionMgr->clearFilters();
+    SMESH::SetPointRepresentation(false);
+    if (theMode < 4) {
+      switch (theMode) {
+      case 0:
+        if (myActor)
+          myActor->SetPointRepresentation(true);
+        else
+          SMESH::SetPointRepresentation(true);
+       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+         aViewWindow->SetSelectionMode(NodeSelection);
+       break;
+      case 1:
+       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+         aViewWindow->SetSelectionMode(EdgeSelection);
+       break;
+      case 2:
+       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+         aViewWindow->SetSelectionMode(FaceSelection);
+       break;
+      default:
+       if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+         aViewWindow->SetSelectionMode(VolumeSelection);
+      }
+    } else {
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+       aViewWindow->SetSelectionMode(ActorSelection);
+      if (theMode == 4)
+       mySelectionMgr->installFilter(mySubMeshFilter);
+      else if (theMode == 5)
+       mySelectionMgr->installFilter(myGroupFilter);
+      else if (theMode == 6)
+       mySelectionMgr->installFilter(myMeshFilter);
+    }
+    mySelectionMode = theMode;
+  }
+}
+
+//=================================================================================
+// function : onApply()
+// purpose  :
+//=================================================================================
+bool SMESHGUI_GroupDlg::onApply()
+{
+  if (mySMESHGUI->isActiveStudyLocked())
+    return false;
+
+  if (myGrpTypeId == 0 &&
+      !myName->text().stripWhiteSpace().isEmpty() &&
+      myElements->count() > 0) {
+    mySelectionMgr->clearSelected();
+    if (myGroup->_is_nil()) {
+      SMESH::ElementType aType = SMESH::ALL;
+      switch(myTypeId) {
+      case 0: aType = SMESH::NODE; break;
+      case 1: aType = SMESH::EDGE; break;
+      case 2: aType = SMESH::FACE; break;
+      case 3: aType = SMESH::VOLUME; break;
+      }
+      SMESH::long_array_var anIdList = new SMESH::long_array;
+      int i, k = myElements->count();
+      anIdList->length(k);
+      QListBoxItem* anItem;
+      for (i = 0, anItem = myElements->firstItem(); anItem != 0; i++, anItem = anItem->next()) {
+       anIdList[i] = anItem->text().toInt();
+      }
+
+      myGroup = SMESH::AddGroup(myMesh, aType, myName->text());
+      myGroup->Add(anIdList.inout());
+
+      /* init for next operation */
+      myName->setText("");
+      myElements->clear();
+      myGroup = SMESH::SMESH_Group::_nil();
+
+    } else {
+      myGroup->SetName(myName->text());
+
+      QValueList<int> aAddList;
+      QValueList<int>::iterator anIt;
+      QListBoxItem* anItem;
+
+      for (anItem = myElements->firstItem(); anItem != 0; anItem = anItem->next()) {
+       int anId = anItem->text().toInt();
+       if ((anIt = myIdList.find(anId)) == myIdList.end())
+         aAddList.append(anId);
+       else
+         myIdList.remove(anIt);
+      }
+      if (!aAddList.empty()) {
+       SMESH::long_array_var anIdList = new SMESH::long_array;
+       anIdList->length(aAddList.count());
+        int i;
+       for (i = 0, anIt = aAddList.begin(); anIt != aAddList.end(); anIt++, i++)
+         anIdList[i] = *anIt;
+       myGroup->Add(anIdList.inout());
+      }
+      if (!myIdList.empty()) {
+       SMESH::long_array_var anIdList = new SMESH::long_array;
+       anIdList->length(myIdList.count());
+        int i;
+       for (i = 0, anIt = myIdList.begin(); anIt != myIdList.end(); anIt++, i++)
+         anIdList[i] = *anIt;
+       myGroup->Remove(anIdList.inout());
+      }
+      /* init for next operation */
+      myIdList.clear();
+      for (anItem = myElements->firstItem(); anItem != 0; anItem = anItem->next())
+       myIdList.append(anItem->text().toInt());
+    }
+
+    mySMESHGUI->updateObjBrowser(true);
+    SMESH::UpdateView(); // asv: fix of BUG PAL5515
+    mySelectionMgr->clearSelected();
+    return true;
+  } else if (myGrpTypeId == 1 &&
+             !myName->text().stripWhiteSpace().isEmpty() &&
+             !CORBA::is_nil(myGeomGroup))
+  {
+    SMESH::ElementType aType = SMESH::ALL;
+    switch (myTypeId) {
+    case 0: aType = SMESH::NODE; break;
+    case 1: aType = SMESH::EDGE; break;
+    case 2: aType = SMESH::FACE; break;
+    case 3: aType = SMESH::VOLUME; break;
+    }
+
+    _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+    GEOM::GEOM_IGroupOperations_var aGroupOp =
+      SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId());
+
+    SMESH::SMESH_GroupOnGeom_var aGroupOnGeom =
+      myMesh->CreateGroupFromGEOM(aType, myName->text(),myGeomGroup);
+
+    mySMESHGUI->updateObjBrowser(true);
+    mySelectionMgr->clearSelected();
+    /* init for next operation */
+    myName->setText("");
+    return true;
+  }
+
+  return false;
+}
+
+//=================================================================================
+// function : onOK()
+// purpose  :
+//=================================================================================
+void SMESHGUI_GroupDlg::onOK()
+{
+  if ( onApply() )
+    onClose();
+}
+
+//=================================================================================
+// function : onListSelectionChanged()
+// purpose  : Called when selection in element list is changed
+//=================================================================================
+void SMESHGUI_GroupDlg::onListSelectionChanged()
+{
+  //  MESSAGE("SMESHGUI_GroupDlg::onListSelectionChanged(); myActor = " << myActor);
+  if( myIsBusy || !myActor) return;
+    myIsBusy = true;
+
+  if (myCurrentLineEdit == 0) {
+    mySelectionMgr->clearSelected();
+    TColStd_MapOfInteger aIndexes;
+    QListBoxItem* anItem;
+    for (anItem = myElements->firstItem(); anItem != 0; anItem = anItem->next()) {
+      if (anItem->isSelected()) {
+       int anId = anItem->text().toInt();
+       aIndexes.Add(anId);
+      }
+    }
+    mySelector->AddOrRemoveIndex(myActor->getIO(), aIndexes, false);
+    SALOME_ListIO aList;
+    aList.Append(myActor->getIO());
+    mySelectionMgr->setSelectedObjects(aList,false);
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->highlight( myActor->getIO(), true, true );
+  }
+  myIsBusy = false;
+}
+
+//=================================================================================
+// function : onObjectSelectionChanged()
+// purpose  : Called when selection in 3D view or ObjectBrowser is changed
+//=================================================================================
+void SMESHGUI_GroupDlg::onObjectSelectionChanged()
+{
+  if ( myIsBusy || !isEnabled()) return;
+    myIsBusy = true;
+
+  SALOME_ListIO aList;
+  mySelectionMgr->selectedObjects( aList );
+  
+  int aNbSel = aList.Extent();
+  myElements->clearSelection();
+
+  if (myCurrentLineEdit) {
+    myCurrentLineEdit->setText("");
+    QString aString = "";
+
+    if (myCurrentLineEdit == myMeshGroupLine) {
+      mySelectSubMesh->setEnabled(false);
+      mySelectGroup->setEnabled(false);
+      myGroupLine->setText("");
+      mySubMeshLine->setText("");
+
+      myGeomGroupBtn->setEnabled(false);
+      myGeomGroupLine->setEnabled(false);
+      myGeomGroupLine->setText("");
+      if (!myCreate)
+        myName->setText("");
+
+      myElements->clear();
+
+      if (aNbSel != 1 ) {
+        myGroup = SMESH::SMESH_Group::_nil();
+        myMesh = SMESH::SMESH_Mesh::_nil();
+        myIsBusy = false;
+        return;
+      }
+      Handle(SALOME_InteractiveObject) IO = aList.First();
+
+      if (myCreate) {
+        myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
+        if (myMesh->_is_nil())
+       {
+         myIsBusy = false;
+          return;
+       }
+        myGroup = SMESH::SMESH_Group::_nil();
+
+        myActor = SMESH::FindActorByObject(myMesh);
+        SMESH::SetPickable(myActor);
+
+        aString = aList.First()->getName();
+        myMeshGroupLine->setText(aString) ;
+        myMeshGroupLine->home( false );
+
+        mySelectSubMesh->setEnabled(true);
+        mySelectGroup->setEnabled(true);
+        myGeomGroupBtn->setEnabled(true);
+        myGeomGroupLine->setEnabled(true);
+        updateButtons();
+      } else {
+        SMESH::SMESH_Group_var aGroup = SMESH::IObjectToInterface<SMESH::SMESH_Group>(IO);
+        if (aGroup->_is_nil())
+       {
+         myIsBusy = false;
+          return;
+       }
+        myIsBusy = false;
+        myCurrentLineEdit = 0;
+        init(aGroup);
+        myIsBusy = true;
+        mySelectSubMesh->setEnabled(true);
+        mySelectGroup->setEnabled(true);
+        myGeomGroupBtn->setEnabled(true);
+        myGeomGroupLine->setEnabled(true);
+      }
+      myCurrentLineEdit = 0;
+      myIsBusy = false;
+      if (!myCreate)
+        return;
+
+      if (myTypeId == -1)
+        onTypeChanged(0);
+      else {
+        myElements->clear();
+        setSelectionMode(myTypeId);
+      }
+
+      myIsBusy = false;
+      return;
+
+    } else if (myCurrentLineEdit == myGeomGroupLine) {
+      if (aNbSel != 1) {
+        myGeomGroup = GEOM::GEOM_Object::_nil();
+        myIsBusy = false;
+        return;
+      }
+
+      Standard_Boolean testResult = Standard_False;
+      myGeomGroup = GEOMBase::ConvertIOinGEOMObject(aList.First(), testResult);
+
+      // Check if the object is a geometry group
+      if (!testResult || CORBA::is_nil(myGeomGroup)) {
+        myGeomGroup = GEOM::GEOM_Object::_nil();
+        myIsBusy = false;
+        return;
+      }
+      // Check if group constructed on the same shape as a mesh or on its child
+      _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+      GEOM::GEOM_IGroupOperations_var anOp =
+        SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId());
+
+      // The main shape of the group
+      GEOM::GEOM_Object_var aGroupMainShape;
+      if (myGeomGroup->GetType() == 37)
+        aGroupMainShape = anOp->GetMainShape(myGeomGroup);
+      else
+        aGroupMainShape = GEOM::GEOM_Object::_duplicate(myGeomGroup);
+      _PTR(SObject) aGroupMainShapeSO =
+        //aStudy->FindObjectIOR(aStudy->ConvertObjectToIOR(aGroupMainShape));
+        aStudy->FindObjectIOR(aGroupMainShape->GetStudyEntry());
+
+      // The mesh SObject
+      _PTR(SObject) aMeshSO = SMESH::FindSObject(myMesh);
+      if (!aMeshSO) {
+        myGeomGroup = GEOM::GEOM_Object::_nil();
+        myIsBusy = false;
+        return;
+      }
+      _PTR(SObject) anObj, aRef;
+      bool isRefOrSubShape = false;
+      if (aMeshSO->FindSubObject(1, anObj) &&  anObj->ReferencedObject(aRef)) {
+        //if (strcmp(aRef->GetID(), aGroupMainShapeSO->GetID()) == 0) {
+        if (aRef->GetID() == aGroupMainShapeSO->GetID()) {
+          isRefOrSubShape = true;
+        } else {
+          _PTR(SObject) aFather = aGroupMainShapeSO->GetFather();
+          _PTR(SComponent) aComponent = aGroupMainShapeSO->GetFatherComponent();
+         //while (!isRefOrSubShape && strcmp(aFather->GetID(), aComponent->GetID()) != 0) {
+         while (!isRefOrSubShape && aFather->GetID() != aComponent->GetID()) {
+            //if (strcmp(aRef->GetID(), aFather->GetID()) == 0)
+            if (aRef->GetID() == aFather->GetID())
+              isRefOrSubShape = true;
+            else
+              aFather = aFather->GetFather();
+          }
+       }
+      }
+      if (!isRefOrSubShape) {
+        myGeomGroup = GEOM::GEOM_Object::_nil();
+        myIsBusy = false;
+        return;
+      }
+    }
+
+    if(aNbSel >= 1) {
+      if(aNbSel > 1) {
+       if(myCurrentLineEdit == mySubMeshLine)
+         aString = tr("SMESH_SUBMESH_SELECTED").arg(aNbSel);
+       else if(myCurrentLineEdit == myGroupLine || myCurrentLineEdit == myGeomGroupLine)
+         aString = tr("SMESH_GROUP_SELECTED").arg(aNbSel);
+      } else {
+       aString = aList.First()->getName();
+      }
+    }
+
+    myCurrentLineEdit->setText(aString);
+    myCurrentLineEdit->home(false);
+
+    updateButtons();
+
+  } else {
+    if (aNbSel == 1 && myActor ) {
+      QString aListStr = "";
+      int aNbItems = 0;
+      if (myTypeId == 0) {
+       aNbItems = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr);
+      } else {
+       aNbItems = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aListStr);
+      }
+      if (aNbItems > 0) {
+       QStringList anElements = QStringList::split(" ", aListStr);
+       QListBoxItem* anItem = 0;
+       for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
+         anItem = myElements->findItem(*it, Qt::ExactMatch);
+         if (anItem) myElements->setSelected(anItem, true);
+       }
+      }
+    }
+  }
+
+  if (!myActor) {
+    if (!myGroup->_is_nil())
+      myActor = SMESH::FindActorByObject(myGroup);
+    else
+      myActor = SMESH::FindActorByObject(myMesh);
+  }
+
+  myIsBusy = false;
+}
+
+//=================================================================================
+// function : onSelectSubMesh()
+// purpose  : Called when selection in 3D view or ObjectBrowser is changed
+//=================================================================================
+void SMESHGUI_GroupDlg::onSelectSubMesh(bool on)
+{
+  if (on) {
+    if (mySelectGroup->isChecked()) {
+      mySelectGroup->setChecked(false);
+    }
+    //VSR: else if (mySelectGeomGroup->isChecked()) {
+    //VSR:   mySelectGeomGroup->setChecked(false);
+    //VSR: }
+    myCurrentLineEdit = mySubMeshLine;
+    setSelectionMode(4);
+  }
+  else {
+    mySubMeshLine->setText("");
+    myCurrentLineEdit = 0;
+    if (myTypeId != -1)
+      setSelectionMode(myTypeId);
+  }
+  mySubMeshBtn->setEnabled(on);
+  mySubMeshLine->setEnabled(on);
+}
+
+
+//=================================================================================
+// function : (onSelectGroup)
+// purpose  : Called when selection in 3D view or ObjectBrowser is changed
+//=================================================================================
+void SMESHGUI_GroupDlg::onSelectGroup(bool on)
+{
+  if (on) {
+    if (mySelectSubMesh->isChecked()) {
+      mySelectSubMesh->setChecked(false);
+    }
+    myCurrentLineEdit = myGroupLine;
+    setSelectionMode(5);
+  }
+  else {
+    myGroupLine->setText("");
+    myCurrentLineEdit = 0;
+    if (myTypeId != -1)
+      setSelectionMode(myTypeId);
+  }
+  myGroupBtn->setEnabled(on);
+  myGroupLine->setEnabled(on);
+}
+
+
+//=================================================================================
+// function : (onSelectGeomGroup)
+// purpose  : Called when selection in 3D view or ObjectBrowser is changed
+//=================================================================================
+void SMESHGUI_GroupDlg::onSelectGeomGroup(bool on)
+{
+  if (on) {
+    if (mySelectSubMesh->isChecked()) {
+      mySelectSubMesh->setChecked(false);
+    }
+    else if (mySelectGroup->isChecked()) {
+      mySelectGroup->setChecked(false);
+    }
+    myCurrentLineEdit = myGeomGroupLine;
+    setSelectionMode(7);
+  }
+  else {
+    myGeomGroupLine->setText("");
+    myCurrentLineEdit = 0;
+    if (myTypeId != -1)
+      setSelectionMode(myTypeId);
+  }
+}
+
+
+//=================================================================================
+// function : setCurrentSelection()
+// purpose  :
+//=================================================================================
+void SMESHGUI_GroupDlg::setCurrentSelection()
+{
+  QPushButton* send = (QPushButton*)sender();
+  myCurrentLineEdit = 0;
+  if (send == myMeshGroupBtn) {
+    myCurrentLineEdit = myMeshGroupLine;
+    if (myCreate)
+      setSelectionMode(6);
+    else
+      setSelectionMode(5);
+    onObjectSelectionChanged();
+  }
+  else if (send == mySubMeshBtn) {
+    myCurrentLineEdit = mySubMeshLine;
+    onObjectSelectionChanged();
+  }
+  else if (send == myGroupBtn) {
+    myCurrentLineEdit = myGroupLine;
+    onObjectSelectionChanged();
+  }
+  else if (send == myGeomGroupBtn) {
+    myCurrentLineEdit = myGeomGroupLine;
+    setSelectionMode(7);
+    onObjectSelectionChanged();
+  }
+}
+
+
+//=================================================================================
+// function : setFilters()
+// purpose  : SLOT. Called when "Filter" button pressed.
+//=================================================================================
+void SMESHGUI_GroupDlg::setFilters()
+{
+  SMESH::ElementType aType = SMESH::ALL;
+  switch ( myTypeId )
+  {
+    case 0 : aType = SMESH::NODE; break;
+    case 1 : aType = SMESH::EDGE; break;
+    case 2 : aType = SMESH::FACE; break;
+    case 3 : aType = SMESH::VOLUME; break;
+    default: return;
+  }
+
+  if ( myFilterDlg == 0 )
+  {
+    myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, aType );
+    connect( myFilterDlg, SIGNAL( Accepted() ), SLOT( onFilterAccepted() ) );
+  }
+  else
+    myFilterDlg->Init( aType );
+
+  myFilterDlg->SetSelection();
+  myFilterDlg->SetMesh( myMesh );
+  myFilterDlg->SetSourceWg( myElements );
+
+  myFilterDlg->show();
+}
+
+//=================================================================================
+// function : onFilterAccepted()
+// purpose  : SLOT. Called when Filter dlg closed with OK button.
+//            Uncheck "Select submesh" and "Select group" checkboxes
+//=================================================================================
+void SMESHGUI_GroupDlg::onFilterAccepted()
+{
+  if ( mySelectSubMesh->isChecked() || mySelectGroup->isChecked() )
+  {
+    mySelectionMode = myTypeId;
+    mySelectSubMesh->setChecked( false );
+    mySelectGroup->setChecked( false );
+  }
+}
+
+//=================================================================================
+// function : onAdd()
+// purpose  :
+//=================================================================================
+void SMESHGUI_GroupDlg::onAdd()
+{
+  SALOME_ListIO aList;
+  mySelectionMgr->selectedObjects( aList );
+
+  int aNbSel = aList.Extent();
+
+  if (aNbSel == 0 || !myActor || myMesh->_is_nil()) return;
+
+  myIsBusy = true;
+
+  SMESH::ElementType aType = SMESH::ALL;
+  switch(myTypeId) {
+  case 0: aType = SMESH::NODE; break;
+  case 1: aType = SMESH::EDGE; break;
+  case 2: aType = SMESH::FACE; break;
+  case 3: aType = SMESH::VOLUME; break;
+  }
+
+  if (myCurrentLineEdit == 0) {
+    //if (aNbSel != 1) { myIsBusy = false; return; }
+    QString aListStr = "";
+    int aNbItems = 0;
+    if (myTypeId == 0) {
+      aNbItems = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr);
+    }
+    else {
+      aNbItems = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aListStr);
+    }
+    if (aNbItems > 0) {
+      QStringList anElements = QStringList::split(" ", aListStr);
+      QListBoxItem* anItem = 0;
+      for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
+       anItem = myElements->findItem(*it, Qt::ExactMatch);
+       if (!anItem) {
+         anItem = new QListBoxText(*it);
+         myElements->insertItem(anItem);
+       }
+       myElements->setSelected(anItem, true);
+      }
+    }
+  } else if (myCurrentLineEdit == mySubMeshLine) {
+    //SALOME_ListIteratorOfListIO anIt (mySelectionMgr->StoredIObjects());
+    
+    SALOME_ListIO aList;
+    mySelectionMgr->selectedObjects( aList );
+
+    SALOME_ListIteratorOfListIO anIt (aList);
+    for (; anIt.More(); anIt.Next()) {
+      SMESH::SMESH_subMesh_var aSubMesh =
+        SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIt.Value());
+      if (!aSubMesh->_is_nil()) {
+       // check if mesh is the same
+       if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) {
+          try {
+            SMESH::long_array_var anElements = aSubMesh->GetElementsByType(aType);
+            int k = anElements->length();
+            QListBoxItem* anItem = 0;
+            for (int i = 0; i < k; i++) {
+              QString aText = QString::number(anElements[i]);
+              anItem = myElements->findItem(aText, Qt::ExactMatch);
+              if (!anItem) {
+                anItem = new QListBoxText(aText);
+                myElements->insertItem(anItem);
+              }
+              myElements->setSelected(anItem, true);
+            }
+          }
+          catch (const SALOME::SALOME_Exception& ex) {
+            SalomeApp_Tools::QtCatchCorbaException(ex);
+          }
+        }
+      }
+    }
+    mySelectSubMesh->setChecked(false);
+    myIsBusy = false;
+    onListSelectionChanged();
+
+  } else if (myCurrentLineEdit == myGroupLine) {
+    //SALOME_ListIteratorOfListIO anIt (mySelectionMgr->StoredIObjects());
+    SALOME_ListIO aList;
+    mySelectionMgr->selectedObjects( aList );
+    
+    SALOME_ListIteratorOfListIO anIt (aList);
+    for (; anIt.More(); anIt.Next()) {
+      SMESH::SMESH_Group_var aGroup =
+        SMESH::IObjectToInterface<SMESH::SMESH_Group>(anIt.Value());
+      if (!aGroup->_is_nil()) {
+       // check if mesh is the same
+       if (aGroup->GetType() == aType && aGroup->GetMesh()->GetId() == myMesh->GetId()) {
+         SMESH::long_array_var anElements = aGroup->GetListOfID();
+         int k = anElements->length();
+         QListBoxItem* anItem = 0;
+         for (int i = 0; i < k; i++) {
+           QString aText = QString::number(anElements[i]);
+           anItem = myElements->findItem(aText, Qt::ExactMatch);
+           if (!anItem) {
+             anItem = new QListBoxText(aText);
+             myElements->insertItem(anItem);
+           }
+           myElements->setSelected(anItem, true);
+         }
+       }
+      }
+    }
+    mySelectGroup->setChecked(false);
+    myIsBusy = false;
+    onListSelectionChanged();
+
+  } else if (myCurrentLineEdit == myGeomGroupLine && !CORBA::is_nil(myGeomGroup)) {
+    _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+    GEOM::GEOM_IGroupOperations_var aGroupOp =
+      SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId());
+
+    SMESH::ElementType aGroupType = SMESH::ALL;
+    switch(aGroupOp->GetType(myGeomGroup)) {
+    case 7: aGroupType = SMESH::NODE; break;
+    case 6: aGroupType = SMESH::EDGE; break;
+    case 4: aGroupType = SMESH::FACE; break;
+    case 2: aGroupType = SMESH::VOLUME; break;
+    default: myIsBusy = false; return;
+    }
+
+    if (aGroupType == aType) {
+      _PTR(SObject) aGroupSO =
+        //aStudy->FindObjectIOR(aStudy->ConvertObjectToIOR(myGeomGroup));
+        aStudy->FindObjectIOR(myGeomGroup->GetStudyEntry());
+      // Construct filter
+      SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
+      SMESH::Filter_var aFilter = aFilterMgr->CreateFilter();
+      SMESH::BelongToGeom_var aBelongToGeom = aFilterMgr->CreateBelongToGeom();;
+      aBelongToGeom->SetGeom(myGeomGroup);
+      aBelongToGeom->SetShapeName(aGroupSO->GetName().c_str());
+      aBelongToGeom->SetElementType(aType);
+      aFilter->SetPredicate(aBelongToGeom);
+
+      SMESH::long_array_var anElements = aFilter->GetElementsId(myMesh);
+
+      int k = anElements->length();
+      QListBoxItem* anItem = 0;
+      for (int i = 0; i < k; i++) {
+       QString aText = QString::number(anElements[i]);
+       anItem = myElements->findItem(aText, Qt::ExactMatch);
+       if (!anItem) {
+         anItem = new QListBoxText(aText);
+         myElements->insertItem(anItem);
+       }
+       myElements->setSelected(anItem, true);
+      }
+    }
+
+    //VSR: mySelectGeomGroup->setChecked(false);
+    myIsBusy = false;
+    onListSelectionChanged();
+  }
+  myIsBusy = false;
+  //  mySelectionMgr->clearSelected();
+  updateButtons();
+}
+
+//=================================================================================
+// function : onRemove()
+// purpose  :
+//=================================================================================
+void SMESHGUI_GroupDlg::onRemove()
+{
+  myIsBusy = true;
+  if (myCurrentLineEdit == 0) {
+    for (int i = myElements->count(); i > 0; i--) {
+      if (myElements->isSelected(i-1)) {
+       myElements->removeItem(i-1);
+      }
+    }
+  } else {
+    SALOME_ListIO aList;
+    mySelectionMgr->selectedObjects( aList );
+
+    int aNbSel = aList.Extent();
+
+    if (aNbSel == 0) { myIsBusy = false; return; }
+
+    SMESH::ElementType aType = SMESH::ALL;
+    switch(myTypeId) {
+    case 0: aType = SMESH::NODE; break;
+    case 1: aType = SMESH::EDGE; break;
+    case 2: aType = SMESH::FACE; break;
+    case 3: aType = SMESH::VOLUME; break;
+    }
+
+    if (myCurrentLineEdit == mySubMeshLine) {
+      //SALOME_ListIteratorOfListIO anIt (mySelectionMgr->StoredIObjects());
+      SALOME_ListIO aList;
+      mySelectionMgr->selectedObjects( aList );
+
+      SALOME_ListIteratorOfListIO anIt (aList);
+      for (; anIt.More(); anIt.Next()) {
+       SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIt.Value());
+       if (!aSubMesh->_is_nil()) {
+         // check if mesh is the same
+         if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) {
+           if (aType == SMESH::NODE) {
+             try {
+               SMESH::long_array_var anElements = aSubMesh->GetNodesId();
+               int k = anElements->length();
+               QListBoxItem* anItem = 0;
+               for (int i = 0; i < k; i++) {
+                 anItem = myElements->findItem(QString::number(anElements[i]), Qt::ExactMatch);
+                 if (anItem) delete anItem;
+               }
+             }
+             catch (const SALOME::SALOME_Exception& ex) {
+               SalomeApp_Tools::QtCatchCorbaException(ex);
+             }
+           }
+           else {
+             try {
+               SMESH::long_array_var anElements = aSubMesh->GetElementsId();
+               int k = anElements->length();
+               QListBoxItem* anItem = 0;
+               for (int i = 0; i < k; i++) {
+                 anItem = myElements->findItem(QString::number(anElements[i]), Qt::ExactMatch);
+                 if (anItem) delete anItem;
+               }
+             }
+             catch (const SALOME::SALOME_Exception& ex) {
+               SalomeApp_Tools::QtCatchCorbaException(ex);
+             }
+           }
+         }
+       }
+      }
+    }
+    else if (myCurrentLineEdit == myGroupLine) {
+      Standard_Boolean aRes;
+      //SALOME_ListIteratorOfListIO anIt (mySelectionMgr->StoredIObjects());
+      SALOME_ListIO aList;
+      mySelectionMgr->selectedObjects( aList );
+
+      SALOME_ListIteratorOfListIO anIt (aList);
+      for (; anIt.More(); anIt.Next()) {
+       SMESH::SMESH_Group_var aGroup = SMESH::IObjectToInterface<SMESH::SMESH_Group>(anIt.Value());
+       if (aRes && !aGroup->_is_nil()) {
+         // check if mesh is the same
+         if (aGroup->GetType() == aType && aGroup->GetMesh()->GetId() == myMesh->GetId()) {
+           SMESH::long_array_var anElements = aGroup->GetListOfID();
+           int k = anElements->length();
+           QListBoxItem* anItem = 0;
+           for (int i = 0; i < k; i++) {
+             anItem = myElements->findItem(QString::number(anElements[i]), Qt::ExactMatch);
+             if (anItem) delete anItem;
+           }
+         }
+       }
+      }
+    }
+  }
+  myIsBusy = false;
+  updateButtons();
+}
+
+//=================================================================================
+// function : onSort()
+// purpose  :
+//=================================================================================
+void SMESHGUI_GroupDlg::onSort()
+{
+  // PAL5412: sorts items in ascending by "string" value
+  // myElements->sort(true);
+  // myElements->update();
+  int i, k = myElements->count();
+  if (k > 0) {
+    myIsBusy = true;
+    QStringList aSelected;
+    std::vector<int> anArray(k);
+    //    QMemArray<int> anArray(k);
+    QListBoxItem* anItem;
+    // fill the array
+    for (anItem = myElements->firstItem(), i = 0; anItem != 0; anItem = anItem->next(), i++) {
+      anArray[i] = anItem->text().toInt();
+      if (anItem->isSelected())
+       aSelected.append(anItem->text());
+    }
+    // sort & update list
+    std::sort(anArray.begin(), anArray.end());
+    //    anArray.sort();
+    myElements->clear();
+    for (i = 0; i < k; i++) {
+      myElements->insertItem(QString::number(anArray[i]));
+    }
+    for (QStringList::iterator it = aSelected.begin(); it != aSelected.end(); ++it) {
+      anItem = myElements->findItem(*it, Qt::ExactMatch);
+      if (anItem) myElements->setSelected(anItem, true);
+    }
+    myIsBusy = false;
+  }
+}
+
+//=================================================================================
+// function : closeEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_GroupDlg::closeEvent (QCloseEvent*)
+{
+  onClose();
+}
+
+//=================================================================================
+// function : SMESHGUI_GroupDlg::onClose
+// purpose  : SLOT called when "Close" button pressed. Close dialog
+//=================================================================================
+void SMESHGUI_GroupDlg::onClose()
+{
+  if (SMESH::GetCurrentVtkView()) {
+    SMESH::RemoveFilters(); // PAL6938 -- clean all mesh entity filters
+    SMESH::SetPointRepresentation(false);
+    SMESH::SetPickable();
+  }
+
+  mySelectionMgr->clearSelected();
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    aViewWindow->SetSelectionMode(ActorSelection);
+  mySelectionMgr->clearFilters();
+  mySMESHGUI->ResetState();
+
+  reject();
+}
+
+//=================================================================================
+// function : SMESHGUI_GroupDlg::onDeactivate
+// purpose  : SLOT called when dialog must be deativated
+//=================================================================================
+void SMESHGUI_GroupDlg::onDeactivate()
+{
+  mySMESHGUI->ResetState();
+  setEnabled(false);
+}
+
+//=================================================================================
+// function : SMESHGUI_GroupDlg::enterEvent
+// purpose  : Event filter
+//=================================================================================
+void SMESHGUI_GroupDlg::enterEvent (QEvent*)
+{
+  if (!isEnabled()) {
+    mySMESHGUI->EmitSignalDeactivateDialog();
+    setEnabled(true);
+    mySelectionMode = -1;
+    setSelectionMode(myTypeId);
+    //mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+    mySMESHGUI->SetActiveDialogBox(this);
+    mySMESHGUI->SetState(800);
+  }
+}
+
+//=================================================================================
+// function : hideEvent
+// purpose  : caused by ESC key
+//=================================================================================
+void SMESHGUI_GroupDlg::hideEvent (QHideEvent*)
+{
+  if (!isMinimized())
+    onClose();
+}
diff --git a/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx
new file mode 100755 (executable)
index 0000000..2887e3c
--- /dev/null
@@ -0,0 +1,1298 @@
+//  SMESH SMESHGUI : GUI for SMESH component
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+//  File   : SMESHGUI_MultiEditDlg.cxx
+//  Author : Sergey LITONIN
+//  Module : SMESH
+
+#include "SMESHGUI_MultiEditDlg.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_Filter.h"
+#include "SMESHGUI_FilterDlg.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_FilterUtils.h"
+#include "SMESHGUI_SpinBox.h"
+
+#include "SMESH_Actor.h"
+#include "SMESH_TypeFilter.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_MeshElement.hxx"
+
+#include "SUIT_ResourceMgr.h"
+#include "SUIT_Desktop.h"
+
+#include "SalomeApp_SelectionMgr.h"
+#include "SALOME_ListIO.hxx"
+#include "SALOME_ListIteratorOfListIO.hxx"
+
+#include "SVTK_Selector.h"
+#include "SVTK_ViewModel.h"
+#include "SVTK_ViewWindow.h"
+#include "SVTK_InteractorStyle.h"
+
+// OCCT Includes
+#include <Precision.hxx>
+#include <TColStd_IndexedMapOfInteger.hxx>
+#include <TColStd_DataMapOfIntegerInteger.hxx>
+#include <TColStd_MapIteratorOfMapOfInteger.hxx>
+
+// VTK Includes
+#include <vtkCell3D.h>
+#include <vtkQuad.h>
+#include <vtkTriangle.h>
+#include <vtkPolygon.h>
+#include <vtkConvexPointSet.h>
+#include <vtkIdList.h>
+#include <vtkIntArray.h>
+#include <vtkCellArray.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkDataSetMapper.h>
+
+// QT Includes
+#include <qframe.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlistbox.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qgroupbox.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qapplication.h>
+#include <qradiobutton.h>
+#include <qhbuttongroup.h>
+
+// IDL Headers
+#include "SALOMEconfig.h"
+#include CORBA_SERVER_HEADER(SMESH_Group)
+
+#define SPACING 5
+#define MARGIN  10
+
+/*!
+ *  Class       : SMESHGUI_MultiEditDlg
+ *  Description : Description : Inversion of the diagonal of a pseudo-quadrangle formed by
+ *                2 neighboring triangles with 1 common edge
+ */
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::SMESHGUI_MultiEditDlg
+// Purpose : Constructor
+//=======================================================================
+SMESHGUI_MultiEditDlg
+::SMESHGUI_MultiEditDlg(SMESHGUI* theModule,
+                       const int theMode,
+                       const bool the3d2d,
+                       const char* theName):
+  QDialog(SMESH::GetDesktop(theModule),
+         theName,
+         false,
+         WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose),
+    mySelector(SMESH::GetViewWindow(theModule)->GetSelector()),
+    mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
+    mySMESHGUI(theModule)
+{
+  myFilterDlg = 0;
+  myEntityType = 0;
+
+  myFilterType = theMode;
+  QVBoxLayout* aDlgLay = new QVBoxLayout(this, MARGIN, SPACING);
+
+  QFrame* aMainFrame = createMainFrame  (this, the3d2d);
+  QFrame* aBtnFrame  = createButtonFrame(this);
+
+  aDlgLay->addWidget(aMainFrame);
+  aDlgLay->addWidget(aBtnFrame);
+
+  aDlgLay->setStretchFactor(aMainFrame, 1);
+  aDlgLay->setStretchFactor(aBtnFrame, 0);
+  Init();
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::createMainFrame
+// Purpose : Create frame containing dialog's input fields
+//=======================================================================
+QFrame* SMESHGUI_MultiEditDlg::createMainFrame (QWidget* theParent, const bool the3d2d)
+{
+  QGroupBox* aMainGrp = new QGroupBox(1, Qt::Horizontal, theParent);
+  aMainGrp->setFrameStyle(QFrame::NoFrame);
+  aMainGrp->setInsideMargin(0);
+
+  QPixmap aPix (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_SELECT")));
+
+  // "Selected cells" group
+  mySelGrp = new QGroupBox(1, Qt::Horizontal,  aMainGrp);
+
+  myEntityTypeGrp = 0;
+  if (the3d2d) {
+    myEntityTypeGrp = new QHButtonGroup(tr("SMESH_ELEMENTS_TYPE"), mySelGrp);
+    (new QRadioButton(tr("SMESH_FACE"),   myEntityTypeGrp))->setChecked(true);
+    (new QRadioButton(tr("SMESH_VOLUME"), myEntityTypeGrp));
+    myEntityType = myEntityTypeGrp->id(myEntityTypeGrp->selected());
+  }
+
+  QFrame* aFrame = new QFrame(mySelGrp);
+
+  myListBox = new QListBox(aFrame);
+  myListBox->setSelectionMode(QListBox::Extended);
+  myListBox->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding));
+  myListBox->installEventFilter(this);
+
+  myFilterBtn = new QPushButton(tr("FILTER")   , aFrame);
+  myAddBtn    = new QPushButton(tr("ADD")      , aFrame);
+  myRemoveBtn = new QPushButton(tr("REMOVE")   , aFrame);
+  mySortBtn   = new QPushButton(tr("SORT_LIST"), aFrame);
+
+  QGridLayout* aLay = new QGridLayout(aFrame, 5, 2, 0, 5);
+  aLay->addMultiCellWidget(myListBox, 0, 4, 0, 0);
+  aLay->addWidget(myFilterBtn, 0, 1);
+  aLay->addWidget(myAddBtn, 1, 1);
+  aLay->addWidget(myRemoveBtn, 2, 1);
+  aLay->addWidget(mySortBtn, 3, 1);
+
+  QSpacerItem* aSpacer = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
+  aLay->addItem(aSpacer, 4, 1);
+
+  myToAllChk = new QCheckBox(tr("TO_ALL"), mySelGrp);
+
+  // Split/Join criterion group
+  myCriterionGrp = new QGroupBox(3, Qt::Vertical, tr("SPLIT_JOIN_CRITERION"), aMainGrp);
+
+  myGroupChoice = new QButtonGroup(3, Qt::Vertical, myCriterionGrp);
+  myGroupChoice->setInsideMargin(0);
+  myGroupChoice->setFrameStyle(QFrame::NoFrame);
+  (new QRadioButton(tr("USE_DIAGONAL_1_3"), myGroupChoice))->setChecked(true);
+  (new QRadioButton(tr("USE_DIAGONAL_2_4"), myGroupChoice));
+  (new QRadioButton(tr("USE_NUMERIC_FUNC"), myGroupChoice));
+
+  myComboBoxFunctor = new QComboBox(myCriterionGrp);
+  myComboBoxFunctor->insertItem(tr("ASPECTRATIO_ELEMENTS"));
+  myComboBoxFunctor->insertItem(tr("MINIMUMANGLE_ELEMENTS"));
+  myComboBoxFunctor->insertItem(tr("SKEW_ELEMENTS"));
+  myComboBoxFunctor->insertItem(tr("AREA_ELEMENTS"));
+  //myComboBoxFunctor->insertItem(tr("LENGTH2D_EDGES")); // for existing elements only
+  //myComboBoxFunctor->insertItem(tr("MULTI2D_BORDERS")); // for existing elements only
+  myComboBoxFunctor->setCurrentItem(0);
+
+  myCriterionGrp->hide();
+  myGroupChoice->hide();
+  myComboBoxFunctor->setEnabled(false);
+
+  // "Select from" group
+  QGroupBox* aGrp = new QGroupBox(3, Qt::Horizontal, tr("SELECT_FROM"), aMainGrp);
+
+  mySubmeshChk = new QCheckBox(tr("SMESH_SUBMESH"), aGrp);
+  mySubmeshBtn = new QPushButton(aGrp);
+  mySubmesh = new QLineEdit(aGrp);
+  mySubmesh->setReadOnly(true);
+  mySubmeshBtn->setPixmap(aPix);
+
+  myGroupChk = new QCheckBox(tr("SMESH_GROUP"), aGrp);
+  myGroupBtn = new QPushButton(aGrp);
+  myGroup = new QLineEdit(aGrp);
+  myGroup->setReadOnly(true);
+  myGroupBtn->setPixmap(aPix);
+
+  return aMainGrp;
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::createButtonFrame
+// Purpose : Create frame containing buttons
+//=======================================================================
+QFrame* SMESHGUI_MultiEditDlg::createButtonFrame (QWidget* theParent)
+{
+  QFrame* aFrame = new QFrame (theParent);
+  aFrame->setFrameStyle(QFrame::Box | QFrame::Sunken);
+
+  myOkBtn     = new QPushButton (tr("SMESH_BUT_OK"   ), aFrame);
+  myApplyBtn  = new QPushButton (tr("SMESH_BUT_APPLY"), aFrame);
+  myCloseBtn  = new QPushButton (tr("SMESH_BUT_CLOSE"), aFrame);
+
+  QSpacerItem* aSpacer = new QSpacerItem (0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
+
+  QHBoxLayout* aLay = new QHBoxLayout (aFrame, MARGIN, SPACING);
+
+  aLay->addWidget(myOkBtn);
+  aLay->addWidget(myApplyBtn);
+  aLay->addItem(aSpacer);
+  aLay->addWidget(myCloseBtn);
+
+  return aFrame;
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::isValid
+// Purpose : Verify validity of input data
+//=======================================================================
+bool SMESHGUI_MultiEditDlg::isValid (const bool /*theMess*/) const
+{
+  return (!myMesh->_is_nil() &&
+          (myListBox->count() > 0 || (myToAllChk->isChecked() && myActor)));
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg
+// Purpose : Destructor
+//=======================================================================
+SMESHGUI_MultiEditDlg::~SMESHGUI_MultiEditDlg()
+{
+  if (myFilterDlg != 0)
+  {
+    myFilterDlg->reparent(0, QPoint());
+    delete myFilterDlg;
+  }
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::eventFilter
+// Purpose : event filter
+//=======================================================================
+bool SMESHGUI_MultiEditDlg::eventFilter (QObject* object, QEvent* event)
+{
+  if (object == myListBox && event->type() == QEvent::KeyPress) {
+    QKeyEvent* ke = (QKeyEvent*)event;
+    if (ke->key() == Key_Delete)
+      onRemoveBtn();
+  }
+  return QDialog::eventFilter(object, event);
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::getNumericalFunctor
+// Purpose :
+//=======================================================================
+SMESH::NumericalFunctor_ptr SMESHGUI_MultiEditDlg::getNumericalFunctor()
+{
+  SMESH::NumericalFunctor_var aNF = SMESH::NumericalFunctor::_nil();
+
+  SMESH::FilterManager_var aFilterMgr = SMESH::GetFilterManager();
+  if (aFilterMgr->_is_nil())
+    return aNF._retn();
+
+  if (myComboBoxFunctor->currentText() == tr("ASPECTRATIO_ELEMENTS"))
+    aNF = aFilterMgr->CreateAspectRatio();
+  else if (myComboBoxFunctor->currentText() == tr("WARP_ELEMENTS"))
+    aNF = aFilterMgr->CreateWarping();
+  else if (myComboBoxFunctor->currentText() == tr("MINIMUMANGLE_ELEMENTS"))
+    aNF = aFilterMgr->CreateMinimumAngle();
+  else if (myComboBoxFunctor->currentText() == tr("TAPER_ELEMENTS"))
+    aNF = aFilterMgr->CreateTaper();
+  else if (myComboBoxFunctor->currentText() == tr("SKEW_ELEMENTS"))
+    aNF = aFilterMgr->CreateSkew();
+  else if (myComboBoxFunctor->currentText() == tr("AREA_ELEMENTS"))
+    aNF = aFilterMgr->CreateArea();
+  else if (myComboBoxFunctor->currentText() == tr("LENGTH2D_EDGES"))
+    aNF = aFilterMgr->CreateLength2D();
+  else if (myComboBoxFunctor->currentText() == tr("MULTI2D_BORDERS"))
+    aNF = aFilterMgr->CreateMultiConnection2D();
+  else ;
+
+  return aNF._retn();
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::Init
+// Purpose : Init dialog fields, connect signals and slots, show dialog
+//=======================================================================
+void SMESHGUI_MultiEditDlg::Init()
+{
+  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+  myListBox->clear();
+  myIds.Clear();
+  myBusy = false;
+  myActor = 0;
+  emit ListContensChanged();
+
+  // main buttons
+  connect(myOkBtn,    SIGNAL(clicked()), SLOT(onOk()));
+  connect(myCloseBtn, SIGNAL(clicked()), SLOT(onClose()));
+  connect(myApplyBtn, SIGNAL(clicked()), SLOT(onApply()));
+
+  // selection and SMESHGUI
+  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionDone()));
+  connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), SLOT(onDeactivate()));
+  connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs()), SLOT(onClose()));
+
+  // dialog controls
+  connect(myFilterBtn, SIGNAL(clicked()), SLOT(onFilterBtn()  ));
+  connect(myAddBtn   , SIGNAL(clicked()), SLOT(onAddBtn()     ));
+  connect(myRemoveBtn, SIGNAL(clicked()), SLOT(onRemoveBtn()  ));
+  connect(mySortBtn  , SIGNAL(clicked()), SLOT(onSortListBtn()));
+
+  connect(mySubmeshChk, SIGNAL(stateChanged(int)), SLOT(onSubmeshChk()));
+  connect(myGroupChk  , SIGNAL(stateChanged(int)), SLOT(onGroupChk()  ));
+  connect(myToAllChk  , SIGNAL(stateChanged(int)), SLOT(onToAllChk()  ));
+
+  if (myEntityTypeGrp)
+    connect(myEntityTypeGrp, SIGNAL(clicked(int)), SLOT(on3d2dChanged(int)));
+
+  connect(myListBox, SIGNAL(selectionChanged()), SLOT(onListSelectionChanged()));
+
+  onSelectionDone();
+
+  // set selection mode
+  setSelectionMode();
+  updateButtons();
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::onOk
+// Purpose : SLOT called when "Ok" button pressed.
+//           Assign filters VTK viewer and close dialog
+//=======================================================================
+void SMESHGUI_MultiEditDlg::onOk()
+{
+  if (onApply())
+    onClose();
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::getIds
+// Purpose : Retrive identifiers from list box
+//=======================================================================
+SMESH::long_array_var SMESHGUI_MultiEditDlg::getIds()
+{
+  SMESH::long_array_var anIds = new SMESH::long_array;
+
+  if (myToAllChk->isChecked())
+  {
+    myIds.Clear();
+    SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
+    if (!anActor)
+      anActor = myActor;
+    if (anActor != 0)
+    {
+      TVisualObjPtr aVisualObj = anActor->GetObject();
+      vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid();
+      if (aGrid != 0) {
+        for (int i = 0, n = aGrid->GetNumberOfCells(); i < n; i++) {
+          vtkCell* aCell = aGrid->GetCell(i);
+          if (aCell != 0) {
+           vtkTriangle* aTri = vtkTriangle::SafeDownCast(aCell);
+           vtkQuad*     aQua = vtkQuad::SafeDownCast(aCell);
+           vtkPolygon*  aPG  = vtkPolygon::SafeDownCast(aCell);
+
+           vtkCell3D*   a3d  = vtkCell3D::SafeDownCast(aCell);
+           vtkConvexPointSet* aPH = vtkConvexPointSet::SafeDownCast(aCell);
+
+           if (aTri && myFilterType == SMESHGUI_TriaFilter ||
+                aQua && myFilterType == SMESHGUI_QuadFilter ||
+                (aTri || aQua || aPG) && myFilterType == SMESHGUI_FaceFilter ||
+                (a3d || aPH) && myFilterType == SMESHGUI_VolumeFilter) {
+              int anObjId = aVisualObj->GetElemObjId(i);
+              myIds.Add(anObjId);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  anIds->length(myIds.Extent());
+  TColStd_MapIteratorOfMapOfInteger anIter(myIds);
+  for (int i = 0; anIter.More(); anIter.Next() )
+  {
+    anIds[ i++ ] = anIter.Key();
+  }
+  return anIds._retn();
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::onClose
+// Purpose : SLOT called when "Close" button pressed. Close dialog
+//=======================================================================
+void SMESHGUI_MultiEditDlg::onClose()
+{
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    aViewWindow->SetSelectionMode(ActorSelection);
+  disconnect(mySelectionMgr, 0, this, 0);
+  disconnect(mySMESHGUI, 0, this, 0);
+  mySMESHGUI->ResetState();
+
+  SMESH::RemoveFilters();
+  SMESH::SetPickable();
+
+  mySelectionMgr->clearSelected();
+  mySelectionMgr->clearFilters();
+
+  reject();
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::onSelectionDone
+// Purpose : SLOT called when selection changed
+//=======================================================================
+void SMESHGUI_MultiEditDlg::onSelectionDone()
+{
+  if (myBusy || !isEnabled()) return;
+  myBusy = true;
+
+  const SALOME_ListIO& aList = mySelector->StoredIObjects();
+
+  int nbSel = aList.Extent();
+  myListBox->clearSelection();
+
+  if (mySubmeshChk->isChecked() || myGroupChk->isChecked()) {
+    QLineEdit* aNameEdit = mySubmeshChk->isChecked() ? mySubmesh : myGroup;
+    if (nbSel == 1) {
+      Handle(SALOME_InteractiveObject) anIO = aList.First();
+      QString aName = "";
+      SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aName);
+      anIO.IsNull() ? aNameEdit->clear() : aNameEdit->setText(aName);
+
+      if (mySubmeshChk->isChecked()) {
+        SMESH::SMESH_subMesh_var aSubMesh =
+          SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIO);
+        if (!aSubMesh->_is_nil())
+          myMesh = aSubMesh->GetFather();
+      } else {
+        SMESH::SMESH_GroupBase_var aGroup =
+          SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIO);
+        if (!aGroup->_is_nil())
+          myMesh = aGroup->GetMesh();
+      }
+    } else if (nbSel > 1) {
+      QString aStr = mySubmeshChk->isChecked() ?
+        tr("SMESH_SUBMESH_SELECTED") : tr("SMESH_GROUP_SELECTED");
+      aNameEdit->setText(aStr.arg(nbSel));
+    } else {
+      aNameEdit->clear();
+    }
+  } else if (nbSel == 1) {
+    QString aListStr = "";
+    Handle(SALOME_InteractiveObject) anIO = aList.First();
+    int aNbItems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aListStr);
+    if (aNbItems > 0) {
+      QStringList anElements = QStringList::split(" ", aListStr);
+      QListBoxItem* anItem = 0;
+      for (QStringList::iterator it = anElements.begin(); it != anElements.end(); ++it) {
+        anItem = myListBox->findItem(*it, Qt::ExactMatch);
+        if (anItem) myListBox->setSelected(anItem, true);
+      }
+    }
+
+    myMesh = SMESH::GetMeshByIO(anIO);
+  }
+
+  if (nbSel == 1) {
+    myActor = SMESH::FindActorByEntry(aList.First()->getEntry());
+    if (!myActor)
+      myActor = SMESH::FindActorByObject(myMesh);
+    SVTK_InteractorStyle* aStyle = SMESH::GetInteractorStyle();
+    Handle(VTKViewer_Filter) aFilter = aStyle->GetFilter(myFilterType);
+    if (!aFilter.IsNull())
+      aFilter->SetActor(myActor);
+  }
+  myBusy = false;
+
+  updateButtons();
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::onDeactivate
+// Purpose : SLOT called when dialog must be deativated
+//=======================================================================
+void SMESHGUI_MultiEditDlg::onDeactivate()
+{
+  setEnabled(false);
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::enterEvent
+// Purpose : Event filter
+//=======================================================================
+void SMESHGUI_MultiEditDlg::enterEvent (QEvent*)
+{
+  if (!isEnabled()) {
+    mySMESHGUI->EmitSignalDeactivateDialog();
+    setEnabled(true);
+    setSelectionMode();
+  }
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::closeEvent
+// Purpose :
+//=======================================================================
+void SMESHGUI_MultiEditDlg::closeEvent (QCloseEvent*)
+{
+  onClose();
+}
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::hideEvent
+// Purpose : caused by ESC key
+//=======================================================================
+void SMESHGUI_MultiEditDlg::hideEvent (QHideEvent*)
+{
+  if (!isMinimized())
+    onClose();
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::onFilterBtn
+// Purpose : SLOT. Called when "Filter" button pressed.
+//           Start "Selection filters" dialog
+//=======================================================================
+void SMESHGUI_MultiEditDlg::onFilterBtn()
+{
+  if (myFilterDlg == 0) {
+    myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, entityType() ? SMESH::VOLUME : SMESH::FACE);
+    connect(myFilterDlg, SIGNAL(Accepted()), SLOT(onFilterAccepted()));
+  } else {
+    myFilterDlg->Init(entityType() ? SMESH::VOLUME : SMESH::FACE);
+  }
+
+  myFilterDlg->SetSelection();
+  myFilterDlg->SetMesh(myMesh);
+  myFilterDlg->SetSourceWg(myListBox);
+
+  myFilterDlg->show();
+}
+
+//=======================================================================
+// name    : onFilterAccepted()
+// Purpose : SLOT. Called when Filter dlg closed with OK button.
+//            Uncheck "Select submesh" and "Select group" checkboxes
+//=======================================================================
+void SMESHGUI_MultiEditDlg::onFilterAccepted()
+{
+  myIds.Clear();
+  for (int i = 0, n = myListBox->count(); i < n; i++)
+    myIds.Add(myListBox->text(i).toInt());
+
+  emit ListContensChanged();
+
+  if (mySubmeshChk->isChecked() || myGroupChk->isChecked()) {
+    mySubmeshChk->blockSignals(true);
+    myGroupChk->blockSignals(true);
+    mySubmeshChk->setChecked(false);
+    myGroupChk->setChecked(false);
+    mySubmeshChk->blockSignals(false);
+    myGroupChk->blockSignals(false);
+  }
+  updateButtons();
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::isIdValid
+// Purpose : Verify whether Id of element satisfies to filters from viewer
+//=======================================================================
+bool SMESHGUI_MultiEditDlg::isIdValid (const int theId) const
+{
+  SVTK_InteractorStyle* aStyle = SMESH::GetInteractorStyle();
+  Handle(SMESHGUI_Filter) aFilter =
+    Handle(SMESHGUI_Filter)::DownCast(aStyle->GetFilter(myFilterType));
+
+  return (!aFilter.IsNull() && aFilter->IsObjValid(theId));
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::onAddBtn
+// Purpose : SLOT. Called when "Add" button pressed.
+//           Add selected in viewer entities in list box
+//=======================================================================
+void SMESHGUI_MultiEditDlg::onAddBtn()
+{
+  const SALOME_ListIO& aList = mySelector->StoredIObjects();
+
+  int nbSelected = aList.Extent();
+  if (nbSelected == 0)
+    return;
+
+  TColStd_IndexedMapOfInteger toBeAdded;
+
+  if (!mySubmeshChk->isChecked() && !myGroupChk->isChecked()) {
+    if (nbSelected == 1)
+      mySelector->GetIndex(aList.First(),toBeAdded);
+  } else if (mySubmeshChk->isChecked()) {
+    SALOME_ListIteratorOfListIO anIter(aList);
+    for (; anIter.More(); anIter.Next()) {
+      SMESH::SMESH_subMesh_var aSubMesh =
+        SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(anIter.Value());
+      if (!aSubMesh->_is_nil()) {
+        if (aSubMesh->GetFather()->GetId() == myMesh->GetId()) {
+          SMESH::long_array_var anIds = aSubMesh->GetElementsId();
+          for (int i = 0, n = anIds->length(); i < n; i++) {
+            if (isIdValid(anIds[ i ]))
+              toBeAdded.Add(anIds[ i ]);
+          }
+        }
+      }
+    }
+  } else if (myGroupChk->isChecked()) {
+    SALOME_ListIteratorOfListIO anIter(aList);
+    for (; anIter.More(); anIter.Next()) {
+      SMESH::SMESH_GroupBase_var aGroup =
+        SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(anIter.Value());
+      if (!aGroup->_is_nil() && (aGroup->GetType() == SMESH::FACE &&
+                                 entityType() == 0 || aGroup->GetType() == SMESH::VOLUME &&
+                                 entityType() == 1)) {
+        if (aGroup->GetMesh()->GetId() == myMesh->GetId()) {
+          SMESH::long_array_var anIds = aGroup->GetListOfID();
+          for (int i = 0, n = anIds->length(); i < n; i++) {
+            if (isIdValid(anIds[ i ]))
+              toBeAdded.Add(anIds[ i ]);
+          }
+        }
+      }
+    }
+  } else {
+  }
+
+  myBusy = true;
+  bool isGroupOrSubmesh = (mySubmeshChk->isChecked() || myGroupChk->isChecked());
+  mySubmeshChk->setChecked(false);
+  myGroupChk->setChecked(false);
+  for(int i = 1; i <= toBeAdded.Extent(); i++)
+    if (myIds.Add(toBeAdded(i))) {
+      QListBoxItem * item = new QListBoxText(QString("%1").arg(toBeAdded(i)));
+      myListBox->insertItem(item);
+      myListBox->setSelected(item, true);
+    }
+  myBusy = false;
+
+  emit ListContensChanged();
+
+  if (isGroupOrSubmesh)
+    onListSelectionChanged();
+
+  updateButtons();
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::updateButtons
+// Purpose : Enable/disable buttons of dialog in accordance with current state
+//=======================================================================
+void SMESHGUI_MultiEditDlg::updateButtons()
+{
+  bool isOk = isValid(false);
+  myOkBtn->setEnabled(isOk);
+  myApplyBtn->setEnabled(isOk);
+
+  bool isListBoxNonEmpty = myListBox->count() > 0;
+  bool isToAll = myToAllChk->isChecked();
+  myFilterBtn->setEnabled(!isToAll);
+  myRemoveBtn->setEnabled(isListBoxNonEmpty && !isToAll);
+  mySortBtn->setEnabled(isListBoxNonEmpty &&!isToAll);
+
+  const SALOME_ListIO& aList = mySelector->StoredIObjects();
+
+  if (isToAll ||
+      myMesh->_is_nil() ||
+      aList.Extent() != 1 ||
+      (SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(aList.First())->_is_nil() &&
+       SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(aList.First())->_is_nil() &&
+       SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(aList.First())->_is_nil()))
+    myAddBtn->setEnabled(false);
+  else
+    myAddBtn->setEnabled(true);
+
+  mySubmeshChk->setEnabled(!isToAll);
+  mySubmeshBtn->setEnabled(mySubmeshChk->isChecked());
+  mySubmesh->setEnabled(mySubmeshChk->isChecked());
+
+  myGroupChk->setEnabled(!isToAll);
+  myGroupBtn->setEnabled(myGroupChk->isChecked());
+  myGroup->setEnabled(myGroupChk->isChecked());
+
+  if (!mySubmeshChk->isChecked())
+    mySubmesh->clear();
+  if (!myGroupChk->isChecked())
+    myGroup->clear();
+
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::onRemoveBtn
+// Purpose : SLOT. Called when "Remove" button pressed.
+//           Remove selected in list box entities
+//=======================================================================
+void SMESHGUI_MultiEditDlg::onRemoveBtn()
+{
+  myBusy = true;
+
+  for (int i = 0, n = myListBox->count(); i < n; i++)
+  {
+    for (int i = myListBox->count(); i > 0; i--) {
+      if (myListBox->isSelected(i - 1))
+      {
+        int anId = myListBox->text(i - 1).toInt();
+        myIds.Remove(anId);
+        myIds.Remove(anId);
+             myListBox->removeItem(i-1);
+      }
+    }
+  }
+  myBusy = false;
+
+  emit ListContensChanged();
+  updateButtons();
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::onSortListBtn
+// Purpose : SLOT. Called when "Sort list" button pressed.
+//           Sort entities of list box
+//=======================================================================
+void SMESHGUI_MultiEditDlg::onSortListBtn()
+{
+  myBusy = true;
+
+  int i, k = myListBox->count();
+  if (k > 0)
+  {
+    QStringList aSelected;
+    std::vector<int> anArray(k);
+    QListBoxItem* anItem;
+    for (anItem = myListBox->firstItem(), i = 0; anItem != 0; anItem = anItem->next(), i++)
+    {
+      anArray[ i ] = anItem->text().toInt();
+      if (anItem->isSelected())
+        aSelected.append(anItem->text());
+    }
+
+    std::sort(anArray.begin(), anArray.end());
+    myListBox->clear();
+    for (i = 0; i < k; i++)
+      myListBox->insertItem(QString::number(anArray[ i ]));
+
+    for (QStringList::iterator it = aSelected.begin(); it != aSelected.end(); ++it)
+    {
+      anItem = myListBox->findItem(*it, Qt::ExactMatch);
+      if (anItem)
+        myListBox->setSelected(anItem, true);
+    }
+  }
+  myBusy = false;
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::onListSelectionChanged
+// Purpose : SLOT. Called when selection in list box changed.
+//           Highlight in selected entities
+//=======================================================================
+void SMESHGUI_MultiEditDlg::onListSelectionChanged()
+{
+  if (myActor == 0 || myBusy)
+    return;
+
+  if (mySubmeshChk->isChecked() || myGroupChk->isChecked())
+    return;
+
+  SMESH_Actor * anActor = SMESH::FindActorByObject(myMesh);
+  if (!anActor)
+    anActor = myActor;
+  TVisualObjPtr anObj = anActor->GetObject();
+
+  TColStd_MapOfInteger anIndexes;
+  for (QListBoxItem* anItem = myListBox->firstItem(); anItem != 0; anItem = anItem->next())
+  {
+    if (anItem->isSelected())
+    {
+      int anId = anItem->text().toInt();
+      if (anObj->GetElemVTKId(anId) >= 0) // avoid exception in hilight
+        anIndexes.Add(anId);
+    }
+  }
+
+  mySelector->AddOrRemoveIndex(anActor->getIO(),anIndexes,false);
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    aViewWindow->highlight(anActor->getIO(),true,true);
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::onSubmeshChk
+// Purpose : SLOT. Called when state of "SubMesh" check box changed.
+//           Activate/deactivate selection of submeshes
+//=======================================================================
+void SMESHGUI_MultiEditDlg::onSubmeshChk()
+{
+  bool isChecked = mySubmeshChk->isChecked();
+  mySubmeshBtn->setEnabled(isChecked);
+  mySubmesh->setEnabled(isChecked);
+  if (!isChecked)
+    mySubmesh->clear();
+  if (isChecked && myGroupChk->isChecked())
+      myGroupChk->setChecked(false);
+
+  setSelectionMode();
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::onGroupChk
+// Purpose : SLOT. Called when state of "Group" check box changed.
+//           Activate/deactivate selection of groupes
+//=======================================================================
+void SMESHGUI_MultiEditDlg::onGroupChk()
+{
+  bool isChecked = myGroupChk->isChecked();
+  myGroupBtn->setEnabled(isChecked);
+  myGroup->setEnabled(isChecked);
+  if (!isChecked)
+    myGroup->clear();
+  if (isChecked && mySubmeshChk->isChecked())
+      mySubmeshChk->setChecked(false);
+
+  setSelectionMode();
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::onToAllChk
+// Purpose : SLOT. Called when state of "Apply to all" check box changed.
+//           Activate/deactivate selection
+//=======================================================================
+void SMESHGUI_MultiEditDlg::onToAllChk()
+{
+  bool isChecked = myToAllChk->isChecked();
+
+  if (isChecked)
+    myListBox->clear();
+
+  myIds.Clear();
+
+  emit ListContensChanged();
+
+  updateButtons();
+  setSelectionMode();
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::setSelectionMode
+// Purpose : Set selection mode
+//=======================================================================
+void SMESHGUI_MultiEditDlg::setSelectionMode()
+{
+  SMESH::RemoveFilters();
+
+  mySelectionMgr->clearSelected();
+  mySelectionMgr->clearFilters();
+
+  if (mySubmeshChk->isChecked()) {
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode(ActorSelection);
+    mySelectionMgr->installFilter(new SMESH_TypeFilter(SUBMESH));
+  }
+  else if (myGroupChk->isChecked()) {
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode(ActorSelection);
+    mySelectionMgr->installFilter(new SMESH_TypeFilter(GROUP));
+  }
+
+  if (entityType()) {
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode(VolumeSelection);
+    SMESH::SetFilter(new SMESHGUI_VolumesFilter());
+  } else {
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode(FaceSelection);
+    if (myFilterType == SMESHGUI_TriaFilter)
+      SMESH::SetFilter(new SMESHGUI_TriangleFilter());
+    else if (myFilterType == SMESHGUI_QuadFilter)
+      SMESH::SetFilter(new SMESHGUI_QuadrangleFilter());
+    else
+      SMESH::SetFilter(new SMESHGUI_FacesFilter());
+  }
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::onApply
+// Purpose : SLOT. Called when "Apply" button clicked.
+//=======================================================================
+bool SMESHGUI_MultiEditDlg::onApply()
+{
+  if (mySMESHGUI->isActiveStudyLocked())
+    return false;
+  if (!isValid(true))
+    return false;
+
+  SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
+  if (aMeshEditor->_is_nil())
+    return false;
+
+  myBusy = true;
+
+  SMESH::long_array_var anIds = getIds();
+
+  bool aResult = process(aMeshEditor, anIds.inout());
+  if (aResult) {
+    if (myActor) {
+      mySelectionMgr->clearSelected();
+      SMESH::UpdateView();
+    }
+
+    myListBox->clear();
+    myIds.Clear();
+    emit ListContensChanged();
+
+    updateButtons();
+  }
+
+  myBusy = false;
+  return aResult;
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::on3d2dChanged
+// Purpose :
+//=======================================================================
+void SMESHGUI_MultiEditDlg::on3d2dChanged (int type)
+{
+  if (myEntityType != type) {
+    myEntityType = type;
+
+    myListBox->clear();
+    myIds.Clear();
+
+    emit ListContensChanged();
+
+    if (type)
+      myFilterType = SMESHGUI_VolumeFilter;
+    else
+      myFilterType = SMESHGUI_FaceFilter;
+
+    updateButtons();
+    setSelectionMode();
+  }
+}
+
+//=======================================================================
+// name    : SMESHGUI_MultiEditDlg::entityType
+// Purpose :
+//=======================================================================
+int SMESHGUI_MultiEditDlg::entityType()
+{
+  return myEntityType;
+}
+
+/*!
+ *  Class       : SMESHGUI_ChangeOrientationDlg
+ *  Description : Modification of orientation of faces
+ */
+
+SMESHGUI_ChangeOrientationDlg
+::SMESHGUI_ChangeOrientationDlg(SMESHGUI* theModule,
+                               const char* theName):
+  SMESHGUI_MultiEditDlg(theModule, SMESHGUI_FaceFilter, true, theName)
+{
+  setCaption(tr("CAPTION"));
+}
+
+SMESHGUI_ChangeOrientationDlg::~SMESHGUI_ChangeOrientationDlg()
+{
+}
+
+bool SMESHGUI_ChangeOrientationDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
+                                             const SMESH::long_array&    theIds)
+{
+  return theEditor->Reorient(theIds);
+}
+
+/*!
+ *  Class       : SMESHGUI_UnionOfTrianglesDlg
+ *  Description : Construction of quadrangles by automatic association of triangles
+ */
+
+SMESHGUI_UnionOfTrianglesDlg
+::SMESHGUI_UnionOfTrianglesDlg(SMESHGUI* theModule,
+                              const char* theName):
+  SMESHGUI_MultiEditDlg(theModule, SMESHGUI_TriaFilter, false, theName)
+{
+  setCaption(tr("CAPTION"));
+
+  myComboBoxFunctor->setEnabled(true);
+  myComboBoxFunctor->insertItem(tr("WARP_ELEMENTS")); // for quadrangles only
+  myComboBoxFunctor->insertItem(tr("TAPER_ELEMENTS")); // for quadrangles only
+
+  // Maximum angle
+  QGroupBox* aMaxAngleGrp = new QGroupBox (2, Qt::Horizontal, myCriterionGrp);
+  aMaxAngleGrp->setInsideMargin(0);
+  aMaxAngleGrp->setFrameStyle(QFrame::NoFrame);
+  new QLabel (tr("MAXIMUM_ANGLE"), aMaxAngleGrp);
+  myMaxAngleSpin = new SMESHGUI_SpinBox (aMaxAngleGrp);
+  myMaxAngleSpin->RangeStepAndValidator(0, 180.0, 1.0, 3);
+  myMaxAngleSpin->SetValue(30.0);
+
+  myCriterionGrp->show();
+}
+
+SMESHGUI_UnionOfTrianglesDlg::~SMESHGUI_UnionOfTrianglesDlg()
+{
+}
+
+bool SMESHGUI_UnionOfTrianglesDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
+                                            const SMESH::long_array&    theIds)
+{
+  SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor();
+  double aMaxAngle = myMaxAngleSpin->GetValue() * PI / 180.0;
+  return theEditor->TriToQuad(theIds, aCriterion, aMaxAngle);
+}
+
+
+/*!
+ *  Class       : SMESHGUI_CuttingOfQuadsDlg
+ *  Description : Automatic splitting of quadrangles into triangles
+ */
+
+SMESHGUI_CuttingOfQuadsDlg
+::SMESHGUI_CuttingOfQuadsDlg(SMESHGUI* theModule,
+                            const char* theName):
+  SMESHGUI_MultiEditDlg(theModule, SMESHGUI_QuadFilter, false, theName)
+{
+  setCaption(tr("CAPTION"));
+  myPreviewActor = 0;
+
+  myPreviewChk = new QCheckBox (tr("PREVIEW"), mySelGrp);
+
+  myCriterionGrp->show();
+  myGroupChoice->show();
+  myComboBoxFunctor->setEnabled(false);
+
+  connect(myPreviewChk     , SIGNAL(stateChanged(int))   , this, SLOT(onPreviewChk()));
+  connect(myGroupChoice    , SIGNAL(clicked(int))        , this, SLOT(onCriterionRB()));
+  connect(myComboBoxFunctor, SIGNAL(activated(int))      , this, SLOT(onPreviewChk()));
+  connect(this             , SIGNAL(ListContensChanged()), this, SLOT(onPreviewChk()));
+}
+
+SMESHGUI_CuttingOfQuadsDlg::~SMESHGUI_CuttingOfQuadsDlg()
+{
+}
+
+void SMESHGUI_CuttingOfQuadsDlg::onClose()
+{
+  erasePreview();
+  SMESHGUI_MultiEditDlg::onClose();
+}
+
+bool SMESHGUI_CuttingOfQuadsDlg::process (SMESH::SMESH_MeshEditor_ptr theEditor,
+                                          const SMESH::long_array&    theIds)
+{
+  switch (myGroupChoice->id(myGroupChoice->selected())) {
+  case 0: // use diagonal 1-3
+    return theEditor->SplitQuad(theIds, true);
+  case 1: // use diagonal 2-4
+    return theEditor->SplitQuad(theIds, false);
+  default: // use numeric functor
+    break;
+  }
+
+  SMESH::NumericalFunctor_var aCriterion = getNumericalFunctor();
+  return theEditor->QuadToTri(theIds, aCriterion);
+}
+
+void SMESHGUI_CuttingOfQuadsDlg::onCriterionRB()
+{
+  if (myGroupChoice->id(myGroupChoice->selected()) == 2) // Use numeric functor
+    myComboBoxFunctor->setEnabled(true);
+  else
+    myComboBoxFunctor->setEnabled(false);
+
+  onPreviewChk();
+}
+
+void SMESHGUI_CuttingOfQuadsDlg::onPreviewChk()
+{
+  myPreviewChk->isChecked() ? displayPreview() : erasePreview();
+}
+
+void SMESHGUI_CuttingOfQuadsDlg::erasePreview()
+{
+  if (myPreviewActor == 0)
+    return;
+
+  if (SVTK_ViewWindow* vf = SMESH::GetCurrentVtkView()) {
+    vf->RemoveActor(myPreviewActor);
+    vf->Repaint();
+  }
+  myPreviewActor->Delete();
+  myPreviewActor = 0;
+}
+  
+void SMESHGUI_CuttingOfQuadsDlg::displayPreview()
+{
+  if (myActor == 0)
+    return;
+
+  if (myPreviewActor != 0)
+    erasePreview();
+
+  // get Ids of elements
+  SMESH::long_array_var anElemIds = getIds();
+  if (getIds()->length() == 0)
+    return;
+
+  SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
+  if (aMesh == 0)
+    return;
+
+  // 0 - use diagonal 1-3, 1 - use diagonal 2-4, 2 - use numerical functor
+  int aChoice = myGroupChoice->id(myGroupChoice->selected());
+  SMESH::NumericalFunctor_var aCriterion  = SMESH::NumericalFunctor::_nil();
+  SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH::SMESH_MeshEditor::_nil();
+  if (aChoice == 2) {
+    aCriterion  = getNumericalFunctor();
+    aMeshEditor = myMesh->GetMeshEditor();
+    if (aMeshEditor->_is_nil())
+      return;
+  }
+
+  //Create grid
+  vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New();
+
+  vtkIdType aNbCells = anElemIds->length() * 2;
+  vtkIdType aCellsSize = 4 * aNbCells;
+  vtkCellArray* aConnectivity = vtkCellArray::New();
+  aConnectivity->Allocate(aCellsSize, 0);
+
+  vtkPoints* aPoints = vtkPoints::New();
+  aPoints->SetNumberOfPoints(anElemIds->length() * 4);
+
+  vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
+  aCellTypesArray->SetNumberOfComponents(1);
+  aCellTypesArray->Allocate(aNbCells * aCellTypesArray->GetNumberOfComponents());
+
+  vtkIdList *anIdList = vtkIdList::New();
+  anIdList->SetNumberOfIds(3);
+
+  TColStd_DataMapOfIntegerInteger anIdToVtk;
+
+  int aNodes[ 4 ];
+  int nbPoints = -1;
+  for (int i = 0, n = anElemIds->length(); i < n; i++)
+  {
+    const SMDS_MeshElement* anElem = aMesh->FindElement(anElemIds[ i ]);
+    if (anElem == 0 || anElem->NbNodes() != 4)
+      continue;
+
+    SMDS_ElemIteratorPtr anIter = anElem->nodesIterator();
+    int k = 0;
+    while (anIter->more()) {
+      const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIter->next());
+      if (aNode)
+      {
+        if (!anIdToVtk.IsBound(aNode->GetID()))
+        {
+          aPoints->SetPoint(++nbPoints, aNode->X(), aNode->Y(), aNode->Z());
+          anIdToVtk.Bind(aNode->GetID(), nbPoints);
+        }
+
+        aNodes[ k++ ] = aNode->GetID();
+      }
+    }
+
+    if (k != 4)
+      continue;
+
+    bool isDiag13 = true;
+    if (aChoice == 0) // use diagonal 1-3
+    {
+      isDiag13 = true;
+    }
+    else if (aChoice == 1) // use diagonal 2-4
+    {
+      isDiag13 = false;
+    }
+    else // use numerical functor
+    {
+      // compare two sets of possible triangles
+      int diag = aMeshEditor->BestSplit(anElemIds[i], aCriterion);
+      if (diag == 1) // 1-3
+        isDiag13 = true;
+      else if (diag == 2) // 2-4
+        isDiag13 = false;
+      else // error
+        continue;
+    }
+
+    if (isDiag13)
+    {
+      anIdList->SetId(0, anIdToVtk(aNodes[ 0 ]));
+      anIdList->SetId(1, anIdToVtk(aNodes[ 1 ]));
+      anIdList->SetId(2, anIdToVtk(aNodes[ 2 ]));
+      aConnectivity->InsertNextCell(anIdList);
+      aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
+
+      anIdList->SetId(0, anIdToVtk(aNodes[ 2 ]));
+      anIdList->SetId(1, anIdToVtk(aNodes[ 3 ]));
+      anIdList->SetId(2, anIdToVtk(aNodes[ 0 ]));
+      aConnectivity->InsertNextCell(anIdList);
+      aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
+    }
+    else
+    {
+      anIdList->SetId(0, anIdToVtk(aNodes[ 1 ]));
+      anIdList->SetId(1, anIdToVtk(aNodes[ 2 ]));
+      anIdList->SetId(2, anIdToVtk(aNodes[ 3 ]));
+      aConnectivity->InsertNextCell(anIdList);
+      aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
+
+      anIdList->SetId(0, anIdToVtk(aNodes[ 3 ]));
+      anIdList->SetId(1, anIdToVtk(aNodes[ 0 ]));
+      anIdList->SetId(2, anIdToVtk(aNodes[ 1 ]));
+      aConnectivity->InsertNextCell(anIdList);
+      aCellTypesArray->InsertNextValue(VTK_TRIANGLE);
+    }
+  }
+
+  vtkIntArray* aCellLocationsArray = vtkIntArray::New();
+  aCellLocationsArray->SetNumberOfComponents(1);
+  aCellLocationsArray->SetNumberOfTuples(aNbCells);
+
+  aConnectivity->InitTraversal();
+  for(vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell(npts, pts); idType++)
+    aCellLocationsArray->SetValue(idType, aConnectivity->GetTraversalLocation(npts));
+
+  aGrid->SetPoints(aPoints);
+  aGrid->SetCells(aCellTypesArray, aCellLocationsArray,aConnectivity);
+
+  // Create and display actor
+  vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
+  aMapper->SetInput(aGrid);
+
+  myPreviewActor = SALOME_Actor::New();
+  myPreviewActor->PickableOff();
+  myPreviewActor->SetMapper(aMapper);
+
+  vtkProperty* aProp = vtkProperty::New();
+  aProp->SetRepresentationToWireframe();
+  aProp->SetColor(250, 0, 250);
+  aProp->SetLineWidth(myActor->GetLineWidth() + 1);
+  myPreviewActor->SetProperty(aProp);
+
+  SMESH::GetCurrentVtkView()->AddActor(myPreviewActor);
+  SMESH::GetCurrentVtkView()->Repaint();
+
+  aProp->Delete();
+  aPoints->Delete();
+  aConnectivity->Delete();
+  aGrid->Delete();
+  aMapper->Delete();
+  anIdList->Delete();
+  aCellTypesArray->Delete();
+  aCellLocationsArray->Delete();
+}
diff --git a/src/SMESHGUI/SMESHGUI_Selection.cxx b/src/SMESHGUI/SMESHGUI_Selection.cxx
new file mode 100644 (file)
index 0000000..014e88a
--- /dev/null
@@ -0,0 +1,433 @@
+
+#include "SMESHGUI_Selection.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_GEOMGenUtils.h"
+
+#include "SMESH_Type.h"
+#include "SMESH_Actor.h"
+
+#include "SalomeApp_SelectionMgr.h"
+#include "SalomeApp_Study.h"
+#include "SalomeApp_VTKSelector.h"
+
+#include "SUIT_Session.h"
+
+#include "SVTK_RenderWindowInteractor.h"
+#include "SVTK_ViewWindow.h"
+
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_Group)
+
+//=======================================================================
+//function : SMESHGUI_Selection
+//purpose  : 
+//=======================================================================
+SMESHGUI_Selection::SMESHGUI_Selection()
+: SalomeApp_Selection()
+{
+}
+
+//=======================================================================
+//function : ~SMESHGUI_Selection
+//purpose  : 
+//=======================================================================
+SMESHGUI_Selection::~SMESHGUI_Selection()
+{
+}
+
+//=======================================================================
+//function : init
+//purpose  : 
+//=======================================================================
+void SMESHGUI_Selection::init( const QString& client, SalomeApp_SelectionMgr* mgr )
+{
+  SalomeApp_Selection::init( client, mgr );
+
+  if( mgr && study() )
+  {
+    _PTR(Study) aStudy = study()->studyDS();
+
+    SUIT_DataOwnerPtrList sel;
+    mgr->selected( sel, client );
+    myDataOwners = sel;
+    SUIT_DataOwnerPtrList::const_iterator anIt = sel.begin(),
+                                          aLast = sel.end();
+    for( ; anIt!=aLast; anIt++ )
+    {
+      SUIT_DataOwner* owner = ( SUIT_DataOwner* )( (*anIt ).get() );
+      SalomeApp_DataOwner* sowner = dynamic_cast<SalomeApp_DataOwner*>( owner );
+      if( sowner )
+        myTypes.append( typeName( type( sowner, aStudy ) ) );
+      else
+        myTypes.append( "Unknown" );
+    }
+  }
+}
+
+//=======================================================================
+//function : param
+//purpose  : 
+//=======================================================================
+QtxValue SMESHGUI_Selection::param( const int ind, const QString& p ) const
+{
+  QtxValue val;
+       if ( p=="client" )        val = QtxValue( globalParam( p ) );
+  else if ( p=="type" )          val = QtxValue( myTypes[ind] );
+  else if ( p=="elemTypes" )     val = QtxValue( elemTypes( ind ) );
+  else if ( p=="numberOfNodes" ) val = QtxValue( numberOfNodes( ind ) );
+  else if ( p=="labeledTypes" )  val = QtxValue( labeledTypes( ind ) );
+  else if ( p=="shrinkMode" )    val = QtxValue( shrinkMode( ind ) );
+  else if ( p=="entityMode" )    val = QtxValue( entityMode( ind ) );
+  else if ( p=="controlMode" )   val = QtxValue( controlMode( ind ) );
+  else if ( p=="displayMode" )   val = QtxValue( displayMode( ind ) );
+  else if ( p=="isComputable" )  val = QtxValue( isComputable( ind ) );
+  else if ( p=="hasReference" )  val = QtxValue( hasReference( ind ) );
+  else if ( p=="isVisible" )     val = QtxValue( isVisible( ind ) );
+
+  // printf( "--> param() : [%s] = %s (%s)\n", p.latin1(), val.toString().latin1(), val.typeName() );
+  //if ( val.type() == QVariant::List )
+  //cout << "size: " << val.toList().count() << endl;
+  return val;
+}
+
+//=======================================================================
+//function : getVtkOwner
+//purpose  : 
+//=======================================================================
+
+SMESH_Actor* SMESHGUI_Selection::getActor( int ind ) const
+{
+  if ( ind >= 0 && ind < myDataOwners.count() ) {
+    const SalomeApp_SVTKDataOwner* owner = 
+      dynamic_cast<const SalomeApp_SVTKDataOwner*> ( myDataOwners[ ind ].get() );
+    if ( owner )    
+      return dynamic_cast<SMESH_Actor*>( owner->GetActor() );
+  }
+  return 0;
+}
+
+//=======================================================================
+//function : elemTypes
+//purpose  : may return {'Edge' 'Face' 'Volume'} at most
+//=======================================================================
+
+QValueList<QVariant> SMESHGUI_Selection::elemTypes( int ind ) const
+{
+  QValueList<QVariant> types;
+  SMESH_Actor* actor = getActor( ind );
+  if ( actor ) {
+    TVisualObjPtr object = actor->GetObject();
+    if ( object ) {
+      if ( object->GetNbEntities( SMDSAbs_Edge )) types.append( "Edge" );
+      if ( object->GetNbEntities( SMDSAbs_Face )) types.append( "Face" );
+      if ( object->GetNbEntities( SMDSAbs_Volume )) types.append( "Volume" );
+    }
+  }
+  return types;
+}
+
+//=======================================================================
+//function : labeledTypes
+//purpose  : may return {'Point' 'Cell'} at most
+//=======================================================================
+
+QValueList<QVariant> SMESHGUI_Selection::labeledTypes( int ind ) const
+{
+  QValueList<QVariant> types;
+  SMESH_Actor* actor = getActor( ind );
+  if ( actor ) {
+    if ( actor->GetPointsLabeled()) types.append( "Point" );
+    if ( actor->GetCellsLabeled()) types.append( "Cell" );
+  }
+  return types;
+}
+
+//=======================================================================
+//function : displayMode
+//purpose  : return SMESH_Actor::EReperesent
+//=======================================================================
+
+QString SMESHGUI_Selection::displayMode( int ind ) const
+{
+  SMESH_Actor* actor = getActor( ind );
+  if ( actor ) {
+    switch( actor->GetRepresentation() ) {
+    case SMESH_Actor::eEdge:    return "eEdge";
+    case SMESH_Actor::eSurface: return "eSurface";
+    case SMESH_Actor::ePoint:   return "ePoint";
+    default:;
+    }
+  }
+  return "Unknown";
+}
+
+//=======================================================================
+//function : shrinkMode
+//purpose  : return either 'IsSrunk', 'IsNotShrunk' or 'IsNotShrinkable'
+//=======================================================================
+
+QString SMESHGUI_Selection::shrinkMode( int ind ) const
+{
+  SMESH_Actor* actor = getActor( ind );
+  if ( actor && actor->IsShrunkable() ) {
+    if ( actor->IsShrunk() )
+      return "IsShrunk";
+    return "IsNotShrunk";
+  }
+  return "IsNotShrinkable";
+}
+
+//=======================================================================
+//function : entityMode
+//purpose  : may return {'Edge' 'Face' 'Volume'} at most
+//=======================================================================
+
+QValueList<QVariant> SMESHGUI_Selection::entityMode( int ind ) const
+{
+  QValueList<QVariant> types;
+  SMESH_Actor* actor = getActor( ind );
+  if ( actor ) {
+    unsigned int aMode = actor->GetEntityMode();
+    if ( aMode & SMESH_Actor::eVolumes) types.append( "Volume");
+    if ( aMode & SMESH_Actor::eFaces  ) types.append( "Face"  );
+    if ( aMode & SMESH_Actor::eEdges  ) types.append( "Edge"  );
+  }
+  return types;
+}
+
+//=======================================================================
+//function : controlMode
+//purpose  : return SMESH_Actor::eControl
+//=======================================================================
+
+QString SMESHGUI_Selection::controlMode( int ind ) const
+{
+  SMESH_Actor* actor = getActor( ind );
+  if ( actor ) {
+    switch( actor->GetControlMode() ) {
+    case SMESH_Actor::eLength:            return "eLength";
+    case SMESH_Actor::eLength2D:          return "eLength2D";
+    case SMESH_Actor::eFreeEdges:         return "eFreeEdges";
+    case SMESH_Actor::eFreeBorders:       return "eFreeBorders";
+    case SMESH_Actor::eMultiConnection:   return "eMultiConnection";
+    case SMESH_Actor::eMultiConnection2D: return "eMultiConnection2D";
+    case SMESH_Actor::eArea:              return "eArea";
+    case SMESH_Actor::eTaper:             return "eTaper";
+    case SMESH_Actor::eAspectRatio:       return "eAspectRatio";
+    case SMESH_Actor::eAspectRatio3D:     return "eAspectRatio3D";
+    case SMESH_Actor::eMinimumAngle:      return "eMinimumAngle";
+    case SMESH_Actor::eWarping:           return "eWarping";
+    case SMESH_Actor::eSkew:              return "eSkew";
+    default:;
+    }
+  }
+  return "eNone";
+}
+
+//=======================================================================
+//function : numberOfNodes
+//purpose  : 
+//=======================================================================
+
+int SMESHGUI_Selection::numberOfNodes( int ind ) const
+{
+  if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
+  {
+    CORBA::Object_var obj =
+      SMESH::DataOwnerToObject( static_cast<SalomeApp_DataOwner*>( myDataOwners[ ind ].get() ));
+    if ( ! CORBA::is_nil( obj )) {
+      SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( obj );
+      if ( ! mesh->_is_nil() )
+        return mesh->NbNodes();
+      SMESH::SMESH_subMesh_var aSubMeshObj = SMESH::SMESH_subMesh::_narrow( obj );
+      if ( !aSubMeshObj->_is_nil() )
+        return aSubMeshObj->GetNumberOfNodes(true);
+      SMESH::SMESH_GroupBase_var aGroupObj = SMESH::SMESH_GroupBase::_narrow( obj );
+      if ( !aGroupObj->_is_nil() )
+        return aGroupObj->Size();
+    }
+  }
+  return 0;
+}
+
+//=======================================================================
+//function : isComputable
+//purpose  : 
+//=======================================================================
+
+QVariant SMESHGUI_Selection::isComputable( int ind ) const
+{
+  if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
+  {
+    Handle(SALOME_InteractiveObject) io =
+      static_cast<SalomeApp_DataOwner*>( myDataOwners[ ind ].get() )->IO();
+    if ( !io.IsNull() ) {
+      SMESH::SMESH_Mesh_var mesh = SMESH::GetMeshByIO(io) ; // m,sm,gr->m
+      if ( !mesh->_is_nil() ) {
+        _PTR(SObject) so = SMESH::FindSObject( mesh );
+        if ( so ) {
+          GEOM::GEOM_Object_var shape = SMESH::GetShapeOnMeshOrSubMesh( so );
+          return QVariant( !shape->_is_nil(), 0 );
+        }
+      }
+    }
+  }
+  return QVariant( false, 0 );
+}
+
+//=======================================================================
+//function : hasReference
+//purpose  : 
+//=======================================================================
+
+QVariant SMESHGUI_Selection::hasReference( int ind ) const
+{
+  if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
+  {
+    SalomeApp_DataOwner* owner = dynamic_cast<SalomeApp_DataOwner*>( myDataOwners[ ind ].operator->() );
+    if( owner )
+    {
+      _PTR(SObject) obj ( study()->studyDS()->FindObjectID( owner->entry().latin1() ) ), ref;
+      return QVariant( obj->ReferencedObject( ref ), 0 );
+    }
+  }
+  return QVariant( false, 0 );
+}
+
+//=======================================================================
+//function : isVisible
+//purpose  : 
+//=======================================================================
+
+QVariant SMESHGUI_Selection::isVisible( int ind ) const
+{
+  if ( ind >= 0 && ind < myTypes.count() && myTypes[ind] != "Unknown" )
+  {
+    QString entry = static_cast<SalomeApp_DataOwner*>( myDataOwners[ ind ].get() )->entry();
+    SMESH_Actor* actor = SMESH::FindActorByEntry( entry.latin1() );
+    if ( actor && actor->hasIO() ) {
+      SVTK_RenderWindowInteractor* renderInter = SMESH::GetCurrentVtkView()->getRWInteractor();
+      return QVariant( renderInter->isVisible( actor->getIO() ), 0 );
+    }
+  }
+  return QVariant( false, 0 );
+}
+
+
+//=======================================================================
+//function : type
+//purpose  :
+//=======================================================================
+int SMESHGUI_Selection::type( SalomeApp_DataOwner* owner, _PTR(Study) study )
+{
+  return type( owner->entry(), study );
+}
+
+//=======================================================================
+//function : type
+//purpose  : 
+//=======================================================================
+
+int SMESHGUI_Selection::type( const QString& entry, _PTR(Study) study )
+{
+  _PTR(SObject) obj (study->FindObjectID(entry.latin1()));
+  if( !obj )
+    return -1;
+
+  _PTR(SObject) ref;
+  if( obj->ReferencedObject( ref ) )
+    obj = ref;
+
+  _PTR(SObject) objFather = obj->GetFather();
+  _PTR(SComponent) objComponent = obj->GetFatherComponent();
+
+  if( objComponent->ComponentDataType()!="SMESH" )
+    return -1;
+
+  int aLevel = obj->Depth() - objComponent->Depth(),
+      aFTag = objFather->Tag(),
+      anOTag = obj->Tag(),
+      res = -1;
+
+  switch( aLevel )
+  {
+  case 1:
+    if( anOTag>=3 )
+      res = MESH;
+    break;
+  case 2:
+    switch( aFTag )
+    {
+    case 1:
+      res = HYPOTHESIS;
+      break;
+    case 2:
+      res = ALGORITHM;
+      break;
+    }
+    break;
+  case 3:
+    switch( aFTag )
+    {
+    case 4:
+      res = SUBMESH_VERTEX;
+      break;
+    case 5:
+      res = SUBMESH_EDGE;
+      break;
+    case 7:
+      res = SUBMESH_FACE;
+      break;
+    case 9:
+      res = SUBMESH_SOLID;
+      break;
+    case 10:
+      res = SUBMESH_COMPOUND;
+      break;
+    }
+    if( aFTag>10 )
+      res = GROUP;
+
+    break;
+  }
+
+  return res;
+}
+
+//=======================================================================
+//function : typeName
+//purpose  : 
+//=======================================================================
+
+QString SMESHGUI_Selection::typeName( const int t )
+{
+  switch( t )
+  {
+  case HYPOTHESIS:
+    return "Hypothesis";
+  case ALGORITHM:
+    return "Algorithm";
+  case MESH:
+    return "Mesh";
+  case SUBMESH:
+    return "SubMesh";
+  case MESHorSUBMESH:
+    return "Mesh or submesh";
+  case SUBMESH_VERTEX:
+    return "Mesh vertex";
+  case SUBMESH_EDGE:
+    return "Mesh edge";
+  case SUBMESH_FACE:
+    return "Mesh face";
+  case SUBMESH_SOLID:
+    return "Mesh solid";
+  case SUBMESH_COMPOUND:
+    return "Mesh compound";
+  case GROUP:
+    return "Group";
+  default:
+    return "Unknown";
+  }
+}
diff --git a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx
new file mode 100644 (file)
index 0000000..c9141ec
--- /dev/null
@@ -0,0 +1,779 @@
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_Filter.h"
+
+#include <vtkRenderer.h>
+#include <vtkActorCollection.h>
+
+#include <TColStd_IndexedMapOfInteger.hxx>
+
+#include <SUIT_Desktop.h>
+#include <SUIT_Session.h>
+#include <SUIT_Study.h>
+
+#include "SalomeApp_SelectionMgr.h"
+
+#include "SVTK_Selector.h"
+#include "SVTK_ViewModel.h"
+#include "SVTK_ViewWindow.h"
+#include "SVTK_RenderWindow.h"
+#include "SVTK_InteractorStyle.h"
+#include "SVTK_RenderWindowInteractor.h"
+
+#include "utilities.h"
+
+#include "SALOMEconfig.h"
+#include CORBA_CLIENT_HEADER(SMESH_Gen)
+#include CORBA_CLIENT_HEADER(SMESH_Mesh)
+#include CORBA_CLIENT_HEADER(SMESH_Group)
+#include CORBA_CLIENT_HEADER(SMESH_Hypothesis)
+
+#include "SMESHGUI.h"
+#include "SMESH_Actor.h"
+#include "SMESH_ObjectDef.h"
+
+#include <SalomeApp_Application.h>
+#include <SalomeApp_SelectionMgr.h>
+#include <SalomeApp_Study.h>
+
+#include <SALOMEDSClient_Study.hxx>
+#include <SALOMEDSClient_SObject.hxx>
+
+#include <SALOME_ListIO.hxx>
+#include <SALOME_ListIteratorOfListIO.hxx>
+
+#include <set>
+using namespace std;
+
+namespace SMESH{
+
+  typedef map<TKeyOfVisualObj,TVisualObjPtr> TVisualObjCont;
+  static TVisualObjCont VISUAL_OBJ_CONT;
+
+  TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry){
+    TVisualObjPtr aVisualObj;
+    try{
+      TVisualObjCont::key_type aKey(theStudyId,theEntry);
+      TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey);
+      if(anIter != VISUAL_OBJ_CONT.end()){
+       aVisualObj = anIter->second;
+      }else{
+        SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SMESHGUI::activeStudy()->application() );
+       _PTR(Study) aStudy = SMESHGUI::activeStudy()->studyDS();
+       _PTR(SObject) aSObj = aStudy->FindObjectID(theEntry);
+       if(aSObj){
+         _PTR(GenericAttribute) anAttr;
+         if(aSObj->FindAttribute(anAttr,"AttributeIOR")){
+           _PTR(AttributeIOR) anIOR = anAttr;
+           CORBA::String_var aVal = anIOR->Value().c_str();
+           CORBA::Object_var anObj = app->orb()->string_to_object( aVal.in() );
+           if(!CORBA::is_nil(anObj)){
+             //Try narrow to SMESH_Mesh interafce
+             SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(anObj);
+             if(!aMesh->_is_nil()){
+               aVisualObj.reset(new SMESH_MeshObj(aMesh));
+               aVisualObj->Update();
+               TVisualObjCont::value_type aValue(aKey,aVisualObj);
+               VISUAL_OBJ_CONT.insert(aValue);
+               return aVisualObj;
+             }
+             //Try narrow to SMESH_Group interafce
+             SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(anObj);
+             if(!aGroup->_is_nil()){
+               _PTR(SObject) aFatherSObj = aSObj->GetFather();
+               if(!aFatherSObj) return aVisualObj;
+               aFatherSObj = aFatherSObj->GetFather();
+               if(!aFatherSObj) return aVisualObj;
+               CORBA::String_var anEntry = aFatherSObj->GetID().c_str();
+               TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in());
+               if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
+                 aVisualObj.reset(new SMESH_GroupObj(aGroup,aMeshObj));
+                 aVisualObj->Update();
+                 TVisualObjCont::value_type aValue(aKey,aVisualObj);
+                 VISUAL_OBJ_CONT.insert(aValue);
+                 return aVisualObj;
+               }
+             }
+             //Try narrow to SMESH_subMesh interafce
+             SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(anObj);
+             if(!aSubMesh->_is_nil()){
+               _PTR(SObject) aFatherSObj = aSObj->GetFather();
+               if(!aFatherSObj) return aVisualObj;
+               aFatherSObj = aFatherSObj->GetFather();
+               if(!aFatherSObj) return aVisualObj;
+               CORBA::String_var anEntry = aFatherSObj->GetID().c_str();
+               TVisualObjPtr aVisObj = GetVisualObj(theStudyId,anEntry.in());
+               if(SMESH_MeshObj* aMeshObj = dynamic_cast<SMESH_MeshObj*>(aVisObj.get())){
+                 aVisualObj.reset(new SMESH_subMeshObj(aSubMesh,aMeshObj));
+                 aVisualObj->Update();
+                 TVisualObjCont::value_type aValue(aKey,aVisualObj);
+                 VISUAL_OBJ_CONT.insert(aValue);
+                 return aVisualObj;
+               }
+             }
+           }
+         }
+       }
+      }
+    }catch(...){
+      INFOS("GetMeshObj - There is no SMESH_Mesh object for the SALOMEDS::Strudy and Entry!!!");
+    }
+    return aVisualObj;
+  }
+
+
+  SVTK_ViewWindow*
+  GetViewWindow(const SalomeApp_Module* theModule)
+  {
+    if (SalomeApp_Application* anApp = theModule->getApp())
+      return dynamic_cast<SVTK_ViewWindow*>(anApp->desktop()->activeWindow());
+    return NULL;
+  }
+
+  SVTK_ViewWindow* FindVtkViewWindow( SUIT_ViewManager* theMgr,
+                                          SUIT_ViewWindow* theWindow )
+  {
+    if( !theMgr )
+      return NULL;
+
+    QPtrVector<SUIT_ViewWindow> views = theMgr->getViews();
+    if( views.containsRef( theWindow ) )
+      return GetVtkViewWindow( theWindow );
+    else
+      return NULL;
+  }
+
+
+  SVTK_ViewWindow* GetVtkViewWindow(SUIT_ViewWindow* theWindow){
+    return dynamic_cast<SVTK_ViewWindow*>(theWindow);
+  }
+
+
+/*  SUIT_ViewWindow* GetActiveWindow()
+  {
+    SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
+    if( !app )
+      return NULL;
+    SUIT_ViewManager* mgr = app->activeViewManager();
+    if( mgr )
+      return mgr->getActiveView();
+    else
+      return NULL;
+  }*/
+
+  SVTK_ViewWindow* GetCurrentVtkView(){
+    return GetVtkViewWindow( GetActiveWindow() );
+  }
+
+  void RepaintViewWindow(SVTK_ViewWindow* theWindow)
+  {
+    theWindow->Repaint();
+  }
+
+  void RenderViewWindow(SVTK_ViewWindow* theWindow)
+  {
+    theWindow->getRenderer()->Render();
+    theWindow->Repaint();
+  }
+
+  SMESH_Actor* FindActorByEntry(SUIT_ViewWindow *theWindow,
+                               const char* theEntry)
+  {
+    if(SVTK_ViewWindow* aViewWindow = GetVtkViewWindow(theWindow)){
+      vtkRenderer *aRenderer = aViewWindow->getRenderer();
+      vtkActorCollection *aCollection = aRenderer->GetActors();
+      aCollection->InitTraversal();
+      while(vtkActor *anAct = aCollection->GetNextActor()){
+       if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+         if(anActor->hasIO()){
+           Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
+           if(anIO->hasEntry() && strcmp(anIO->getEntry(),theEntry) == 0){
+             return anActor;
+           }
+         }
+       }
+      }
+    }
+    return NULL;
+  }
+
+
+  SMESH_Actor* FindActorByEntry(const char* theEntry){
+    return FindActorByEntry(GetActiveWindow(),theEntry);
+  }
+
+
+  SMESH_Actor* FindActorByObject(CORBA::Object_ptr theObject){
+    SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
+    if( !app )
+      return NULL;
+
+    if(!CORBA::is_nil(theObject)){
+      _PTR(Study) aStudy = GetActiveStudyDocument();
+      CORBA::String_var anIOR = app->orb()->object_to_string( theObject );
+      _PTR(SObject) aSObject = aStudy->FindObjectIOR(anIOR.in());
+      if(aSObject){
+       CORBA::String_var anEntry = aSObject->GetID().c_str();
+       return FindActorByEntry(anEntry.in());
+      }
+    }
+    return NULL;
+  }
+
+
+  SMESH_Actor* CreateActor(_PTR(Study) theStudy,
+                          const char* theEntry,
+                          int theIsClear)
+  {
+    SMESH_Actor *anActor = NULL;
+    CORBA::Long anId = theStudy->StudyId();
+    if(TVisualObjPtr aVisualObj = GetVisualObj(anId,theEntry)){
+      _PTR(SObject) aSObj = theStudy->FindObjectID(theEntry);
+      if(aSObj){
+       _PTR(GenericAttribute) anAttr;
+       if(aSObj->FindAttribute(anAttr,"AttributeName")){
+         _PTR(AttributeName) aName = anAttr;
+         std::string aNameVal = aName->Value();
+         anActor = SMESH_Actor::New(aVisualObj,theEntry,aNameVal.c_str(),theIsClear);
+       }
+      }
+    }
+    return anActor;
+  }
+
+
+  void DisplayActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){
+    if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){
+      vtkWnd->AddActor(theActor);
+      vtkWnd->Repaint();
+    }
+  }
+
+
+  void RemoveActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){
+    if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){
+      vtkWnd->RemoveActor(theActor);
+      if(theActor->hasIO()){
+       Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
+       if(anIO->hasEntry()){
+         std::string anEntry = anIO->getEntry();
+         SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( vtkWnd->getViewManager()->study() );
+         int aStudyId = aStudy->id();
+         TVisualObjCont::key_type aKey(aStudyId,anEntry);
+         VISUAL_OBJ_CONT.erase(aKey);
+       }
+      }
+      theActor->Delete();
+      vtkWnd->Repaint();
+    }
+  }
+
+
+  void FitAll(){
+    if(SVTK_ViewWindow* wnd = GetCurrentVtkView() ){
+      wnd->onFitAll();
+      wnd->Repaint();
+    }
+  }
+
+  vtkRenderer* GetCurrentRenderer(){
+    if(SVTK_ViewWindow* wnd = GetCurrentVtkView() )
+      return wnd->getRenderer();
+    return NULL;
+  }
+
+  void RepaintCurrentView(){
+    if(SVTK_ViewWindow* wnd = GetCurrentVtkView() )
+      {
+       wnd->getRenderer()->Render();
+       wnd->Repaint(false);
+      }
+  }
+
+  void UpdateView(SUIT_ViewWindow *theWnd, EDisplaing theAction, const char* theEntry)
+  {
+    if(SVTK_ViewWindow* aViewWnd = GetVtkViewWindow(theWnd)){
+      vtkRenderer *aRenderer = aViewWnd->getRenderer();
+      vtkActorCollection *aCollection = aRenderer->GetActors();
+      aCollection->InitTraversal();
+      switch(theAction){
+      case eDisplayAll: {
+       while(vtkActor *anAct = aCollection->GetNextActor()){
+         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+           anActor->SetVisibility(true);
+         }
+       }
+       break;
+      }
+      case eDisplayOnly:
+      case eEraseAll: {
+       while(vtkActor *anAct = aCollection->GetNextActor()){
+         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+           anActor->SetVisibility(false);
+         }
+       }
+      }
+      default: {
+       if(SMESH_Actor *anActor = FindActorByEntry(theWnd,theEntry)){
+         switch(theAction) {
+           case eDisplay:
+           case eDisplayOnly:
+             anActor->SetVisibility(true);
+             break;
+           case eErase:
+             anActor->SetVisibility(false);
+             break;
+         }
+       } else {
+         switch(theAction){
+         case eDisplay:
+         case eDisplayOnly:{
+           SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( theWnd->getViewManager()->study() );
+           _PTR(Study) aDocument = aStudy->studyDS();
+           if((anActor = CreateActor(aDocument,theEntry,true))) {
+             DisplayActor(theWnd,anActor);
+             FitAll();
+           }
+           break;
+         }
+         }
+       }
+      }
+      }
+    }
+  }
+
+
+  void UpdateView(EDisplaing theAction, const char* theEntry){
+    SalomeApp_Study* aStudy = dynamic_cast< SalomeApp_Study* >( GetActiveStudy() );
+    SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( aStudy->application() );
+    SUIT_ViewWindow *aWnd = app->activeViewManager()->getActiveView();
+    UpdateView(aWnd,theAction,theEntry);
+  }
+
+  void UpdateView(){
+    if(SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView()){
+      SalomeApp_SelectionMgr* mgr = SMESHGUI::selectionMgr();
+      SALOME_ListIO selected; mgr->selectedObjects( selected );
+
+      if( selected.Extent() == 0){
+       vtkRenderer* aRenderer = aWnd->getRenderer();
+       vtkActorCollection *aCollection = aRenderer->GetActors();
+       aCollection->InitTraversal();
+       while(vtkActor *anAct = aCollection->GetNextActor()){
+         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+           if(anActor->hasIO())
+             Update(anActor->getIO(),anActor->GetVisibility());
+         }
+       }
+      }else{
+       SALOME_ListIteratorOfListIO anIter( selected );
+       for(; anIter.More(); anIter.Next()){
+         Handle(SALOME_InteractiveObject) anIO = anIter.Value();
+         Update(anIO,true);
+       }
+      }
+      RepaintCurrentView();
+    }
+  }
+
+
+  void Update(const Handle(SALOME_InteractiveObject)& theIO,
+             bool theDisplay)
+  {
+    _PTR(Study) aStudy = GetActiveStudyDocument();
+    CORBA::Long anId = aStudy->StudyId();
+    TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry());
+    if( aVisualObj )
+      aVisualObj->Update();
+    if ( theDisplay )
+      UpdateView(SMESH::eDisplay,theIO->getEntry());
+  }
+
+
+  void UpdateSelectionProp( SMESHGUI* theModule ) {
+    if( !theModule )
+      return;
+
+    SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( theModule->application() );
+    if( !app )
+    {
+      MESSAGE( "UpdateSelectionProp: Application is null" );
+      return;
+    }
+
+    SUIT_ViewManager* vm = app->activeViewManager();
+    if( !vm )
+    {
+      MESSAGE( "UpdateSelectionProp: View manager is null" );
+      return;
+    }
+
+    QPtrVector<SUIT_ViewWindow> views = vm->getViews();
+
+    SUIT_ResourceMgr* mgr = SMESH::GetResourceMgr( theModule );
+    if( !mgr )
+    {
+      MESSAGE( "UpdateSelectionProp: Resource manager is null" );
+      return;
+    }
+
+    QColor aHiColor = mgr->colorValue( "SMESH", "selection_object_color", Qt::white ),
+           aSelColor = mgr->colorValue( "SMESH", "selection_element_color", Qt::yellow ),
+          aPreColor = mgr->colorValue( "SMESH", "highlight_color", Qt::cyan );
+
+    int SW = mgr->integerValue( "SMESH", "selection_width", 5 ),
+        PW = mgr->integerValue( "SMESH", "highlight_width", 5 );
+
+    double SP1 = mgr->doubleValue( "SMESH", "selection_precision_node", 0.025 ),
+           SP2 = mgr->doubleValue( "SMESH", "selection_precision_element", 0.001 );
+
+    for ( int i=0, n=views.count(); i<n; i++ ) {
+        SVTK_ViewWindow* aVtkView = GetVtkViewWindow( views[i] );
+       if (!aVtkView) continue;
+       // update VTK viewer properties
+       SVTK_RenderWindowInteractor* anInteractor = aVtkView->getRWInteractor();
+       if (anInteractor) {
+         // mesh element selection
+         anInteractor->SetSelectionProp(aSelColor.red()/255., aSelColor.green()/255.,
+                                        aSelColor.blue()/255., SW );
+
+         // tolerances
+         anInteractor->SetSelectionTolerance(SP1, SP2);
+
+         // pre-selection
+         SVTK_InteractorStyle* aStyle =
+           dynamic_cast<SVTK_InteractorStyle*>( anInteractor->GetInteractorStyle() );
+         if (aStyle) {
+           aStyle->setPreselectionProp(aPreColor.red()/255., aPreColor.green()/255.,
+                                       aPreColor.blue()/255., PW);
+         }
+       }
+       // update actors
+       vtkRenderer* aRenderer = aVtkView->getRenderer();
+       vtkActorCollection *aCollection = aRenderer->GetActors();
+       aCollection->InitTraversal();
+       while(vtkActor *anAct = aCollection->GetNextActor()){
+         if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+           anActor->SetHighlightColor(aHiColor.red()/255., aHiColor.green()/255.,
+                                      aHiColor.blue()/255.);
+           anActor->SetPreHighlightColor(aPreColor.red()/255., aPreColor.green()/255.,
+                                         aPreColor.blue()/255.);
+         }
+       }
+    }
+  }
+
+
+  //----------------------------------------------------------------------------
+  SVTK_InteractorStyle* GetInteractorStyle(SUIT_ViewWindow *theWindow){
+    if(SVTK_ViewWindow* aWnd = GetVtkViewWindow(theWindow)){
+      if(SVTK_RenderWindowInteractor* anInteractor = aWnd->getRWInteractor()){
+       return dynamic_cast<SVTK_InteractorStyle*>( anInteractor->GetInteractorStyle() );
+      }
+    }
+    return NULL;
+  }
+
+  void SetFilter(const Handle(VTKViewer_Filter)& theFilter,
+                SVTK_InteractorStyle* theStyle)
+  {
+    if (theStyle)
+      theStyle->SetFilter(theFilter);
+  }
+
+  Handle(VTKViewer_Filter) GetFilter(int theId, SVTK_InteractorStyle* theStyle)
+  {
+    return theStyle->GetFilter(theId);
+  }
+
+  bool IsFilterPresent(int theId, SVTK_InteractorStyle* theStyle)
+  {
+    return theStyle->IsFilterPresent(theId);
+  }
+
+  void RemoveFilter(int theId, SVTK_InteractorStyle* theStyle)
+  {
+    theStyle->RemoveFilter(theId);
+  }
+
+  void RemoveFilters(SVTK_InteractorStyle* theStyle)
+  {
+    for ( int id = SMESHGUI_NodeFilter; theStyle && id < SMESHGUI_LastFilter; id++ )
+      theStyle->RemoveFilter( id );
+  }
+
+  bool IsValid(SALOME_Actor* theActor, int theCellId,
+              SVTK_InteractorStyle* theStyle)
+  {
+    return theStyle->IsValid(theActor,theCellId);
+  }
+
+
+  //----------------------------------------------------------------------------
+  void SetPointRepresentation(bool theIsVisible){
+    if(SVTK_ViewWindow* aViewWindow = GetCurrentVtkView()){
+      vtkRenderer *aRenderer = aViewWindow->getRenderer();
+      vtkActorCollection *aCollection = aRenderer->GetActors();
+      aCollection->InitTraversal();
+      while(vtkActor *anAct = aCollection->GetNextActor()){
+       if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+         if(anActor->GetVisibility()){
+           anActor->SetPointRepresentation(theIsVisible);
+         }
+       }
+      }
+      RepaintCurrentView();
+    }
+  }
+
+
+  void SetPickable(SMESH_Actor* theActor){
+    if(SVTK_ViewWindow* aWnd = GetCurrentVtkView()){
+      int anIsAllPickable = (theActor == NULL);
+      vtkRenderer *aRenderer = aWnd->getRenderer();
+      vtkActorCollection *aCollection = aRenderer->GetActors();
+      aCollection->InitTraversal();
+      while(vtkActor *anAct = aCollection->GetNextActor()){
+       if(SALOME_Actor *anActor = dynamic_cast<SALOME_Actor*>(anAct)){
+         if(anActor->GetVisibility()){
+           anActor->SetPickable(anIsAllPickable);
+         }
+       }
+      }
+      if(theActor)
+       theActor->SetPickable(!anIsAllPickable);
+      RepaintCurrentView();
+    }
+  }
+
+
+  //----------------------------------------------------------------------------
+  int GetNameOfSelectedNodes(SVTK_Selector* theSelector,
+                            const Handle(SALOME_InteractiveObject)& theIO,
+                            QString& theName)
+  {
+    theName = "";
+    TColStd_IndexedMapOfInteger aMapIndex;
+    theSelector->GetIndex(theIO,aMapIndex);
+
+    for(int i = 1; i <= aMapIndex.Extent(); i++)
+      theName += QString(" %1").arg(aMapIndex(i));
+
+    return aMapIndex.Extent();
+  }
+
+  int GetNameOfSelectedElements(SVTK_Selector* theSelector,
+                               const Handle(SALOME_InteractiveObject)& theIO,
+                               QString& theName)
+  {
+    theName = "";
+    TColStd_IndexedMapOfInteger aMapIndex;
+    theSelector->GetIndex(theIO,aMapIndex);
+
+    typedef std::set<int> TIdContainer;
+    TIdContainer anIdContainer;
+    for( int i = 1; i <= aMapIndex.Extent(); i++)
+      anIdContainer.insert(aMapIndex(i));
+
+    TIdContainer::const_iterator anIter = anIdContainer.begin();
+    for(; anIter != anIdContainer.end(); anIter++)
+      theName += QString(" %1").arg(*anIter);
+
+    return aMapIndex.Extent();
+  }
+
+
+  int GetEdgeNodes(SVTK_Selector* theSelector,
+                  const TVisualObjPtr& theVisualObject,
+                  int& theId1,
+                  int& theId2)
+  {
+    const SALOME_ListIO& selected = theSelector->StoredIObjects();
+
+    if ( selected.Extent() != 1 )
+      return -1;
+
+    Handle(SALOME_InteractiveObject) anIO = selected.First();
+    if ( anIO.IsNull() || !anIO->hasEntry() )
+      return -1;
+
+    TColStd_IndexedMapOfInteger aMapIndex;
+    theSelector->GetIndex( anIO, aMapIndex );
+    if ( aMapIndex.Extent() != 2 )
+      return -1;
+
+    int anObjId = -1, anEdgeNum = -1;
+    for ( int i = 1; i <= aMapIndex.Extent(); i++ ) {
+      int aVal = aMapIndex( i );
+      if ( aVal > 0 )
+       anObjId = aVal;
+      else
+       anEdgeNum = abs( aVal ) - 1;
+    }
+
+    if ( anObjId == -1 || anEdgeNum == -1 )
+      return -1;
+
+    return theVisualObject->GetEdgeNodes( anObjId, anEdgeNum, theId1, theId2 ) ? 1 : -1;
+  }
+
+  //----------------------------------------------------------------------------
+  int GetNameOfSelectedNodes(SalomeApp_SelectionMgr *theMgr,
+                            const Handle(SALOME_InteractiveObject)& theIO,
+                            QString& theName)
+  {
+    theName = "";
+    if(theIO->hasEntry()){
+      if(FindActorByEntry(theIO->getEntry())){
+       TColStd_IndexedMapOfInteger aMapIndex;
+       theMgr->GetIndexes(theIO,aMapIndex);
+       for(int i = 1; i <= aMapIndex.Extent(); i++){
+         theName += QString(" %1").arg(aMapIndex(i));
+       }
+       return aMapIndex.Extent();
+      }
+    }
+    return -1;
+  }
+
+  int GetNameOfSelectedNodes(SalomeApp_SelectionMgr *theMgr, QString& theName){
+    theName = "";
+    SALOME_ListIO selected; theMgr->selectedObjects( selected );
+    if(selected.Extent() == 1){
+      Handle(SALOME_InteractiveObject) anIO = selected.First();
+      return GetNameOfSelectedNodes(theMgr,anIO,theName);
+    }
+    return -1;
+  }
+
+
+  int GetNameOfSelectedElements(SalomeApp_SelectionMgr *theMgr,
+                               const Handle(SALOME_InteractiveObject)& theIO,
+                               QString& theName)
+  {
+    theName = "";
+    if(theIO->hasEntry()){
+      if(FindActorByEntry(theIO->getEntry())){
+       TColStd_IndexedMapOfInteger aMapIndex;
+       theMgr->GetIndexes(theIO,aMapIndex);
+       typedef set<int> TIdContainer;
+       TIdContainer anIdContainer;
+       for( int i = 1; i <= aMapIndex.Extent(); i++)
+         anIdContainer.insert(aMapIndex(i));
+       TIdContainer::const_iterator anIter = anIdContainer.begin();
+       for(; anIter != anIdContainer.end(); anIter++){
+         theName += QString(" %1").arg(*anIter);
+       }
+       return aMapIndex.Extent();
+      }
+    }
+    return -1;
+  }
+
+
+  int GetNameOfSelectedElements(SalomeApp_SelectionMgr *theMgr, QString& theName)
+  {
+    theName = "";
+    SALOME_ListIO selected; theMgr->selectedObjects( selected );
+
+    if( selected.Extent() == 1){
+      Handle(SALOME_InteractiveObject) anIO = selected.First();
+      return GetNameOfSelectedElements(theMgr,anIO,theName);
+    }
+    return -1;
+  }
+
+  int GetSelected(SalomeApp_SelectionMgr*      theMgr,
+                 TColStd_IndexedMapOfInteger& theMap,
+                 const bool                   theIsElement)
+  {
+    theMap.Clear();
+    SALOME_ListIO selected; theMgr->selectedObjects( selected );
+
+    if ( selected.Extent() == 1 )
+    {
+      Handle(SALOME_InteractiveObject) anIO = selected.First();
+      if ( anIO->hasEntry() ) {
+       theMgr->GetIndexes( anIO, theMap );
+      }
+    }
+    return theMap.Extent();
+  }
+
+
+  int GetEdgeNodes( SalomeApp_SelectionMgr* theMgr, int& theId1, int& theId2 )
+  {
+    SALOME_ListIO selected; theMgr->selectedObjects( selected );
+
+    if ( selected.Extent() != 1 )
+      return -1;
+
+    Handle(SALOME_InteractiveObject) anIO = selected.First();
+    if ( anIO.IsNull() || !anIO->hasEntry() )
+      return -1;
+
+    SMESH_Actor *anActor = SMESH::FindActorByEntry( anIO->getEntry() );
+    if ( anActor == 0 )
+      return -1;
+
+    TColStd_IndexedMapOfInteger aMapIndex;
+    theMgr->GetIndexes( anIO, aMapIndex );
+    if ( aMapIndex.Extent() != 2 )
+      return -1;
+
+    int anObjId = -1, anEdgeNum = -1;
+    for ( int i = 1; i <= aMapIndex.Extent(); i++ ) {
+      int aVal = aMapIndex( i );
+      if ( aVal > 0 )
+       anObjId = aVal;
+      else
+       anEdgeNum = abs( aVal );
+    }
+
+    if ( anObjId == -1 || anEdgeNum == -1 )
+      return -1;
+
+    return anActor->GetObject()->GetEdgeNodes( anObjId, anEdgeNum, theId1, theId2 ) ? 1 : -1;
+  }
+
+  void SetControlsPrecision( const long theVal )
+  {
+    if( SVTK_ViewWindow* aWnd = SMESH::GetCurrentVtkView() )
+    {
+      vtkRenderer *aRenderer = aWnd->getRenderer();
+      vtkActorCollection *aCollection = aRenderer->GetActors();
+      aCollection->InitTraversal();
+
+      while ( vtkActor *anAct = aCollection->GetNextActor())
+      {
+        if ( SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>( anAct ) )
+        {
+          anActor->SetControlsPrecision( theVal );
+          anActor->SetControlMode( anActor->GetControlMode() );
+        }
+      }
+
+    }
+  }
+}
diff --git a/src/SMESH_I/SMESH_1D_Algo_i.cxx b/src/SMESH_I/SMESH_1D_Algo_i.cxx
new file mode 100644 (file)
index 0000000..06f621d
--- /dev/null
@@ -0,0 +1,89 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESH_1D_Algo_i.cxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+using namespace std;
+#include "SMESH_1D_Algo_i.hxx"
+
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ *  SMESH_1D_Algo_i::SMESH_1D_Algo_i
+ * 
+ *  Constructor
+ */
+//=============================================================================
+
+SMESH_1D_Algo_i::SMESH_1D_Algo_i( PortableServer::POA_ptr thePOA )
+     : SALOME::GenericObj_i( thePOA ), 
+       SMESH_Hypothesis_i( thePOA ), 
+       SMESH_Algo_i( thePOA )
+{
+  MESSAGE( "SMESH_1D_Algo_i::SMESH_1D_Algo_i" );
+}
+
+//=============================================================================
+/*!
+ *  SMESH_1D_Algo_i::~SMESH_1D_Algo_i
+ * 
+ *  Destructor
+ */
+//=============================================================================
+
+SMESH_1D_Algo_i::~SMESH_1D_Algo_i()
+{
+  MESSAGE( "SMESH_1D_Algo_i::~SMESH_1D_Algo_i" );
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether algorithm supports given entity type 
+  * \param type - dimension (see SMESH::Dimension enumeration)
+  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ * 
+ * Verify whether algorithm supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================
+CORBA::Boolean SMESH_1D_Algo_i::IsDimSupported( SMESH::Dimension type )
+{
+  return type == SMESH::DIM_1D;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/SMESH_I/SMESH_1D_Algo_i.hxx b/src/SMESH_I/SMESH_1D_Algo_i.hxx
new file mode 100644 (file)
index 0000000..1112a40
--- /dev/null
@@ -0,0 +1,56 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESH_1D_Algo_i.hxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_1D_ALGO_I_HXX_
+#define _SMESH_1D_ALGO_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Hypothesis)
+
+#include "SMESH_Algo_i.hxx"
+
+// ======================================================
+// Generic 1D algorithm
+// ======================================================
+class SMESH_1D_Algo_i:
+  public virtual POA_SMESH::SMESH_1D_Algo,
+  public virtual SMESH_Algo_i
+{
+protected:
+  // Constructor : placed in protected section to prohibit creation of generic class instance
+  SMESH_1D_Algo_i( PortableServer::POA_ptr thePOA );
+
+public:
+  // Destructor
+  virtual ~SMESH_1D_Algo_i();
+  
+  // Verify whether algorithm supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
diff --git a/src/SMESH_I/SMESH_2D_Algo_i.cxx b/src/SMESH_I/SMESH_2D_Algo_i.cxx
new file mode 100644 (file)
index 0000000..00744ee
--- /dev/null
@@ -0,0 +1,75 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESH_2D_Algo_i.cxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+using namespace std;
+#include "SMESH_2D_Algo_i.hxx"
+
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ *  SMESH_2D_Algo_i::SMESH_2D_Algo_i
+ * 
+ *  Constructor
+ */
+//=============================================================================
+
+SMESH_2D_Algo_i::SMESH_2D_Algo_i( PortableServer::POA_ptr thePOA )
+     : SALOME::GenericObj_i( thePOA ), 
+       SMESH_Hypothesis_i( thePOA ), 
+       SMESH_Algo_i( thePOA ) 
+{
+  MESSAGE( "SMESH_2D_Algo_i::SMESH_2D_Algo_i" );
+}
+
+//=============================================================================
+/*!
+ *  SMESH_2D_Algo_i::~SMESH_2D_Algo_i
+ * 
+ *  Destructor
+ */
+//=============================================================================
+
+SMESH_2D_Algo_i::~SMESH_2D_Algo_i()
+{
+  MESSAGE( "SMESH_2D_Algo_i::~SMESH_2D_Algo_i" );
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether algorithm supports given entity type 
+  * \param type - dimension (see SMESH::Dimension enumeration)
+  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ * 
+ * Verify whether algorithm supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================  
+CORBA::Boolean SMESH_2D_Algo_i::IsDimSupported( SMESH::Dimension type )
+{
+  return type == SMESH::DIM_2D;
+}
diff --git a/src/SMESH_I/SMESH_2D_Algo_i.hxx b/src/SMESH_I/SMESH_2D_Algo_i.hxx
new file mode 100644 (file)
index 0000000..58664c9
--- /dev/null
@@ -0,0 +1,56 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESH_2D_Algo_i.hxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_2D_ALGO_I_HXX_
+#define _SMESH_2D_ALGO_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Hypothesis)
+
+#include "SMESH_Algo_i.hxx"
+
+// ======================================================
+// Generic 2D algorithm
+// ======================================================
+class SMESH_2D_Algo_i:
+  public virtual POA_SMESH::SMESH_2D_Algo,
+  public virtual SMESH_Algo_i
+{
+protected:
+  // Constructor : placed in protected section to prohibit creation of generic class instance
+  SMESH_2D_Algo_i( PortableServer::POA_ptr thePOA );
+
+public:
+  // Destructor
+  virtual ~SMESH_2D_Algo_i();
+  
+  // Verify whether algorithm supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
diff --git a/src/SMESH_I/SMESH_3D_Algo_i.cxx b/src/SMESH_I/SMESH_3D_Algo_i.cxx
new file mode 100644 (file)
index 0000000..14276fe
--- /dev/null
@@ -0,0 +1,76 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESH_3D_Algo_i.cxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+using namespace std;
+#include "SMESH_3D_Algo_i.hxx"
+
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ *  SMESH_3D_Algo_i::SMESH_3D_Algo_i
+ * 
+ *  Constructor
+ */
+//=============================================================================
+
+SMESH_3D_Algo_i::SMESH_3D_Algo_i( PortableServer::POA_ptr thePOA )
+     : SALOME::GenericObj_i( thePOA ), 
+       SMESH_Hypothesis_i( thePOA ), 
+       SMESH_Algo_i( thePOA )
+{
+  MESSAGE( "SMESH_3D_Algo_i::SMESH_3D_Algo_i" );
+}
+
+//=============================================================================
+/*!
+ *  SMESH_3D_Algo_i::~SMESH_3D_Algo_i
+ * 
+ *  Destructor
+ */
+//=============================================================================
+
+SMESH_3D_Algo_i::~SMESH_3D_Algo_i()
+{
+  MESSAGE( "SMESH_3D_Algo_i::~SMESH_3D_Algo_i" );
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether algorithm supports given entity type 
+  * \param type - dimension (see SMESH::Dimension enumeration)
+  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ * 
+ * Verify whether algorithm supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================  
+CORBA::Boolean SMESH_3D_Algo_i::IsDimSupported( SMESH::Dimension type )
+{
+  return type == SMESH::DIM_3D;
+}
+
diff --git a/src/SMESH_I/SMESH_3D_Algo_i.hxx b/src/SMESH_I/SMESH_3D_Algo_i.hxx
new file mode 100644 (file)
index 0000000..8589e16
--- /dev/null
@@ -0,0 +1,56 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESH_3D_Algo_i.hxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_3D_ALGO_I_HXX_
+#define _SMESH_3D_ALGO_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Hypothesis)
+
+#include "SMESH_Algo_i.hxx"
+
+// ======================================================
+// Generic 3D algorithm
+// ======================================================
+class SMESH_3D_Algo_i:
+  public virtual POA_SMESH::SMESH_3D_Algo,
+  public virtual SMESH_Algo_i
+{
+protected:
+  // Constructor : placed in protected section to prohibit creation of generic class instance
+  SMESH_3D_Algo_i( PortableServer::POA_ptr thePOA );
+
+public:
+  // Destructor
+  virtual ~SMESH_3D_Algo_i();
+  
+  // Verify whether algorithm supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx
new file mode 100644 (file)
index 0000000..42fac7d
--- /dev/null
@@ -0,0 +1,268 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESH_Mesh_i.hxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_MESH_I_HXX_
+#define _SMESH_MESH_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_Hypothesis)
+#include CORBA_CLIENT_HEADER(GEOM_Gen)
+#include CORBA_CLIENT_HEADER(MED)
+
+#include "SMESH_Hypothesis.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_subMesh_i.hxx"
+#include "SMESH_subMesh.hxx"
+
+#include "SALOME_GenericObj_i.hh"
+
+class SMESH_Gen_i;
+class SMESH_GroupBase_i;
+
+#include <map>
+
+class SMESH_Mesh_i:
+  public virtual POA_SMESH::SMESH_Mesh,
+  public virtual SALOME::GenericObj_i
+{
+  SMESH_Mesh_i();
+  SMESH_Mesh_i(const SMESH_Mesh_i&);
+public:
+  SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
+                SMESH_Gen_i*            myGen_i,
+               CORBA::Long             studyId );
+
+  virtual ~SMESH_Mesh_i();
+
+  // --- CORBA
+  void SetShape( GEOM::GEOM_Object_ptr theShapeObject )
+    throw (SALOME::SALOME_Exception);
+
+  GEOM::GEOM_Object_ptr GetShapeToMesh()
+    throw (SALOME::SALOME_Exception);
+
+  SMESH::Hypothesis_Status AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
+                                         SMESH::SMESH_Hypothesis_ptr anHyp)
+    throw (SALOME::SALOME_Exception);
+
+  SMESH::Hypothesis_Status RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
+                                            SMESH::SMESH_Hypothesis_ptr anHyp)
+    throw (SALOME::SALOME_Exception);
+
+  SMESH::ListOfHypothesis* GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
+    throw (SALOME::SALOME_Exception);
+
+  SMESH::SMESH_subMesh_ptr GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject, const char* theName)
+    throw (SALOME::SALOME_Exception);
+
+  void RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
+    throw (SALOME::SALOME_Exception);
+
+  SMESH::SMESH_Group_ptr CreateGroup( SMESH::ElementType theElemType, const char* theName )
+    throw (SALOME::SALOME_Exception);
+  
+  SMESH::SMESH_GroupOnGeom_ptr CreateGroupFromGEOM(SMESH::ElementType    theElemType,
+                                                   const char*           theName,
+                                                   GEOM::GEOM_Object_ptr theGeomObj )
+    throw (SALOME::SALOME_Exception);
+
+  void RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
+    throw (SALOME::SALOME_Exception);
+  
+  void RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
+    throw (SALOME::SALOME_Exception);
+  
+  SMESH::SMESH_Group_ptr UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1, 
+                                      SMESH::SMESH_GroupBase_ptr theGroup2, 
+                                      const char* theName )
+    throw (SALOME::SALOME_Exception);
+  
+  SMESH::SMESH_Group_ptr IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1, 
+                                          SMESH::SMESH_GroupBase_ptr theGroup2, 
+                                          const char* theName )
+    throw (SALOME::SALOME_Exception);
+  
+  SMESH::SMESH_Group_ptr CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1, 
+                                    SMESH::SMESH_GroupBase_ptr theGroup2, 
+                                   const char* theName )
+    throw (SALOME::SALOME_Exception);
+
+//    SMESH::string_array* GetLog(CORBA::Boolean clearAfterGet)
+//      throw (SALOME::SALOME_Exception);
+
+  SMESH::log_array* GetLog(CORBA::Boolean clearAfterGet)
+    throw (SALOME::SALOME_Exception);
+
+  SMESH::SMESH_MeshEditor_ptr GetMeshEditor();
+
+  void ClearLog()
+    throw (SALOME::SALOME_Exception);
+
+  CORBA::Long GetId()
+    throw (SALOME::SALOME_Exception);
+
+  CORBA::Long GetStudyId()
+    throw (SALOME::SALOME_Exception);
+
+  // --- C++ interface
+
+  void SetImpl(::SMESH_Mesh* impl);
+  ::SMESH_Mesh& GetImpl();         // :: force no namespace here
+
+  SMESH_Gen_i* GetGen() { return _gen_i; }
+  
+  int ImportUNVFile( const char* theFileName )
+    throw (SALOME::SALOME_Exception);
+
+  int ImportSTLFile( const char* theFileName )
+    throw (SALOME::SALOME_Exception);
+
+  /*!
+   * consult DriverMED_R_SMESHDS_Mesh::ReadStatus for returned value
+   */
+  SMESH::DriverMED_ReadStatus ImportMEDFile( const char* theFileName, const char* theMeshName )
+    throw (SALOME::SALOME_Exception);
+
+  void ExportToMED( const char* file, CORBA::Boolean auto_groups, SMESH::MED_VERSION theVersion )
+    throw (SALOME::SALOME_Exception);
+  void ExportMED( const char* file, CORBA::Boolean auto_groups )
+    throw (SALOME::SALOME_Exception);
+
+  void ExportDAT( const char* file )
+    throw (SALOME::SALOME_Exception);
+  void ExportUNV( const char* file )
+    throw (SALOME::SALOME_Exception);
+  void ExportSTL( const char* file, const bool isascii )
+    throw (SALOME::SALOME_Exception);
+
+  SALOME_MED::MESH_ptr GetMEDMesh()
+    throw (SALOME::SALOME_Exception);
+
+  CORBA::Long NbNodes()
+    throw (SALOME::SALOME_Exception);
+
+  CORBA::Long NbElements()
+    throw (SALOME::SALOME_Exception);
+
+  CORBA::Long NbEdges()
+    throw (SALOME::SALOME_Exception);
+
+  CORBA::Long NbFaces()
+    throw (SALOME::SALOME_Exception);
+
+  CORBA::Long NbTriangles()
+    throw (SALOME::SALOME_Exception);
+
+  CORBA::Long NbQuadrangles()
+    throw (SALOME::SALOME_Exception);
+
+  CORBA::Long NbPolygons()
+    throw (SALOME::SALOME_Exception);
+
+  CORBA::Long NbVolumes()
+    throw (SALOME::SALOME_Exception);
+
+  CORBA::Long NbTetras()
+    throw (SALOME::SALOME_Exception);
+
+  CORBA::Long NbHexas()
+    throw (SALOME::SALOME_Exception);
+
+  CORBA::Long NbPyramids()
+    throw (SALOME::SALOME_Exception);
+
+  CORBA::Long NbPrisms()
+    throw (SALOME::SALOME_Exception);
+
+  CORBA::Long NbPolyhedrons()
+    throw (SALOME::SALOME_Exception);
+
+  CORBA::Long NbSubMesh()
+    throw (SALOME::SALOME_Exception);
+
+  SMESH::long_array* GetElementsId()
+    throw (SALOME::SALOME_Exception);
+
+  SMESH::long_array* GetElementsByType( SMESH::ElementType theElemType )
+    throw (SALOME::SALOME_Exception);
+  
+  SMESH::long_array* GetNodesId()
+    throw (SALOME::SALOME_Exception);
+  
+  SMESH::ElementType GetElementType( const CORBA::Long id, const bool iselem )
+    throw (SALOME::SALOME_Exception);
+  
+  char* Dump();
+  
+  // Internal methods not available through CORBA
+  // They are called by corresponding interface methods
+  SMESH_Hypothesis::Hypothesis_Status addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
+                                                    SMESH::SMESH_Hypothesis_ptr anHyp);
+
+  SMESH_Hypothesis::Hypothesis_Status removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
+                                                       SMESH::SMESH_Hypothesis_ptr anHyp);
+  
+  int importMEDFile( const char* theFileName, const char* theMeshName );
+
+  SMESH::SMESH_subMesh_ptr createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject );
+
+  void removeSubMesh(SMESH::SMESH_subMesh_ptr theSubMesh,
+                     GEOM::GEOM_Object_ptr theSubShapeObject );
+
+  SMESH::SMESH_GroupBase_ptr createGroup(SMESH::ElementType  theElemType,
+                                         const char*         theName,
+                                         const TopoDS_Shape& theShape = TopoDS_Shape());
+
+  void removeGroup( const int theId );
+
+  SMESH::SMESH_subMesh_ptr getSubMesh(int shapeID);
+  // return an existing subMesh object for the shapeID. shapeID == submeshID.
+
+  const map<int, SMESH::SMESH_GroupBase_ptr>& getGroups() { return _mapGroups; }
+  // return an existing group object.
+
+  virtual SMESH::long_array* GetIDs();
+
+  map<int, SMESH_subMesh_i*> _mapSubMesh_i; //NRI
+  map<int, ::SMESH_subMesh*> _mapSubMesh;   //NRI
+
+private:
+  static int myIdGenerator;
+  ::SMESH_Mesh* _impl;  // :: force no namespace here
+  SMESH_Gen_i* _gen_i;
+  int _id;          // id given by creator (unique within the creator instance)
+  int _studyId;
+  map<int, SMESH::SMESH_subMesh_ptr>    _mapSubMeshIor;
+  map<int, SMESH::SMESH_GroupBase_ptr>  _mapGroups;
+  map<int, SMESH::SMESH_Hypothesis_ptr> _mapHypo;
+};
+
+#endif
+
diff --git a/src/SMESH_I/SMESH_subMesh_i.cxx b/src/SMESH_I/SMESH_subMesh_i.cxx
new file mode 100644 (file)
index 0000000..f8ade30
--- /dev/null
@@ -0,0 +1,487 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESH_subMesh_i.cxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+using namespace std;
+#include "SMESH_subMesh_i.hxx"
+#include "SMESH_Gen_i.hxx"
+#include "SMESH_Mesh_i.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+#include "OpUtil.hxx"
+#include "Utils_ExceptHandlers.hxx"
+
+#include <BRepTools.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Iterator.hxx>
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+SMESH_subMesh_i::SMESH_subMesh_i()
+     : SALOME::GenericObj_i( PortableServer::POA::_nil() )
+{
+  MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i default, not for use");
+    ASSERT(0);
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+SMESH_subMesh_i::SMESH_subMesh_i( PortableServer::POA_ptr thePOA,
+                                 SMESH_Gen_i*            gen_i,
+                                 SMESH_Mesh_i*           mesh_i,
+                                 int                     localId )
+     : SALOME::GenericObj_i( thePOA )
+{
+  MESSAGE("SMESH_subMesh_i::SMESH_subMesh_i");
+  _gen_i = gen_i;
+  _mesh_i = mesh_i;
+  _localId = localId;
+  thePOA->activate_object( this );
+  // ****
+}
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+SMESH_subMesh_i::~SMESH_subMesh_i()
+{
+  MESSAGE("SMESH_subMesh_i::~SMESH_subMesh_i");
+  // ****
+}
+
+//=======================================================================
+//function : getSubMeshes
+//purpose  : for a submesh on shape to which elements are not bound directly,
+//           return submeshes containing elements
+//=======================================================================
+
+typedef list<SMESHDS_SubMesh*> TListOfSubMeshes;
+
+bool getSubMeshes(::SMESH_subMesh*  theSubMesh,
+                  TListOfSubMeshes& theSubMeshList)
+{
+  int size = theSubMeshList.size();
+
+  SMESH_Mesh*      aMesh      = theSubMesh->GetFather();
+  SMESHDS_Mesh*    aMeshDS    = aMesh->GetMeshDS();
+  SMESHDS_SubMesh* aSubMeshDS = theSubMesh->GetSubMeshDS();
+
+  // nodes can be bound to either vertex, edge, face or solid_or_shell
+  TopoDS_Shape aShape = theSubMesh->GetSubShape();
+  switch ( aShape.ShapeType() )
+  {
+  case TopAbs_SOLID: {
+    // add submesh of solid itself
+    aSubMeshDS = aMeshDS->MeshElements( aShape );
+    if ( aSubMeshDS )
+      theSubMeshList.push_back( aSubMeshDS );
+    // and of the first shell
+    TopExp_Explorer exp( aShape, TopAbs_SHELL );
+    if ( exp.More() ) {
+      aSubMeshDS = aMeshDS->MeshElements( exp.Current() );
+      if ( aSubMeshDS )
+        theSubMeshList.push_back( aSubMeshDS );
+    }
+    break;
+  }
+  case TopAbs_WIRE:
+  case TopAbs_COMPOUND:
+  case TopAbs_COMPSOLID: {
+    // call getSubMeshes() for sub-shapes
+    list<TopoDS_Shape> shapeList;
+    shapeList.push_back( aShape );
+    list<TopoDS_Shape>::iterator sh = shapeList.begin();
+    for ( ; sh != shapeList.end(); ++sh ) {
+      for ( TopoDS_Iterator it( *sh ); it.More(); it.Next() ) {
+        ::SMESH_subMesh* aSubMesh = aMesh->GetSubMeshContaining( it.Value() );
+        if ( aSubMesh )
+          getSubMeshes( aSubMesh, theSubMeshList );
+        else
+          // no submesh for a compound inside compound
+          shapeList.push_back( it.Value() );
+      }
+    }
+    // return only unique submeshes
+    set<SMESHDS_SubMesh*> smSet;
+    TListOfSubMeshes::iterator sm = theSubMeshList.begin();
+    while ( sm != theSubMeshList.end() ) {
+      if ( !smSet.insert( *sm ).second )
+        sm = theSubMeshList.erase( sm );
+      else
+        ++sm;
+    }
+    break;
+  }
+  }
+  return size < theSubMeshList.size();
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+CORBA::Long SMESH_subMesh_i::GetNumberOfElements()
+  throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  MESSAGE("SMESH_subMesh_i::GetNumberOfElements");
+  if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
+    return 0;
+
+  ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
+  SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
+
+  int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
+
+  // volumes are bound to shell
+  TListOfSubMeshes smList;
+  if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
+  {
+    TListOfSubMeshes::iterator sm = smList.begin();
+    for ( ; sm != smList.end(); ++sm )
+      nbElems += (*sm)->NbElements();
+  }
+  return nbElems;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
+  throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  MESSAGE("SMESH_subMesh_i::GetNumberOfNodes");
+  if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
+    return 0;
+
+  ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
+  SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
+
+  set<int> nodeIds;
+
+  // nodes are bound to shell instead of solid
+  TListOfSubMeshes smList;
+  if ( all && getSubMeshes( aSubMesh, smList ))
+  {
+    TListOfSubMeshes::iterator sm = smList.begin();
+    for ( ; sm != smList.end(); ++sm )
+    {
+      SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
+      while ( eIt->more() ) {
+        const SMDS_MeshElement* anElem = eIt->next();
+        SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+        while ( nIt->more() )
+          nodeIds.insert( nIt->next()->GetID() );
+      }
+    }
+    return nodeIds.size();
+  }
+
+  if ( aSubMeshDS == NULL )
+    return 0;
+
+  if ( all ) { // all nodes of submesh elements
+    SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
+    while ( eIt->more() ) {
+      const SMDS_MeshElement* anElem = eIt->next();
+      SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+      while ( nIt->more() )
+        nodeIds.insert( nIt->next()->GetID() );
+    }
+    return nodeIds.size();
+  }
+    
+  return aSubMeshDS->NbNodes();
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+  
+SMESH::long_array* SMESH_subMesh_i::GetElementsId()
+  throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  MESSAGE("SMESH_subMesh_i::GetElementsId");
+  SMESH::long_array_var aResult = new SMESH::long_array();
+
+  if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
+    return aResult._retn();
+
+  ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
+  SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
+
+  int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
+  TListOfSubMeshes smList;
+  if ( nbElems )
+    smList.push_back( aSubMeshDS );
+
+  // volumes are bound to shell
+  if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
+  {
+    TListOfSubMeshes::iterator sm = smList.begin();
+    for ( ; sm != smList.end(); ++sm )
+      nbElems += (*sm)->NbElements();
+  }
+
+  aResult->length( nbElems );
+  if ( nbElems )
+  {
+    TListOfSubMeshes::iterator sm = smList.begin();
+    for ( int i = 0; sm != smList.end(); sm++ )
+    {
+      SMDS_ElemIteratorPtr anIt = (*sm)->GetElements();
+      for ( int n = aSubMeshDS->NbElements(); i < n && anIt->more(); i++ )
+        aResult[i] = anIt->next()->GetID();
+    }
+  }
+  return aResult._retn();
+}
+
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theElemType )
+    throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  MESSAGE("SMESH_subMesh_i::GetElementsByType");
+  SMESH::long_array_var aResult = new SMESH::long_array();
+
+  if ( _mesh_i->_mapSubMesh.find( _localId ) == _mesh_i->_mapSubMesh.end() )
+    return aResult._retn();
+
+  ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId];
+  SMESHDS_SubMesh* aSubMeshDS = aSubMesh->GetSubMeshDS();
+
+  // PAL5440, return all nodes belonging to elements of submesh
+  set<int> nodeIds;
+  int nbElems = aSubMeshDS ? aSubMeshDS->NbElements() : 0;
+
+  // volumes may be bound to shell instead of solid
+  TListOfSubMeshes smList;
+  if ( nbElems == 0 && getSubMeshes( aSubMesh, smList ))
+  {
+    TListOfSubMeshes::iterator sm = smList.begin();
+    for ( ; sm != smList.end(); ++sm )
+    {
+      if ( theElemType == SMESH::NODE )
+      {
+        SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
+        while ( eIt->more() ) {
+          const SMDS_MeshElement* anElem = eIt->next();
+          SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+          while ( nIt->more() )
+            nodeIds.insert( nIt->next()->GetID() );
+        }
+      }
+      else
+      {
+        nbElems += (*sm)->NbElements();
+      }
+    }
+    aSubMeshDS = 0;
+  }
+  else
+  {
+    if ( nbElems )
+      smList.push_back( aSubMeshDS );
+  }
+
+  if ( theElemType == SMESH::NODE && aSubMeshDS )
+  {
+    SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
+    while ( eIt->more() ) {
+      const SMDS_MeshElement* anElem = eIt->next();
+      SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+      while ( nIt->more() )
+        nodeIds.insert( nIt->next()->GetID() );
+    }
+  }
+
+  if ( theElemType == SMESH::NODE )
+    aResult->length( nodeIds.size() );
+  else
+    aResult->length( nbElems );
+
+  int i = 0, n = aResult->length();
+
+  if ( theElemType == SMESH::NODE && !nodeIds.empty() ) {
+    set<int>::iterator idIt = nodeIds.begin();
+    for ( ; i < n && idIt != nodeIds.end() ; i++, idIt++ )
+      aResult[i] = *idIt;
+  }
+
+  if ( theElemType != SMESH::NODE ) {
+    TListOfSubMeshes::iterator sm = smList.begin();
+    for ( i = 0; sm != smList.end(); sm++ )
+    {
+      aSubMeshDS = *sm;
+      SMDS_ElemIteratorPtr anIt = aSubMeshDS->GetElements();
+      while ( i < n && anIt->more() ) {
+        const SMDS_MeshElement* anElem = anIt->next();
+        if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
+          aResult[i++] = anElem->GetID();
+      }
+    }
+  }
+
+  aResult->length( i );
+
+  return aResult._retn();
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+  
+SMESH::long_array* SMESH_subMesh_i::GetNodesId()
+  throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  MESSAGE("SMESH_subMesh_i::GetNodesId");
+  SMESH::long_array_var aResult = GetElementsByType( SMESH::NODE );
+  return aResult._retn();
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+  
+SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetFather()
+  throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  MESSAGE("SMESH_subMesh_i::GetFather");
+  return _mesh_i->_this();
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+  
+CORBA::Long SMESH_subMesh_i::GetId()
+{
+  MESSAGE("SMESH_subMesh_i::GetId");
+  return _localId;
+}
+
+//=======================================================================
+//function : GetSubShape
+//purpose  : 
+//=======================================================================
+
+GEOM::GEOM_Object_ptr SMESH_subMesh_i::GetSubShape()
+     throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  GEOM::GEOM_Object_var aShapeObj;
+  try {
+    if ( _mesh_i->_mapSubMesh.find( _localId ) != _mesh_i->_mapSubMesh.end()) {
+      TopoDS_Shape S = _mesh_i->_mapSubMesh[ _localId ]->GetSubShape();
+      if ( !S.IsNull() )
+        aShapeObj = _gen_i->ShapeToGeomObject( S );
+    }
+  }
+  catch(SALOME_Exception & S_ex) {
+    THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+  }
+  return aShapeObj._retn();
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+SALOME_MED::FAMILY_ptr SMESH_subMesh_i::GetFamily()
+  throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  SALOME_MED::MESH_var MEDMesh = GetFather()->GetMEDMesh();
+
+  SALOME_MED::Family_array_var families = 
+    MEDMesh->getFamilies(SALOME_MED::MED_NODE);
+    
+  for ( int i = 0; i < families->length(); i++ ) {
+    if ( families[i]->getIdentifier() == ( _localId ) )
+      return families[i];
+  }
+  
+  return SALOME_MED::FAMILY::_nil();
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+SMESH::long_array* SMESH_subMesh_i::GetIDs()
+{
+  SMESH::long_array_var aResult = GetElementsId();
+  return aResult._retn();
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+SMESH::ElementType SMESH_subMesh_i::GetElementType( const CORBA::Long id, const bool iselem )
+  throw (SALOME::SALOME_Exception)
+{
+  return GetFather()->GetElementType( id, iselem );
+}
diff --git a/src/SMESH_I/SMESH_subMesh_i.hxx b/src/SMESH_I/SMESH_subMesh_i.hxx
new file mode 100644 (file)
index 0000000..e8d84b3
--- /dev/null
@@ -0,0 +1,93 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : SMESH_subMesh_i.hxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_SUBMESH_I_HXX_
+#define _SMESH_SUBMESH_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_Hypothesis)
+#include CORBA_CLIENT_HEADER(GEOM_Gen)
+#include CORBA_CLIENT_HEADER(MED)
+
+#include "SALOME_GenericObj_i.hh"
+
+class SMESH_Gen_i;
+class SMESH_Mesh_i;
+
+class SMESH_subMesh_i:
+  public virtual POA_SMESH::SMESH_subMesh,
+  public virtual SALOME::GenericObj_i
+{
+public:
+  SMESH_subMesh_i();
+  SMESH_subMesh_i( PortableServer::POA_ptr thePOA,
+                   SMESH_Gen_i*            gen_i,
+                  SMESH_Mesh_i*           mesh_i,
+                  int                     localId );
+  ~SMESH_subMesh_i();
+
+  CORBA::Long GetNumberOfElements()
+    throw (SALOME::SALOME_Exception);
+  
+  CORBA::Long  GetNumberOfNodes( CORBA::Boolean all )
+    throw (SALOME::SALOME_Exception);
+  
+  SMESH::long_array* GetElementsId()
+    throw (SALOME::SALOME_Exception);
+
+  SMESH::long_array* GetElementsByType( SMESH::ElementType theElemType )
+    throw (SALOME::SALOME_Exception);
+  
+  SMESH::ElementType GetElementType( const CORBA::Long id, const bool iselem )
+    throw (SALOME::SALOME_Exception);
+  
+  SMESH::long_array* GetNodesId()
+    throw (SALOME::SALOME_Exception);
+  
+  SMESH::SMESH_Mesh_ptr GetFather()
+    throw (SALOME::SALOME_Exception);
+  
+  GEOM::GEOM_Object_ptr GetSubShape()
+    throw (SALOME::SALOME_Exception);
+
+  CORBA::Long GetId();   
+
+  SALOME_MED::FAMILY_ptr GetFamily()
+    throw (SALOME::SALOME_Exception);
+
+  virtual SMESH::long_array* GetIDs();
+
+  SMESH_Mesh_i* _mesh_i; //NRI
+
+protected:
+  SMESH_Gen_i* _gen_i;
+  int _localId;
+};
+
+#endif
diff --git a/src/SMESH_SWIG/Makefile.in b/src/SMESH_SWIG/Makefile.in
new file mode 100644 (file)
index 0000000..df7e19a
--- /dev/null
@@ -0,0 +1,120 @@
+#  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+# 
+#  This library is free software; you can redistribute it and/or 
+#  modify it under the terms of the GNU Lesser General Public 
+#  License as published by the Free Software Foundation; either 
+#  version 2.1 of the License. 
+# 
+#  This library is distributed in the hope that it will be useful, 
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+#  Lesser General Public License for more details. 
+# 
+#  You should have received a copy of the GNU Lesser General Public 
+#  License along with this library; if not, write to the Free Software 
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+# 
+#  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+#
+#
+#
+#  File   : Makefile.in
+#  Author : Nicolas REJNERI, Paul RASCLE
+#  Module : SMESH
+#  $Header$
+
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@:@top_srcdir@/idl
+
+
+@COMMENCE@
+
+# Libraries targets
+
+LIB = libSMESH_Swigcmodule.la
+LIB_SRC = 
+
+SWIG_DEF = libSMESH_Swig.i
+EXPORT_PYSCRIPTS = libSMESH_Swig.py \
+                  smesh.py \
+                  batchmode_smesh.py \
+                  batchmode_mefisto.py \
+                  ex00_all.py \
+                  ex01_cube2build.py \
+                  ex02_cube2primitive.py \
+                  ex03_cube2partition.py \
+                  ex04_cube5tetraHexa.py \
+                  ex05_hole1build.py \
+                  ex06_hole1boolean.py \
+                  ex07_hole1partition.py \
+                  ex08_hole2build.py \
+                  ex09_grid4build.py \
+                  ex10_grid4geometry.py \
+                  ex11_grid3partition.py \
+                  ex12_grid17partition.py \
+                  ex13_hole1partial.py \
+                  ex14_cyl1holed.py \
+                  ex15_cyl2geometry.py \
+                  ex16_cyl2complementary.py \
+                  ex17_dome1.py \
+                  ex18_dome2.py \
+                  ex19_sphereINcube.py \
+                   SMESH_test.py\
+                   SMESH_test0.py\
+                  SMESH_test1.py \
+                  SMESH_test2.py \
+                  SMESH_test3.py \
+                  SMESH_test4.py \
+                  SMESH_test5.py \
+                  SMESH_mechanic.py \
+                  SMESH_mechanic_tetra.py \
+                  SMESH_mechanic_editor.py \
+                  SMESH_fixation.py \
+                  SMESH_fixation_hexa.py \
+                  SMESH_fixation_tetra.py \
+                  SMESH_box_tetra.py \
+                  SMESH_box2_tetra.py \
+                  SMESH_box3_tetra.py \
+                  SMESH_flight_skin.py \
+                  SMESH_Partition1_tetra.py\
+                  SMESH_controls.py \
+                  SMESH_freebord.py \
+                  SMESH_blocks.py \
+                  SMESH_BelongToGeom.py \
+                  SMESH_GroupFromGeom2.py \
+                  SMESH_box.py \
+                  SMESH_demo_hexa2_upd.py \
+                  SMESH_hexaedre.py \
+                  SMESH_Sphere.py \
+                  SMESH_GroupFromGeom.py \
+                  SMESH_Nut.py \
+                  SMESH_GroupLyingOnGeom.py \
+                  PAL_MESH_041_mesh.py \
+                  PAL_MESH_043_2D.py \
+                  PAL_MESH_043_3D.py \
+                  SMESH_reg.py
+
+LIB_CLIENT_IDL = SALOMEDS.idl \
+                SALOME_Exception.idl \
+                GEOM_Gen.idl \
+                SMESH_Gen.idl \
+                SMESH_Mesh.idl \
+                SMESH_Hypothesis.idl \
+                SMESH_BasicHypothesis.idl \
+                SMESH_Group.idl \
+                SALOME_ModuleCatalog.idl \
+                SALOME_Component.idl \
+                SALOME_GenericObj.idl \
+                MED.idl \
+                SALOME_Comm.idl
+
+EXPORT_SHAREDPYSCRIPTS=SMESH_shared_modules.py
+
+CPPFLAGS+=$(QT_INCLUDES) $(PYTHON_INCLUDES) $(OCC_INCLUDES) $(VTK_INCLUDES) $(OGL_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome -DHAVE_CONFIG_H
+LIBS+= $(PYTHON_LIBS)
+LDFLAGS+= -lSMESH -L${KERNEL_ROOT_DIR}/lib/salome -lSalomeGenericObj
+
+@CONCLUDE@
diff --git a/src/SMESH_SWIG/SMESH_test.py b/src/SMESH_SWIG/SMESH_test.py
new file mode 100644 (file)
index 0000000..d2385f3
--- /dev/null
@@ -0,0 +1,200 @@
+#  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+#
+#  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+#  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+#  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+#
+#
+#
+#  File   : SMESH_test.py
+#  Module : SMESH
+
+import salome
+import geompy
+import smeshpy
+
+import SMESH
+import StdMeshers
+
+# ---- define a box
+
+box = geompy.MakeBox(0., 0., 0., 100., 200., 300.)
+idb = geompy.addToStudy(box, "box")
+
+# ---- add first face of box in study
+
+subShapeList = geompy.SubShapeAll(box, geompy.ShapeType["FACE"])
+face = subShapeList[0]
+name = geompy.SubShapeName(face, box)
+idf = geompy.addToStudyInFather(box, face, name)
+
+# ---- add shell from box  in study
+
+subShellList = geompy.SubShapeAll(box, geompy.ShapeType["SHELL"])
+shell = subShellList[0]
+name = geompy.SubShapeName(shell, box)
+ids = geompy.addToStudyInFather(box, shell, name)
+
+# ---- add first edge of face in study
+
+edgeList = geompy.SubShapeAll(face, geompy.ShapeType["EDGE"])
+edge = edgeList[0];
+name = geompy.SubShapeName(edge, face)
+ide = geompy.addToStudyInFather(face, edge, name)
+
+# ---- launch SMESH, init a Mesh with the box
+
+gen = smeshpy.smeshpy()
+mesh = gen.CreateMesh(idb)
+
+print "-------------------------- create Hypothesis"
+
+print "-------------------------- LocalLength"
+
+hypo1 = gen.CreateHypothesis("LocalLength", "libStdMeshersEngine.so")
+print hypo1.GetName()
+print hypo1.GetId()
+print hypo1.GetLength()
+hypo1.SetLength(100)
+print hypo1.GetLength()
+
+print "-------------------------- bidon"
+
+hyp3 = gen.CreateHypothesis("bidon", "")
+
+print "-------------------------- NumberOfSegments"
+
+hypo3 = gen.CreateHypothesis("NumberOfSegments", "libStdMeshersEngine.so")
+hypo3.SetNumberOfSegments(7)
+print hypo3.GetName()
+print hypo3.GetNumberOfSegments()
+print hypo3.GetId()
+
+print "-------------------------- MaxElementArea"
+
+hypo4 = gen.CreateHypothesis("MaxElementArea", "libStdMeshersEngine.so")
+hypo4.SetMaxElementArea(5000)
+print hypo4.GetName()
+print hypo4.GetMaxElementArea()
+print hypo4.GetId()
+
+print "-------------------------- Regular_1D"
+
+algo_1 = gen.CreateHypothesis("Regular_1D", "libStdMeshersEngine.so")
+print algo_1.GetName()
+print algo_1.GetId()
+listHyp = algo_1.GetCompatibleHypothesis()
+for hyp in listHyp:
+    print hyp
+print algo_1.GetId()
+
+print "-------------------------- MEFISTO_2D"
+
+algo_2 = gen.CreateHypothesis("MEFISTO_2D", "libStdMeshersEngine.so")
+print algo_2.GetName()
+print algo_2.GetId()
+listHyp = algo_2.GetCompatibleHypothesis()
+for hyp in listHyp:
+    print hyp
+print algo_2.GetId()
+
+print "-------------------------- add hypothesis to edge"
+
+edge = salome.IDToObject(ide)
+submesh = mesh.GetSubMesh(edge, "SubMeshEdge")
+ret = mesh.AddHypothesis(edge,algo_1)
+print ret
+ret = mesh.AddHypothesis(edge,hypo1)
+print ret
+
+##print "-------------------------- compute edge"
+##ret=gen.Compute(mesh,ide)
+##print ret
+##log=mesh.GetLog(1);
+##for a in log:
+##    print a
+
+print "-------------------------- add hypothesis to box"
+
+box = salome.IDToObject(idb)
+submesh = mesh.GetSubMesh(box, "SubMeshBox")
+ret = mesh.AddHypothesis(box,algo_1)
+print ret
+ret = mesh.AddHypothesis(box,hypo1)
+print ret
+ret = mesh.AddHypothesis(box,algo_2)
+print ret
+ret = mesh.AddHypothesis(box,hypo4)
+print ret
+
+print "-------------------------- compute face"
+
+ret = gen.Compute(mesh,idf)
+print ret
+log = mesh.GetLog(0) # 0 - GetLog without ClearLog after, else if 1 - ClearLog after
+for a in log:
+    print "-------"
+    ii = 0
+    ir = 0
+    comType = a.commandType
+    if comType == 0:
+        for i in range(a.number):
+            ind = a.indexes[ii]
+            ii = ii+1
+            r1 = a.coords[ir]
+            ir = ir+1
+            r2 = a.coords[ir]
+            ir = ir+1
+            r3 = a.coords[ir]
+            ir = ir+1
+            print "AddNode %i - %g %g %g" % (ind, r1, r2, r3)
+    elif comType == 1:
+        for i in range(a.number):
+            ind = a.indexes[ii]
+            ii = ii+1
+            i1 = a.indexes[ii]
+            ii = ii+1
+            i2 = a.indexes[ii]
+            ii = ii+1
+            print "AddEdge %i - %i %i" % (ind, i1, i2)
+    elif comType == 2:
+        for i in range(a.number):
+            ind = a.indexes[ii]
+            ii = ii+1
+            i1 = a.indexes[ii]
+            ii = ii+1
+            i2 = a.indexes[ii]
+            ii = ii+1
+            i3 = a.indexes[ii]
+            ii = ii+1
+            print "AddTriangle %i - %i %i %i" % (ind, i1, i2, i3)
+
+##print "-------------------------- compute box"
+##ret=gen.Compute(mesh,idb)
+##print ret
+##log=mesh.GetLog(1);
+##print log
+
+##shell=salome.IDToObject(ids)
+##submesh=mesh.GetElementsOnShape(shell)
+##ret=mesh.AddHypothesis(shell,algo_1)
+##print ret
+##ret=mesh.AddHypothesis(shell,hypo1)
+##print ret
+##ret=gen.Compute(mesh,ids)
+##print ret
diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.cxx b/src/StdMeshers/StdMeshers_Hexa_3D.cxx
new file mode 100644 (file)
index 0000000..a3ed4f1
--- /dev/null
@@ -0,0 +1,1068 @@
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : StdMeshers_Hexa_3D.cxx
+//           Moved here from SMESH_Hexa_3D.cxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+using namespace std;
+#include "StdMeshers_Hexa_3D.hxx"
+#include "StdMeshers_Quadrangle_2D.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_subMesh.hxx"
+
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_FacePosition.hxx"
+#include "SMDS_VolumeTool.hxx"
+#include "SMDS_VolumeOfNodes.hxx"
+
+#include <TopExp.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+
+#include <BRep_Tool.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom2d_Curve.hxx>
+#include <Handle_Geom2d_Curve.hxx>
+#include <Handle_Geom_Curve.hxx>
+#include <gp_Pnt2d.hxx>
+
+#include "utilities.h"
+#include "Utils_ExceptHandlers.hxx"
+
+//modified by NIZNHY-PKV Wed Nov 17 15:31:58 2004 f
+#include "StdMeshers_Penta_3D.hxx"
+
+static bool ComputePentahedralMesh(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape);
+//modified by NIZNHY-PKV Wed Nov 17 15:32:00 2004 t
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId,
+       SMESH_Gen * gen):SMESH_3D_Algo(hypId, studyId, gen)
+{
+       MESSAGE("StdMeshers_Hexa_3D::StdMeshers_Hexa_3D");
+       _name = "Hexa_3D";
+//   _shapeType = TopAbs_SOLID;
+       _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit /shape type
+//   MESSAGE("_shapeType octal " << oct << _shapeType);
+       for (int i = 0; i < 6; i++)
+               _quads[i] = 0;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D()
+{
+       MESSAGE("StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D");
+       for (int i = 0; i < 6; i++)
+               StdMeshers_Quadrangle_2D::QuadDelete(_quads[i]);
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+bool StdMeshers_Hexa_3D::CheckHypothesis
+                         (SMESH_Mesh& aMesh,
+                          const TopoDS_Shape& aShape,
+                          SMESH_Hypothesis::Hypothesis_Status& aStatus)
+{
+       //MESSAGE("StdMeshers_Hexa_3D::CheckHypothesis");
+
+       bool isOk = true;
+        aStatus = SMESH_Hypothesis::HYP_OK;
+
+       // nothing to check
+
+       return isOk;
+}
+
+//=======================================================================
+//function : findIJ
+//purpose  : return i,j of the node
+//=======================================================================
+
+static bool findIJ (const SMDS_MeshNode* node, const FaceQuadStruct * quad, int& I, int& J)
+{
+  I = J = 0;
+  const SMDS_FacePosition* fpos =
+    static_cast<const SMDS_FacePosition*>(node->GetPosition().get());
+  if ( ! fpos ) return false;
+  gp_Pnt2d uv( fpos->GetUParameter(), fpos->GetVParameter() );
+
+  double minDist = DBL_MAX;
+  int nbhoriz  = Min(quad->nbPts[0], quad->nbPts[2]);
+  int nbvertic = Min(quad->nbPts[1], quad->nbPts[3]);
+  for (int i = 1; i < nbhoriz - 1; i++) {
+    for (int j = 1; j < nbvertic - 1; j++) {
+      int ij = j * nbhoriz + i;
+      gp_Pnt2d uv2( quad->uv_grid[ij].u, quad->uv_grid[ij].v );
+      double dist = uv.SquareDistance( uv2 );
+      if ( dist < minDist ) {
+        minDist = dist;
+        I = i;
+        J = j;
+      }
+    }
+  }
+  return true;
+}
+
+//=============================================================================
+/*!
+ * Hexahedron mesh on hexaedron like form
+ * -0.  - shape and face mesh verification
+ * -1.  - identify faces and vertices of the "cube"
+ * -2.  - Algorithm from:
+ * "Application de l'interpolation transfinie à la création de maillages
+ *  C0 ou G1 continus sur des triangles, quadrangles, tetraedres, pentaedres
+ *  et hexaedres déformés."
+ * Alain PERONNET - 8 janvier 1999
+ */
+//=============================================================================
+
+bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
+       const TopoDS_Shape & aShape)throw(SALOME_Exception)
+{
+  Unexpect aCatch(SalomeException);
+       MESSAGE("StdMeshers_Hexa_3D::Compute");
+       //bool isOk = false;
+       SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+       //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
+       //const SMESHDS_SubMesh *& subMeshDS = theSubMesh->GetSubMeshDS();
+
+       // 0.  - shape and face mesh verification
+       // 0.1 - shape must be a solid (or a shell) with 6 faces
+       //MESSAGE("---");
+
+       vector < SMESH_subMesh * >meshFaces;
+       for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next())
+       {
+               SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
+               ASSERT(aSubMesh);
+               meshFaces.push_back(aSubMesh);
+       }
+       if (meshFaces.size() != 6)
+       {
+               SCRUTE(meshFaces.size());
+//             ASSERT(0);
+               return false;
+       }
+
+       // 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges)
+       //MESSAGE("---");
+
+       for (int i = 0; i < 6; i++)
+       {
+         TopoDS_Shape aFace = meshFaces[i]->GetSubShape();
+         SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace);
+         string algoName = algo->GetName();
+          bool isAllQuad = false;
+         if (algoName == "Quadrangle_2D") {
+            SMESHDS_SubMesh * sm = meshDS->MeshElements( aFace );
+            if ( sm ) {
+              isAllQuad = true;
+              SMDS_ElemIteratorPtr eIt = sm->GetElements();
+              while ( isAllQuad && eIt->more() )
+                isAllQuad = ( eIt->next()->NbNodes() == 4 );
+            }
+          }
+          if ( ! isAllQuad ) {
+           //modified by NIZNHY-PKV Wed Nov 17 15:31:37 2004 f
+            bool bIsOk;
+            //
+            bIsOk=ComputePentahedralMesh(aMesh, aShape);
+            if (bIsOk) {
+              return true;
+            }
+           //modified by NIZNHY-PKV Wed Nov 17 15:31:42 2004 t
+           SCRUTE(algoName);
+           //                  ASSERT(0);
+           return false;
+         }
+         StdMeshers_Quadrangle_2D *quadAlgo =
+           dynamic_cast < StdMeshers_Quadrangle_2D * >(algo);
+         ASSERT(quadAlgo);
+         try
+           {
+             _quads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace);
+             // *** to delete after usage
+           }
+         catch(SALOME_Exception & S_ex)
+           {
+             // *** delete _quads
+             // *** throw exception
+             //                        ASSERT(0);
+             return false;
+           }
+
+         // 0.2.1 - number of points on the opposite edges must be the same
+         if (_quads[i]->nbPts[0] != _quads[i]->nbPts[2] ||
+             _quads[i]->nbPts[1] != _quads[i]->nbPts[3])
+           {
+             MESSAGE("different number of points on the opposite edges of face " << i);
+             //                  ASSERT(0);
+             return false;
+           }
+       }
+
+       // 1.  - identify faces and vertices of the "cube"
+       // 1.1 - ancestor maps vertex->edges in the cube
+       //MESSAGE("---");
+
+       TopTools_IndexedDataMapOfShapeListOfShape MS;
+       TopExp::MapShapesAndAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, MS);
+
+       // 1.2 - first face is choosen as face Y=0 of the unit cube
+       //MESSAGE("---");
+
+       const TopoDS_Shape & aFace = meshFaces[0]->GetSubShape();
+       const TopoDS_Face & F = TopoDS::Face(aFace);
+
+       // 1.3 - identify the 4 vertices of the face Y=0: V000, V100, V101, V001
+       //MESSAGE("---");
+
+       int i = 0;
+       TopoDS_Edge E = _quads[0]->edge[i];     //edge will be Y=0,Z=0 on unit cube
+       double f, l;
+       Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+       TopoDS_Vertex VFirst, VLast;
+       TopExp::Vertices(E, VFirst, VLast);     // corresponds to f and l
+       bool isForward =
+               (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0);
+
+       if (isForward)
+       {
+               _cube.V000 = VFirst;    // will be (0,0,0) on the unit cube
+               _cube.V100 = VLast;             // will be (1,0,0) on the unit cube
+       }
+       else
+       {
+               _cube.V000 = VLast;
+               _cube.V100 = VFirst;
+       }
+
+       i = 1;
+       E = _quads[0]->edge[i];
+       C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+       TopExp::Vertices(E, VFirst, VLast);
+       isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0);
+       if (isForward)
+               _cube.V101 = VLast;             // will be (1,0,1) on the unit cube
+       else
+               _cube.V101 = VFirst;
+
+       i = 2;
+       E = _quads[0]->edge[i];
+       C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+       TopExp::Vertices(E, VFirst, VLast);
+       isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0);
+       if (isForward)
+               _cube.V001 = VLast;             // will be (0,0,1) on the unit cube
+       else
+               _cube.V001 = VFirst;
+
+       // 1.4 - find edge X=0, Z=0 (ancestor of V000 not in face Y=0)
+       //     - find edge X=1, Z=0 (ancestor of V100 not in face Y=0)
+       //     - find edge X=1, Z=1 (ancestor of V101 not in face Y=0) 
+       //     - find edge X=0, Z=1 (ancestor of V001 not in face Y=0)
+       //MESSAGE("---");
+
+       TopoDS_Edge E_0Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V000, MS);
+       ASSERT(!E_0Y0.IsNull());
+
+       TopoDS_Edge E_1Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V100, MS);
+       ASSERT(!E_1Y0.IsNull());
+
+       TopoDS_Edge E_1Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V101, MS);
+       ASSERT(!E_1Y1.IsNull());
+
+       TopoDS_Edge E_0Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V001, MS);
+       ASSERT(!E_0Y1.IsNull());
+
+       // 1.5 - identify the 4 vertices in face Y=1: V010, V110, V111, V011
+       //MESSAGE("---");
+
+       TopExp::Vertices(E_0Y0, VFirst, VLast);
+       if (VFirst.IsSame(_cube.V000))
+               _cube.V010 = VLast;
+       else
+               _cube.V010 = VFirst;
+
+       TopExp::Vertices(E_1Y0, VFirst, VLast);
+       if (VFirst.IsSame(_cube.V100))
+               _cube.V110 = VLast;
+       else
+               _cube.V110 = VFirst;
+
+       TopExp::Vertices(E_1Y1, VFirst, VLast);
+       if (VFirst.IsSame(_cube.V101))
+               _cube.V111 = VLast;
+       else
+               _cube.V111 = VFirst;
+
+       TopExp::Vertices(E_0Y1, VFirst, VLast);
+       if (VFirst.IsSame(_cube.V001))
+               _cube.V011 = VLast;
+       else
+               _cube.V011 = VFirst;
+
+       // 1.6 - find remaining faces given 4 vertices
+       //MESSAGE("---");
+
+       _indY0 = 0;
+       _cube.quad_Y0 = _quads[_indY0];
+
+       _indY1 = GetFaceIndex(aMesh, aShape, meshFaces,
+               _cube.V010, _cube.V011, _cube.V110, _cube.V111);
+       _cube.quad_Y1 = _quads[_indY1];
+
+       _indZ0 = GetFaceIndex(aMesh, aShape, meshFaces,
+               _cube.V000, _cube.V010, _cube.V100, _cube.V110);
+       _cube.quad_Z0 = _quads[_indZ0];
+
+       _indZ1 = GetFaceIndex(aMesh, aShape, meshFaces,
+               _cube.V001, _cube.V011, _cube.V101, _cube.V111);
+       _cube.quad_Z1 = _quads[_indZ1];
+
+       _indX0 = GetFaceIndex(aMesh, aShape, meshFaces,
+               _cube.V000, _cube.V001, _cube.V010, _cube.V011);
+       _cube.quad_X0 = _quads[_indX0];
+
+       _indX1 = GetFaceIndex(aMesh, aShape, meshFaces,
+               _cube.V100, _cube.V101, _cube.V110, _cube.V111);
+       _cube.quad_X1 = _quads[_indX1];
+
+       //MESSAGE("---");
+
+       // 1.7 - get convertion coefs from face 2D normalized to 3D normalized
+
+       Conv2DStruct cx0;                       // for face X=0
+       Conv2DStruct cx1;                       // for face X=1
+       Conv2DStruct cy0;
+       Conv2DStruct cy1;
+       Conv2DStruct cz0;
+       Conv2DStruct cz1;
+
+       GetConv2DCoefs(*_cube.quad_X0, meshFaces[_indX0]->GetSubShape(),
+               _cube.V000, _cube.V010, _cube.V011, _cube.V001, cx0);
+       GetConv2DCoefs(*_cube.quad_X1, meshFaces[_indX1]->GetSubShape(),
+               _cube.V100, _cube.V110, _cube.V111, _cube.V101, cx1);
+       GetConv2DCoefs(*_cube.quad_Y0, meshFaces[_indY0]->GetSubShape(),
+               _cube.V000, _cube.V100, _cube.V101, _cube.V001, cy0);
+       GetConv2DCoefs(*_cube.quad_Y1, meshFaces[_indY1]->GetSubShape(),
+               _cube.V010, _cube.V110, _cube.V111, _cube.V011, cy1);
+       GetConv2DCoefs(*_cube.quad_Z0, meshFaces[_indZ0]->GetSubShape(),
+               _cube.V000, _cube.V100, _cube.V110, _cube.V010, cz0);
+       GetConv2DCoefs(*_cube.quad_Z1, meshFaces[_indZ1]->GetSubShape(),
+               _cube.V001, _cube.V101, _cube.V111, _cube.V011, cz1);
+
+       // 1.8 - create a 3D structure for normalized values
+
+       //MESSAGE("---");
+        int nbx = _cube.quad_Z0->nbPts[0];
+        if (cz0.a1 == 0.) nbx = _cube.quad_Z0->nbPts[1];
+        int nby = _cube.quad_X0->nbPts[0];
+        if (cx0.a1 == 0.) nby = _cube.quad_X0->nbPts[1];
+        int nbz = _cube.quad_Y0->nbPts[0];
+        if (cy0.a1 != 0.) nbz = _cube.quad_Y0->nbPts[1];
+
+       int i1, j1, nbxyz = nbx * nby * nbz;
+       Point3DStruct *np = new Point3DStruct[nbxyz];
+
+       // 1.9 - store node indexes of faces
+
+       {
+               const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX0]->GetSubShape());
+
+               faceQuadStruct *quad = _cube.quad_X0;
+               int i = 0;                              // j = x/face , k = y/face
+               int nbdown = quad->nbPts[0];
+               int nbright = quad->nbPts[1];
+
+
+               SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+                       
+               while(itf->more())
+               {
+                       const SMDS_MeshNode * node = itf->next();
+                        findIJ( node, quad, i1, j1 );
+                       int ij1 = j1 * nbdown + i1;
+                       quad->uv_grid[ij1].node = node;
+               }
+
+               for (int i1 = 0; i1 < nbdown; i1++)
+                       for (int j1 = 0; j1 < nbright; j1++)
+                       {
+                               int ij1 = j1 * nbdown + i1;
+                               int j = cx0.ia * i1 + cx0.ib * j1 + cx0.ic;     // j = x/face
+                               int k = cx0.ja * i1 + cx0.jb * j1 + cx0.jc;     // k = y/face
+                               int ijk = k * nbx * nby + j * nbx + i;
+                               //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+                               np[ijk].node = quad->uv_grid[ij1].node;
+                               //SCRUTE(np[ijk].nodeId);
+                       }
+       }
+
+       {
+               const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX1]->GetSubShape());
+
+               SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+
+               faceQuadStruct *quad = _cube.quad_X1;
+               int i = nbx - 1;                // j = x/face , k = y/face
+               int nbdown = quad->nbPts[0];
+               int nbright = quad->nbPts[1];
+
+               while(itf->more())
+               {
+                       const SMDS_MeshNode * node = itf->next();
+                        findIJ( node, quad, i1, j1 );
+                       int ij1 = j1 * nbdown + i1;
+                       quad->uv_grid[ij1].node = node;
+               }
+
+               for (int i1 = 0; i1 < nbdown; i1++)
+                       for (int j1 = 0; j1 < nbright; j1++)
+                       {
+                               int ij1 = j1 * nbdown + i1;
+                               int j = cx1.ia * i1 + cx1.ib * j1 + cx1.ic;     // j = x/face
+                               int k = cx1.ja * i1 + cx1.jb * j1 + cx1.jc;     // k = y/face
+                               int ijk = k * nbx * nby + j * nbx + i;
+                               //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+                               np[ijk].node = quad->uv_grid[ij1].node;
+                               //SCRUTE(np[ijk].nodeId);
+                       }
+       }
+
+       {
+               const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY0]->GetSubShape());
+
+               SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+
+               faceQuadStruct *quad = _cube.quad_Y0;
+               int j = 0;                              // i = x/face , k = y/face
+               int nbdown = quad->nbPts[0];
+               int nbright = quad->nbPts[1];
+
+               while(itf->more())
+               {
+                       const SMDS_MeshNode * node = itf->next();
+                        findIJ( node, quad, i1, j1 );
+                       int ij1 = j1 * nbdown + i1;
+                       quad->uv_grid[ij1].node = node;
+               }
+
+               for (int i1 = 0; i1 < nbdown; i1++)
+                       for (int j1 = 0; j1 < nbright; j1++)
+                       {
+                               int ij1 = j1 * nbdown + i1;
+                               int i = cy0.ia * i1 + cy0.ib * j1 + cy0.ic;     // i = x/face
+                               int k = cy0.ja * i1 + cy0.jb * j1 + cy0.jc;     // k = y/face
+                               int ijk = k * nbx * nby + j * nbx + i;
+                               //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+                               np[ijk].node = quad->uv_grid[ij1].node;
+                               //SCRUTE(np[ijk].nodeId);
+                       }
+       }
+
+       {
+               const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY1]->GetSubShape());
+
+               SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+
+               faceQuadStruct *quad = _cube.quad_Y1;
+               int j = nby - 1;                // i = x/face , k = y/face
+               int nbdown = quad->nbPts[0];
+               int nbright = quad->nbPts[1];
+
+               while(itf->more())
+               {
+                       const SMDS_MeshNode * node = itf->next();
+                        findIJ( node, quad, i1, j1 );
+                       int ij1 = j1 * nbdown + i1;
+                       quad->uv_grid[ij1].node = node;
+               }
+
+               for (int i1 = 0; i1 < nbdown; i1++)
+                       for (int j1 = 0; j1 < nbright; j1++)
+                       {
+                               int ij1 = j1 * nbdown + i1;
+                               int i = cy1.ia * i1 + cy1.ib * j1 + cy1.ic;     // i = x/face
+                               int k = cy1.ja * i1 + cy1.jb * j1 + cy1.jc;     // k = y/face
+                               int ijk = k * nbx * nby + j * nbx + i;
+                               //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+                               np[ijk].node = quad->uv_grid[ij1].node;
+                               //SCRUTE(np[ijk].nodeId);
+                       }
+       }
+
+       {
+               const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ0]->GetSubShape());
+
+               SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+
+               faceQuadStruct *quad = _cube.quad_Z0;
+               int k = 0;                              // i = x/face , j = y/face
+               int nbdown = quad->nbPts[0];
+               int nbright = quad->nbPts[1];
+
+               while(itf->more())
+               {
+                       const SMDS_MeshNode * node = itf->next();
+                        findIJ( node, quad, i1, j1 );
+                       int ij1 = j1 * nbdown + i1;
+                       quad->uv_grid[ij1].node = node;
+               }
+
+               for (int i1 = 0; i1 < nbdown; i1++)
+                       for (int j1 = 0; j1 < nbright; j1++)
+                       {
+                               int ij1 = j1 * nbdown + i1;
+                               int i = cz0.ia * i1 + cz0.ib * j1 + cz0.ic;     // i = x/face
+                               int j = cz0.ja * i1 + cz0.jb * j1 + cz0.jc;     // j = y/face
+                               int ijk = k * nbx * nby + j * nbx + i;
+                               //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+                               np[ijk].node = quad->uv_grid[ij1].node;
+                               //SCRUTE(np[ijk].nodeId);
+                       }
+       }
+
+       {
+               const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ1]->GetSubShape());
+
+               SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+
+               faceQuadStruct *quad = _cube.quad_Z1;
+               int k = nbz - 1;                // i = x/face , j = y/face
+               int nbdown = quad->nbPts[0];
+               int nbright = quad->nbPts[1];
+
+               while(itf->more())
+               {
+                       const SMDS_MeshNode * node = itf->next();
+                        findIJ( node, quad, i1, j1 );
+                       int ij1 = j1 * nbdown + i1;
+                       quad->uv_grid[ij1].node = node;
+               }
+
+               for (int i1 = 0; i1 < nbdown; i1++)
+                       for (int j1 = 0; j1 < nbright; j1++)
+                       {
+                               int ij1 = j1 * nbdown + i1;
+                               int i = cz1.ia * i1 + cz1.ib * j1 + cz1.ic;     // i = x/face
+                               int j = cz1.ja * i1 + cz1.jb * j1 + cz1.jc;     // j = y/face
+                               int ijk = k * nbx * nby + j * nbx + i;
+                               //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+                               np[ijk].node = quad->uv_grid[ij1].node;
+                               //SCRUTE(np[ijk].nodeId);
+                       }
+       }
+
+       // 2.0 - for each node of the cube:
+       //       - get the 8 points 3D = 8 vertices of the cube
+       //       - get the 12 points 3D on the 12 edges of the cube
+       //       - get the 6 points 3D on the 6 faces with their ID
+       //       - compute the point 3D
+       //       - store the point 3D in SMESHDS, store its ID in 3D structure
+
+        int shapeID = meshDS->ShapeToIndex( aShape );
+
+       Pt3 p000, p001, p010, p011, p100, p101, p110, p111;
+       Pt3 px00, px01, px10, px11;
+       Pt3 p0y0, p0y1, p1y0, p1y1;
+       Pt3 p00z, p01z, p10z, p11z;
+       Pt3 pxy0, pxy1, px0z, px1z, p0yz, p1yz;
+
+       GetPoint(p000, 0, 0, 0, nbx, nby, nbz, np, meshDS);
+       GetPoint(p001, 0, 0, nbz - 1, nbx, nby, nbz, np, meshDS);
+       GetPoint(p010, 0, nby - 1, 0, nbx, nby, nbz, np, meshDS);
+       GetPoint(p011, 0, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS);
+       GetPoint(p100, nbx - 1, 0, 0, nbx, nby, nbz, np, meshDS);
+       GetPoint(p101, nbx - 1, 0, nbz - 1, nbx, nby, nbz, np, meshDS);
+       GetPoint(p110, nbx - 1, nby - 1, 0, nbx, nby, nbz, np, meshDS);
+       GetPoint(p111, nbx - 1, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS);
+
+       for (int i = 1; i < nbx - 1; i++)
+       {
+               for (int j = 1; j < nby - 1; j++)
+               {
+                       for (int k = 1; k < nbz - 1; k++)
+                       {
+                               // *** seulement maillage regulier
+                               // 12 points on edges
+                               GetPoint(px00, i, 0, 0, nbx, nby, nbz, np, meshDS);
+                               GetPoint(px01, i, 0, nbz - 1, nbx, nby, nbz, np, meshDS);
+                               GetPoint(px10, i, nby - 1, 0, nbx, nby, nbz, np, meshDS);
+                               GetPoint(px11, i, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS);
+
+                               GetPoint(p0y0, 0, j, 0, nbx, nby, nbz, np, meshDS);
+                               GetPoint(p0y1, 0, j, nbz - 1, nbx, nby, nbz, np, meshDS);
+                               GetPoint(p1y0, nbx - 1, j, 0, nbx, nby, nbz, np, meshDS);
+                               GetPoint(p1y1, nbx - 1, j, nbz - 1, nbx, nby, nbz, np, meshDS);
+
+                               GetPoint(p00z, 0, 0, k, nbx, nby, nbz, np, meshDS);
+                               GetPoint(p01z, 0, nby - 1, k, nbx, nby, nbz, np, meshDS);
+                               GetPoint(p10z, nbx - 1, 0, k, nbx, nby, nbz, np, meshDS);
+                               GetPoint(p11z, nbx - 1, nby - 1, k, nbx, nby, nbz, np, meshDS);
+
+                               // 12 points on faces
+                               GetPoint(pxy0, i, j, 0, nbx, nby, nbz, np, meshDS);
+                               GetPoint(pxy1, i, j, nbz - 1, nbx, nby, nbz, np, meshDS);
+                               GetPoint(px0z, i, 0, k, nbx, nby, nbz, np, meshDS);
+                               GetPoint(px1z, i, nby - 1, k, nbx, nby, nbz, np, meshDS);
+                               GetPoint(p0yz, 0, j, k, nbx, nby, nbz, np, meshDS);
+                               GetPoint(p1yz, nbx - 1, j, k, nbx, nby, nbz, np, meshDS);
+
+                               int ijk = k * nbx * nby + j * nbx + i;
+                               double x = double (i) / double (nbx - 1);       // *** seulement
+                               double y = double (j) / double (nby - 1);       // *** maillage
+                               double z = double (k) / double (nbz - 1);       // *** regulier
+
+                               Pt3 X;
+                               for (int i = 0; i < 3; i++)
+                               {
+                                       X[i] =
+                                               (1 - x) * p0yz[i] + x * p1yz[i]
+                                               + (1 - y) * px0z[i] + y * px1z[i]
+                                               + (1 - z) * pxy0[i] + z * pxy1[i]
+                                               - (1 - x) * ((1 - y) * p00z[i] + y * p01z[i])
+                                               - x * ((1 - y) * p10z[i] + y * p11z[i])
+                                               - (1 - y) * ((1 - z) * px00[i] + z * px01[i])
+                                               - y * ((1 - z) * px10[i] + z * px11[i])
+                                               - (1 - z) * ((1 - x) * p0y0[i] + x * p1y0[i])
+                                               - z * ((1 - x) * p0y1[i] + x * p1y1[i])
+                                               + (1 - x) * ((1 - y) * ((1 - z) * p000[i] + z * p001[i])
+                                               + y * ((1 - z) * p010[i] + z * p011[i]))
+                                               + x * ((1 - y) * ((1 - z) * p100[i] + z * p101[i])
+                                               + y * ((1 - z) * p110[i] + z * p111[i]));
+                               }
+
+                               SMDS_MeshNode * node = meshDS->AddNode(X[0], X[1], X[2]);
+                               np[ijk].node = node;
+                                meshDS->SetNodeInVolume(node, shapeID);
+                       }
+               }
+       }
+
+  // find orientation of furute volumes according to MED convention
+  vector< bool > forward( nbx * nby );
+  SMDS_VolumeTool vTool;
+  for (int i = 0; i < nbx - 1; i++)
+    for (int j = 0; j < nby - 1; j++)
+    {
+      int n1 = j * nbx + i;
+      int n2 = j * nbx + i + 1;
+      int n3 = (j + 1) * nbx + i + 1;
+      int n4 = (j + 1) * nbx + i;
+      int n5 = nbx * nby + j * nbx + i;
+      int n6 = nbx * nby + j * nbx + i + 1;
+      int n7 = nbx * nby + (j + 1) * nbx + i + 1;
+      int n8 = nbx * nby + (j + 1) * nbx + i;
+
+      SMDS_VolumeOfNodes tmpVol (np[n1].node,np[n2].node,np[n3].node,np[n4].node,
+                                 np[n5].node,np[n6].node,np[n7].node,np[n8].node);
+      vTool.Set( &tmpVol );
+      forward[ n1 ] = vTool.IsForward();
+    }
+
+       //2.1 - for each node of the cube (less 3 *1 Faces):
+       //      - store hexahedron in SMESHDS
+       MESSAGE("Storing hexahedron into the DS");
+       for (int i = 0; i < nbx - 1; i++)
+               for (int j = 0; j < nby - 1; j++)
+                {
+                        bool isForw = forward.at( j * nbx + i );
+                       for (int k = 0; k < nbz - 1; k++)
+                       {
+                               int n1 = k * nbx * nby + j * nbx + i;
+                               int n2 = k * nbx * nby + j * nbx + i + 1;
+                               int n3 = k * nbx * nby + (j + 1) * nbx + i + 1;
+                               int n4 = k * nbx * nby + (j + 1) * nbx + i;
+                               int n5 = (k + 1) * nbx * nby + j * nbx + i;
+                               int n6 = (k + 1) * nbx * nby + j * nbx + i + 1;
+                               int n7 = (k + 1) * nbx * nby + (j + 1) * nbx + i + 1;
+                               int n8 = (k + 1) * nbx * nby + (j + 1) * nbx + i;
+
+                               SMDS_MeshVolume * elt;
+                                if ( isForw )
+                                  elt = meshDS->AddVolume(np[n1].node,
+                                                          np[n2].node,
+                                                          np[n3].node,
+                                                          np[n4].node,
+                                                          np[n5].node,
+                                                          np[n6].node,
+                                                          np[n7].node,
+                                                          np[n8].node);
+                                else
+                                  elt = meshDS->AddVolume(np[n1].node,
+                                                          np[n4].node,
+                                                          np[n3].node,
+                                                          np[n2].node,
+                                                          np[n5].node,
+                                                          np[n8].node,
+                                                          np[n7].node,
+                                                          np[n6].node);
+
+                                meshDS->SetMeshElementOnShape(elt, shapeID);
+                              }
+                      }
+  if ( np ) delete [] np;
+       //MESSAGE("End of StdMeshers_Hexa_3D::Compute()");
+       return true;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+void StdMeshers_Hexa_3D::GetPoint(Pt3 p, int i, int j, int k, int nbx, int nby,
+       int nbz, Point3DStruct * np, const SMESHDS_Mesh * meshDS)
+{
+       int ijk = k * nbx * nby + j * nbx + i;
+       const SMDS_MeshNode * node = np[ijk].node;
+       p[0] = node->X();
+       p[1] = node->Y();
+       p[2] = node->Z();
+       //MESSAGE(" "<<i<<" "<<j<<" "<<k<<" "<<p[0]<<" "<<p[1]<<" "<<p[2]);
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+int StdMeshers_Hexa_3D::GetFaceIndex(SMESH_Mesh & aMesh,
+       const TopoDS_Shape & aShape,
+       const vector < SMESH_subMesh * >&meshFaces,
+       const TopoDS_Vertex & V0,
+       const TopoDS_Vertex & V1,
+       const TopoDS_Vertex & V2, const TopoDS_Vertex & V3)
+{
+       //MESSAGE("StdMeshers_Hexa_3D::GetFaceIndex");
+       int faceIndex = -1;
+       for (int i = 1; i < 6; i++)
+       {
+               const TopoDS_Shape & aFace = meshFaces[i]->GetSubShape();
+               //const TopoDS_Face& F = TopoDS::Face(aFace);
+               TopTools_IndexedMapOfShape M;
+               TopExp::MapShapes(aFace, TopAbs_VERTEX, M);
+               bool verticesInShape = false;
+               if (M.Contains(V0))
+                       if (M.Contains(V1))
+                               if (M.Contains(V2))
+                                       if (M.Contains(V3))
+                                               verticesInShape = true;
+               if (verticesInShape)
+               {
+                       faceIndex = i;
+                       break;
+               }
+       }
+       ASSERT(faceIndex > 0);
+       //SCRUTE(faceIndex);
+       return faceIndex;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+TopoDS_Edge
+       StdMeshers_Hexa_3D::EdgeNotInFace(SMESH_Mesh & aMesh,
+       const TopoDS_Shape & aShape,
+       const TopoDS_Face & aFace,
+       const TopoDS_Vertex & aVertex,
+       const TopTools_IndexedDataMapOfShapeListOfShape & MS)
+{
+       //MESSAGE("StdMeshers_Hexa_3D::EdgeNotInFace");
+       TopTools_IndexedDataMapOfShapeListOfShape MF;
+       TopExp::MapShapesAndAncestors(aFace, TopAbs_VERTEX, TopAbs_EDGE, MF);
+       const TopTools_ListOfShape & ancestorsInSolid = MS.FindFromKey(aVertex);
+       const TopTools_ListOfShape & ancestorsInFace = MF.FindFromKey(aVertex);
+//     SCRUTE(ancestorsInSolid.Extent());
+//     SCRUTE(ancestorsInFace.Extent());
+       ASSERT(ancestorsInSolid.Extent() == 6); // 6 (edges doublees)
+       ASSERT(ancestorsInFace.Extent() == 2);
+
+       TopoDS_Edge E;
+       E.Nullify();
+       TopTools_ListIteratorOfListOfShape its(ancestorsInSolid);
+       for (; its.More(); its.Next())
+       {
+               TopoDS_Shape ancestor = its.Value();
+               TopTools_ListIteratorOfListOfShape itf(ancestorsInFace);
+               bool isInFace = false;
+               for (; itf.More(); itf.Next())
+               {
+                       TopoDS_Shape ancestorInFace = itf.Value();
+                       if (ancestorInFace.IsSame(ancestor))
+                       {
+                               isInFace = true;
+                               break;
+                       }
+               }
+               if (!isInFace)
+               {
+                       E = TopoDS::Edge(ancestor);
+                       break;
+               }
+       }
+       return E;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+void StdMeshers_Hexa_3D::GetConv2DCoefs(const faceQuadStruct & quad,
+       const TopoDS_Shape & aShape,
+       const TopoDS_Vertex & V0,
+       const TopoDS_Vertex & V1,
+       const TopoDS_Vertex & V2, const TopoDS_Vertex & V3, Conv2DStruct & conv)
+{
+//     MESSAGE("StdMeshers_Hexa_3D::GetConv2DCoefs");
+       const TopoDS_Face & F = TopoDS::Face(aShape);
+       TopoDS_Edge E = quad.edge[0];
+       double f, l;
+       Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+       TopoDS_Vertex VFirst, VLast;
+       TopExp::Vertices(E, VFirst, VLast);     // corresponds to f and l
+       bool isForward = (((l - f) * (quad.last[0] - quad.first[0])) > 0);
+       TopoDS_Vertex VA, VB;
+       if (isForward)
+       {
+               VA = VFirst;
+               VB = VLast;
+       }
+       else
+       {
+               VA = VLast;
+               VB = VFirst;
+       }
+       int a1, b1, c1, a2, b2, c2;
+       if (VA.IsSame(V0))
+               if (VB.IsSame(V1))
+               {
+                       a1 = 1;
+                       b1 = 0;
+                       c1 = 0;                         // x
+                       a2 = 0;
+                       b2 = 1;
+                       c2 = 0;                         // y
+               }
+               else
+               {
+                       ASSERT(VB.IsSame(V3));
+                       a1 = 0;
+                       b1 = 1;
+                       c1 = 0;                         // y
+                       a2 = 1;
+                       b2 = 0;
+                       c2 = 0;                         // x
+               }
+       if (VA.IsSame(V1))
+               if (VB.IsSame(V2))
+               {
+                       a1 = 0;
+                       b1 = -1;
+                       c1 = 1;                         // 1-y
+                       a2 = 1;
+                       b2 = 0;
+                       c2 = 0;                         // x
+               }
+               else
+               {
+                       ASSERT(VB.IsSame(V0));
+                       a1 = -1;
+                       b1 = 0;
+                       c1 = 1;                         // 1-x
+                       a2 = 0;
+                       b2 = 1;
+                       c2 = 0;                         // y
+               }
+       if (VA.IsSame(V2))
+               if (VB.IsSame(V3))
+               {
+                       a1 = -1;
+                       b1 = 0;
+                       c1 = 1;                         // 1-x
+                       a2 = 0;
+                       b2 = -1;
+                       c2 = 1;                         // 1-y
+               }
+               else
+               {
+                       ASSERT(VB.IsSame(V1));
+                       a1 = 0;
+                       b1 = -1;
+                       c1 = 1;                         // 1-y
+                       a2 = -1;
+                       b2 = 0;
+                       c2 = 1;                         // 1-x
+               }
+       if (VA.IsSame(V3))
+               if (VB.IsSame(V0))
+               {
+                       a1 = 0;
+                       b1 = 1;
+                       c1 = 0;                         // y
+                       a2 = -1;
+                       b2 = 0;
+                       c2 = 1;                         // 1-x
+               }
+               else
+               {
+                       ASSERT(VB.IsSame(V2));
+                       a1 = 1;
+                       b1 = 0;
+                       c1 = 0;                         // x
+                       a2 = 0;
+                       b2 = -1;
+                       c2 = 1;                         // 1-y
+               }
+//     MESSAGE("X = " << c1 << "+ " << a1 << "*x + " << b1 << "*y");
+//     MESSAGE("Y = " << c2 << "+ " << a2 << "*x + " << b2 << "*y");
+       conv.a1 = a1;
+       conv.b1 = b1;
+       conv.c1 = c1;
+       conv.a2 = a2;
+       conv.b2 = b2;
+       conv.c2 = c2;
+
+       int nbdown = quad.nbPts[0];
+       int nbright = quad.nbPts[1];
+       conv.ia = int (a1);
+       conv.ib = int (b1);
+       conv.ic =
+               int (c1 * a1 * a1) * (nbdown - 1) + int (c1 * b1 * b1) * (nbright - 1);
+       conv.ja = int (a2);
+       conv.jb = int (b2);
+       conv.jc =
+               int (c2 * a2 * a2) * (nbdown - 1) + int (c2 * b2 * b2) * (nbright - 1);
+//     MESSAGE("I " << conv.ia << " " << conv.ib << " " << conv.ic);
+//     MESSAGE("J " << conv.ja << " " << conv.jb << " " << conv.jc);
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+ostream & StdMeshers_Hexa_3D::SaveTo(ostream & save)
+{
+  return save;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+istream & StdMeshers_Hexa_3D::LoadFrom(istream & load)
+{
+  return load;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+ostream & operator <<(ostream & save, StdMeshers_Hexa_3D & hyp)
+{
+  return hyp.SaveTo( save );
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+istream & operator >>(istream & load, StdMeshers_Hexa_3D & hyp)
+{
+  return hyp.LoadFrom( load );
+}
+
+//modified by NIZNHY-PKV Wed Nov 17 15:34:13 2004 f
+///////////////////////////////////////////////////////////////////////////////
+//ZZ
+//#include <stdio.h>
+
+//=======================================================================
+//function : ComputePentahedralMesh
+//purpose  : 
+//=======================================================================
+bool ComputePentahedralMesh(SMESH_Mesh & aMesh,        const TopoDS_Shape & aShape)
+{
+  //printf(" ComputePentahedralMesh HERE\n");
+  //
+  bool bOK;
+  //int iErr;
+  StdMeshers_Penta_3D anAlgo;
+  //
+  bOK=anAlgo.Compute(aMesh, aShape);
+  /*
+  iErr=anAlgo.ErrorStatus();
+  
+  if (iErr) {
+    printf("  *** Error# %d\n", iErr);
+  }
+  else {
+    printf("  *** No errors# %d\n", iErr);
+  }
+  */
+  return bOK;
+}
+
diff --git a/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx b/src/StdMeshers/StdMeshers_MEFISTO_2D.cxx
new file mode 100644 (file)
index 0000000..ed166fc
--- /dev/null
@@ -0,0 +1,872 @@
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : StdMeshers_MEFISTO_2D.cxx
+//           Moved here from SMESH_MEFISTO_2D.cxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+using namespace std;
+#include "StdMeshers_MEFISTO_2D.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_subMesh.hxx"
+
+#include "StdMeshers_MaxElementArea.hxx"
+#include "StdMeshers_LengthFromEdges.hxx"
+
+#include "Rn.h"
+#include "aptrte.h"
+
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_FacePosition.hxx"
+
+#include "utilities.h"
+
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Shape.hxx>
+#include <Geom_Surface.hxx>
+#include <GeomAdaptor_Curve.hxx>
+#include <Geom2d_Curve.hxx>
+#include <gp_Pnt2d.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepTools.hxx>
+#include <BRepTools_WireExplorer.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <GCPnts_UniformAbscissa.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+
+#include <string>
+//#include <algorithm>
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId,
+       SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen)
+{
+       MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D");
+       _name = "MEFISTO_2D";
+//   _shapeType = TopAbs_FACE;
+       _shapeType = (1 << TopAbs_FACE);
+       _compatibleHypothesis.push_back("MaxElementArea");
+       _compatibleHypothesis.push_back("LengthFromEdges");
+
+       _edgeLength = 0;
+       _maxElementArea = 0;
+       _hypMaxElementArea = NULL;
+       _hypLengthFromEdges = NULL;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D()
+{
+       MESSAGE("StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D");
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+bool StdMeshers_MEFISTO_2D::CheckHypothesis
+                         (SMESH_Mesh& aMesh,
+                          const TopoDS_Shape& aShape,
+                          SMESH_Hypothesis::Hypothesis_Status& aStatus)
+{
+       //MESSAGE("StdMeshers_MEFISTO_2D::CheckHypothesis");
+
+       _hypMaxElementArea = NULL;
+       _hypLengthFromEdges = NULL;
+
+       list <const SMESHDS_Hypothesis * >::const_iterator itl;
+       const SMESHDS_Hypothesis *theHyp;
+
+       const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
+       int nbHyp = hyps.size();
+        if (!nbHyp)
+        {
+          aStatus = SMESH_Hypothesis::HYP_MISSING;
+          return false;  // can't work with no hypothesis
+        }
+
+       itl = hyps.begin();
+       theHyp = (*itl); // use only the first hypothesis
+
+       string hypName = theHyp->GetName();
+       //int hypId = theHyp->GetID();
+       //SCRUTE(hypName);
+
+       bool isOk = false;
+
+       if (hypName == "MaxElementArea")
+       {
+               _hypMaxElementArea = static_cast<const StdMeshers_MaxElementArea *>(theHyp);
+               ASSERT(_hypMaxElementArea);
+               _maxElementArea = _hypMaxElementArea->GetMaxArea();
+               _edgeLength = 0;
+               isOk = true;
+                aStatus = SMESH_Hypothesis::HYP_OK;
+       }
+
+       else if (hypName == "LengthFromEdges")
+       {
+               _hypLengthFromEdges = static_cast<const StdMeshers_LengthFromEdges *>(theHyp);
+               ASSERT(_hypLengthFromEdges);
+               _edgeLength = 0;
+               _maxElementArea = 0;
+               isOk = true;
+                aStatus = SMESH_Hypothesis::HYP_OK;
+       }
+        else
+          aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+
+       if (isOk)
+       {
+               isOk = false;
+               if (_maxElementArea > 0)
+               {
+//                     _edgeLength = 2 * sqrt(_maxElementArea);        // triangles : minorant
+                       _edgeLength = 2 * sqrt(_maxElementArea/sqrt(3.0));
+                       isOk = true;
+               }
+               else
+                       isOk = (_hypLengthFromEdges != NULL);   // **** check mode
+                if (!isOk)
+                  aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
+       }
+
+       //SCRUTE(_edgeLength);
+       //SCRUTE(_maxElementArea);
+       return isOk;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
+{
+       MESSAGE("StdMeshers_MEFISTO_2D::Compute");
+
+       if (_hypLengthFromEdges)
+               _edgeLength = ComputeEdgeElementLength(aMesh, aShape);
+
+       bool isOk = false;
+       //const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+       //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
+
+       const TopoDS_Face & FF = TopoDS::Face(aShape);
+       bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
+       TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
+
+       Z nblf;                                         //nombre de lignes fermees (enveloppe en tete)
+       Z *nudslf = NULL;                       //numero du dernier sommet de chaque ligne fermee
+       R2 *uvslf = NULL;
+       Z nbpti = 0;                            //nombre points internes futurs sommets de la triangulation
+       R2 *uvpti = NULL;
+
+       Z nbst;
+       R2 *uvst = NULL;
+       Z nbt;
+       Z *nust = NULL;
+       Z ierr = 0;
+
+       Z nutysu = 1;                           // 1: il existe un fonction areteideale_()
+       // Z  nutysu=0;              // 0: on utilise aretmx
+       R aretmx = _edgeLength;         // longueur max aretes future triangulation
+
+       nblf = NumberOfWires(F);
+
+       nudslf = new Z[1 + nblf];
+       nudslf[0] = 0;
+       int iw = 1;
+       int nbpnt = 0;
+
+       myOuterWire = BRepTools::OuterWire(F);
+       nbpnt += NumberOfPoints(aMesh, myOuterWire);
+        if ( nbpnt < 3 ) // ex: a circle with 2 segments
+          return false;
+       nudslf[iw++] = nbpnt;
+
+       for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
+       {
+               const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
+               if (!myOuterWire.IsSame(W))
+               {
+                       nbpnt += NumberOfPoints(aMesh, W);
+                       nudslf[iw++] = nbpnt;
+               }
+       }
+
+        // avoid passing same uv points for a vertex common to 2 wires
+        TopTools_IndexedDataMapOfShapeListOfShape VWMap;
+        if ( iw - 1 > 1 ) // nbofWires > 1
+          TopExp::MapShapesAndAncestors( F , TopAbs_VERTEX, TopAbs_WIRE, VWMap );
+
+       uvslf = new R2[nudslf[nblf]];
+       int m = 0;
+
+        double scalex, scaley;
+        ComputeScaleOnFace(aMesh, F, scalex, scaley);
+
+        map<int, const SMDS_MeshNode*> mefistoToDS;    // correspondence mefisto index--> points IDNodes
+       if ( !LoadPoints(aMesh, F, myOuterWire, uvslf, m,
+                         mefistoToDS, scalex, scaley, VWMap))
+          return false;
+
+       for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
+       {
+               const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
+               if (!myOuterWire.IsSame(W))
+               {
+                       if (! LoadPoints(aMesh, F, W, uvslf, m,
+                                         mefistoToDS, scalex, scaley, VWMap ))
+                          return false;
+               }
+       }
+
+       uvst = NULL;
+       nust = NULL;
+       aptrte(nutysu, aretmx,
+               nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr);
+
+       if (ierr == 0)
+         {
+           MESSAGE("... End Triangulation Generated Triangle Number " << nbt);
+           MESSAGE("                                    Node Number " << nbst);
+           StoreResult(aMesh, nbst, uvst, nbt, nust, F,
+                       faceIsForward, mefistoToDS, scalex, scaley);
+           isOk = true;
+         }
+       else
+       {
+               MESSAGE("Error in Triangulation");
+               isOk = false;
+       }
+       if (nudslf != NULL)
+               delete[]nudslf;
+       if (uvslf != NULL)
+               delete[]uvslf;
+       if (uvst != NULL)
+               delete[]uvst;
+       if (nust != NULL)
+               delete[]nust;
+       return isOk;
+}
+
+//=======================================================================
+//function : fixOverlappedLinkUV
+//purpose  : prevent failure due to overlapped adjacent links
+//=======================================================================
+
+static bool fixOverlappedLinkUV( R2& uv0, const R2& uv1, const R2& uv2 )
+{
+  gp_XY v1( uv0.x - uv1.x, uv0.y - uv1.y );
+  gp_XY v2( uv2.x - uv1.x, uv2.y - uv1.y );
+
+  double tol2 = DBL_MIN * DBL_MIN;
+  double sqMod1 = v1.SquareModulus();
+  if ( sqMod1 <= tol2 ) return false;
+  double sqMod2 = v2.SquareModulus();
+  if ( sqMod2 <= tol2 ) return false;
+
+  double dot = v1*v2;
+
+  // check sinus >= 1.e-3
+  const double minSin = 1.e-3;
+  if ( dot > 0 && 1 - dot * dot / ( sqMod1 * sqMod2 ) < minSin * minSin ) {
+    MESSAGE(" ___ FIX UV ____" << uv0.x << " " << uv0.y);
+    v1.SetCoord( -v1.Y(), v1.X() );
+    double delta = sqrt( sqMod1 ) * minSin;
+    if ( v1.X() < 0 )
+      uv0.x -= delta;
+    else
+      uv0.x += delta;
+    if ( v1.Y() < 0 )
+      uv0.y -= delta;
+    else
+      uv0.y += delta;
+//    MESSAGE(" -> " << uv0.x << " " << uv0.y << " ");
+//     MESSAGE("v1( " << v1.X() << " " << v1.Y() << " ) " <<
+//       "v2( " << v2.X() << " " << v2.Y() << " ) ");
+//    MESSAGE("SIN: " << sqrt(1 - dot * dot / (sqMod1 * sqMod2)));
+//     v1.SetCoord( uv0.x - uv1.x, uv0.y - uv1.y );
+//     v2.SetCoord( uv2.x - uv1.x, uv2.y - uv1.y );
+//     gp_XY v3( uv2.x - uv0.x, uv2.y - uv0.y );
+//     sqMod1 = v1.SquareModulus();
+//     sqMod2 = v2.SquareModulus();
+//     dot = v1*v2;
+//     double sin = sqrt(1 - dot * dot / (sqMod1 * sqMod2));
+//     MESSAGE("NEW SIN: " << sin);
+    return true;
+  }
+  return false;
+}
+
+//=======================================================================
+//function : fixCommonVertexUV
+//purpose  : 
+//=======================================================================
+
+static bool fixCommonVertexUV (gp_Pnt2d &           theUV,
+                               const TopoDS_Vertex& theV,
+                               const TopoDS_Wire&   theW,
+                               const TopoDS_Wire&   theOW,
+                               const TopoDS_Face&   theF,
+                               const TopTools_IndexedDataMapOfShapeListOfShape & theVWMap,
+                               SMESH_Mesh &         theMesh)
+{
+  if( theW.IsSame( theOW ) ||
+      !theVWMap.Contains( theV )) return false;
+
+  // check if there is another wire sharing theV
+  const TopTools_ListOfShape& WList = theVWMap.FindFromKey( theV );
+  TopTools_ListIteratorOfListOfShape aWIt;
+  for ( aWIt.Initialize( WList ); aWIt.More(); aWIt.Next() )
+    if ( !theW.IsSame( aWIt.Value() ))
+      break;
+  if ( !aWIt.More() ) return false;
+
+  TopTools_ListOfShape EList;
+  list< double >       UList;
+
+  // find edges of theW sharing theV
+  // and find 2d normal to them at theV
+  gp_Vec2d N(0.,0.);
+  TopoDS_Iterator itE( theW );
+  for (  ; itE.More(); itE.Next() )
+  {
+    const TopoDS_Edge& E = TopoDS::Edge( itE.Value() );
+    TopoDS_Iterator itV( E );
+    for ( ; itV.More(); itV.Next() )
+    {
+      const TopoDS_Vertex & V = TopoDS::Vertex( itV.Value() );
+      if ( !V.IsSame( theV ))
+        continue;
+      EList.Append( E );
+      Standard_Real u = BRep_Tool::Parameter( V, E );
+      UList.push_back( u );
+      double f, l;
+      Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
+      gp_Vec2d d1;
+      gp_Pnt2d p;
+      C2d->D1( u, p, d1 );
+      gp_Vec2d n( d1.Y(), -d1.X() );
+      if ( E.Orientation() == TopAbs_REVERSED )
+        n.Reverse();
+      N += n.Normalized();
+    }
+  }
+
+  // define step size by which to move theUV
+
+  gp_Pnt2d nextUV; // uv of next node on edge, most distant of the four
+  double maxDist = -DBL_MAX;
+  TopTools_ListIteratorOfListOfShape aEIt (EList);
+  list< double >::iterator aUIt = UList.begin();
+  for ( ; aEIt.More(); aEIt.Next(), aUIt++ )
+  {
+    const TopoDS_Edge& E = TopoDS::Edge( aEIt.Value() );
+    double f, l;
+    Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, theF, f, l);
+
+    double umin = DBL_MAX, umax = -DBL_MAX;
+    SMDS_NodeIteratorPtr nIt = theMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
+    if ( !nIt->more() ) // no nodes on edge, only on vertices
+    {
+      umin = l;
+      umax = f;
+    }
+    else
+    {
+      while ( nIt->more() ) {
+        const SMDS_MeshNode* node = nIt->next();
+        const SMDS_EdgePosition* epos =
+          static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+        double u = epos->GetUParameter();
+        if ( u < umin )
+          umin = u;
+        if ( u > umax )
+          umax = u;
+      }
+    }
+    bool isFirstCommon = ( *aUIt == f );
+    gp_Pnt2d uv = C2d->Value( isFirstCommon ? umin : umax );
+    double dist = theUV.SquareDistance( uv );
+    if ( dist > maxDist ) {
+      maxDist = dist;
+      nextUV  = uv;
+    }
+  }
+  R2 uv0, uv1, uv2;
+  uv0.x = theUV.X();    uv0.y = theUV.Y(); 
+  uv1.x = nextUV.X();   uv1.y = nextUV.Y(); 
+  uv2.x = uv0.x;        uv2.y = uv0.y;
+  if ( fixOverlappedLinkUV( uv0, uv1, uv2 ))
+  {
+    double step = theUV.Distance( gp_Pnt2d( uv0.x, uv0.y ));
+
+    // move theUV along the normal by the step
+
+    N *= step;
+
+    MESSAGE("--fixCommonVertexUV move(" << theUV.X() << " " << theUV.Y()
+            << ") by (" << N.X() << " " << N.Y() << ")" 
+            << endl << "--- MAX DIST " << maxDist);
+
+    theUV.SetXY( theUV.XY() + N.XY() );
+
+    return true;
+  }
+  return false;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh &        aMesh,
+                                       const TopoDS_Face & FF,
+                                       const TopoDS_Wire & WW,
+                                       R2 *                uvslf,
+                                       int &               m,
+                                       map<int, const SMDS_MeshNode*>&mefistoToDS,
+                                       double              scalex,
+                                       double              scaley,
+                                       const TopTools_IndexedDataMapOfShapeListOfShape& VWMap)
+{
+//  MESSAGE("StdMeshers_MEFISTO_2D::LoadPoints");
+
+  //SMDS_Mesh * meshDS = aMesh.GetMeshDS();
+
+  TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
+
+  int mInit = m, mFirst, iEdge;
+  gp_XY scale( scalex, scaley );
+
+  TopoDS_Wire W = TopoDS::Wire(WW.Oriented(TopAbs_FORWARD));
+  BRepTools_WireExplorer wexp(W, F);
+  for (wexp.Init(W, F), iEdge = 0; wexp.More(); wexp.Next(), iEdge++)
+  {
+    const TopoDS_Edge & E = wexp.Current();
+
+    // --- IDNodes of first and last Vertex
+
+    TopoDS_Vertex VFirst, VLast;
+    TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
+
+    ASSERT(!VFirst.IsNull());
+    SMDS_NodeIteratorPtr lid=
+      aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes();
+    if ( !lid->more() ) {
+      MESSAGE (" NO NODE BUILT ON VERTEX ");
+      return false;
+    }
+    const SMDS_MeshNode* idFirst = lid->next();
+
+    ASSERT(!VLast.IsNull());
+    lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes();
+    if ( !lid->more() ) {
+      MESSAGE (" NO NODE BUILT ON VERTEX ");
+      return false;
+    }
+    const SMDS_MeshNode* idLast = lid->next();
+
+    // --- edge internal IDNodes (relies on good order storage, not checked)
+
+    int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
+
+    double f, l;
+    Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+
+    SMDS_NodeIteratorPtr ite= aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
+
+    //bool isForward = (E.Orientation() == TopAbs_FORWARD);
+    map<double, const SMDS_MeshNode*> params;
+
+    while(ite->more())
+    {
+      const SMDS_MeshNode * node = ite->next();
+      const SMDS_EdgePosition* epos =
+        static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+      double param = epos->GetUParameter();
+      params[param] = node;
+    }
+    if ( nbPoints != params.size())
+    {
+      MESSAGE( "BAD NODE ON EDGE POSITIONS" );
+      return false;
+    }
+
+    mFirst = m;
+
+    // --- load 2D values into MEFISTO structure,
+    //     add IDNodes in mefistoToDS map
+    if (E.Orientation() == TopAbs_FORWARD)
+    {
+      gp_Pnt2d p = C2d->Value(f).XY().Multiplied( scale );       // first point = Vertex Forward
+      if ( fixCommonVertexUV( p, VFirst, W, myOuterWire, F, VWMap, aMesh ))
+        myNodesOnCommonV.push_back( idFirst );
+      uvslf[m].x = p.X();
+      uvslf[m].y = p.Y();
+      mefistoToDS[m + 1] = idFirst;
+      //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
+      //MESSAGE("__ f "<<f<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
+      m++;
+      map<double, const SMDS_MeshNode*>::iterator itp = params.begin();
+      for (int i = 1; i <= nbPoints; i++)       // nbPoints internal
+      {
+        double param = (*itp).first;
+        gp_Pnt2d p = C2d->Value(param).XY().Multiplied( scale );
+        uvslf[m].x = p.X();
+        uvslf[m].y = p.Y();
+        mefistoToDS[m + 1] = (*itp).second;
+        //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
+        //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
+        m++;
+        itp++;
+      }
+    }
+    else
+    {
+      gp_Pnt2d p = C2d->Value(l).XY().Multiplied( scale );       // last point = Vertex Reversed
+      if ( fixCommonVertexUV( p, VLast, W, myOuterWire, F, VWMap, aMesh ))
+        myNodesOnCommonV.push_back( idLast );
+      uvslf[m].x = p.X();
+      uvslf[m].y = p.Y();
+      mefistoToDS[m + 1] = idLast;
+      //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
+      //MESSAGE("__ l "<<l<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
+      m++;
+      map<double, const SMDS_MeshNode*>::reverse_iterator itp = params.rbegin();
+      for (int i = nbPoints; i >= 1; i--)
+      {
+        double param = (*itp).first;
+        gp_Pnt2d p = C2d->Value(param).XY().Multiplied( scale );
+        uvslf[m].x = p.X();
+        uvslf[m].y = p.Y();
+        mefistoToDS[m + 1] = (*itp).second;
+        //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
+        //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
+        m++;
+        itp++;
+      }
+    }
+    // prevent failure on overlapped adjacent links
+    if ( iEdge > 0 )
+      fixOverlappedLinkUV (uvslf[ mFirst - 1],
+                           uvslf[ mFirst ],
+                           uvslf[ mFirst + 1 ]);
+    
+  } // for  wexp
+
+  fixOverlappedLinkUV (uvslf[ m - 1],
+                       uvslf[ mInit ],
+                       uvslf[ mInit + 1 ]);
+
+  return true;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh & aMesh,
+       const TopoDS_Face & aFace, double &scalex, double &scaley)
+{
+  //MESSAGE("StdMeshers_MEFISTO_2D::ComputeScaleOnFace");
+  TopoDS_Face F = TopoDS::Face(aFace.Oriented(TopAbs_FORWARD));
+  TopoDS_Wire W = BRepTools::OuterWire(F);
+
+  double xmin = 1.e300;         // min & max of face 2D parametric coord.
+  double xmax = -1.e300;
+  double ymin = 1.e300;
+  double ymax = -1.e300;
+  int nbp = 23;
+  scalex = 1;
+  scaley = 1;
+
+  TopExp_Explorer wexp(W, TopAbs_EDGE);
+  for ( ; wexp.More(); wexp.Next())
+  {
+    const TopoDS_Edge & E = TopoDS::Edge( wexp.Current() );
+    double f, l;
+    Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+    if ( C2d.IsNull() ) continue;
+    double du = (l - f) / double (nbp);
+    for (int i = 0; i <= nbp; i++)
+    {
+      double param = f + double (i) * du;
+      gp_Pnt2d p = C2d->Value(param);
+      if (p.X() < xmin)
+        xmin = p.X();
+      if (p.X() > xmax)
+        xmax = p.X();
+      if (p.Y() < ymin)
+        ymin = p.Y();
+      if (p.Y() > ymax)
+        ymax = p.Y();
+      //    MESSAGE(" "<< f<<" "<<l<<" "<<param<<" "<<xmin<<" "<<xmax<<" "<<ymin<<" "<<ymax);
+    }
+  }
+  //   SCRUTE(xmin);
+  //   SCRUTE(xmax);
+  //   SCRUTE(ymin);
+  //   SCRUTE(ymax);
+  double xmoy = (xmax + xmin) / 2.;
+  double ymoy = (ymax + ymin) / 2.;
+  double xsize = xmax - xmin;
+  double ysize = ymax - ymin;
+
+  Handle(Geom_Surface) S = BRep_Tool::Surface(F);       // 3D surface
+
+  double length_x = 0;
+  double length_y = 0;
+  gp_Pnt PX0 = S->Value(xmin, ymoy);
+  gp_Pnt PY0 = S->Value(xmoy, ymin);
+  double dx = xsize / double (nbp);
+  double dy = ysize / double (nbp);
+  for (int i = 1; i <= nbp; i++)
+  {
+    double x = xmin + double (i) * dx;
+    gp_Pnt PX = S->Value(x, ymoy);
+    double y = ymin + double (i) * dy;
+    gp_Pnt PY = S->Value(xmoy, y);
+    length_x += PX.Distance(PX0);
+    length_y += PY.Distance(PY0);
+    PX0 = PX;
+    PY0 = PY;
+  }
+  scalex = length_x / xsize;
+  scaley = length_y / ysize;
+//   SCRUTE(xsize);
+//   SCRUTE(ysize);
+  double xyratio = xsize*scalex/(ysize*scaley);
+  const double maxratio = 1.e2;
+  //SCRUTE(xyratio);
+  if (xyratio > maxratio) {
+    SCRUTE( scaley );
+    scaley *= xyratio / maxratio;
+    SCRUTE( scaley );
+  }
+  else if (xyratio < 1./maxratio) {
+    SCRUTE( scalex );
+    scalex *= 1 / xyratio / maxratio;
+    SCRUTE( scalex );
+  }
+  ASSERT(scalex);
+  ASSERT(scaley);
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+void StdMeshers_MEFISTO_2D::StoreResult(SMESH_Mesh & aMesh,
+                                        Z nbst, R2 * uvst, Z nbt, Z * nust,
+                                        const TopoDS_Face & F, bool faceIsForward,
+                                        map<int, const SMDS_MeshNode*>&mefistoToDS,
+                                        double scalex, double scaley)
+{
+  SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+  int faceID = meshDS->ShapeToIndex( F );
+
+  Z n, m;
+  Handle(Geom_Surface) S = BRep_Tool::Surface(F);
+
+  for (n = 0; n < nbst; n++)
+  {
+    if (mefistoToDS.find(n + 1) == mefistoToDS.end())
+    {
+      double u = uvst[n][0] / scalex;
+      double v = uvst[n][1] / scaley;
+      gp_Pnt P = S->Value(u, v);
+
+      SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
+      meshDS->SetNodeOnFace(node, faceID, u, v);
+
+      //MESSAGE(P.X()<<" "<<P.Y()<<" "<<P.Z());
+      mefistoToDS[n + 1] = node;
+      //MESSAGE("NEW: "<<n<<" "<<mefistoToDS[n+1]);
+    }
+  }
+
+  m = 0;
+  //int mt = 0;
+
+  //SCRUTE(faceIsForward);
+  for (n = 1; n <= nbt; n++)
+  {
+    int inode1 = nust[m++];
+    int inode2 = nust[m++];
+    int inode3 = nust[m++];
+
+    const SMDS_MeshNode *n1, *n2, *n3;
+    n1 = mefistoToDS[inode1];
+    n2 = mefistoToDS[inode2];
+    n3 = mefistoToDS[inode3];
+    //MESSAGE("-- "<<inode1<<" "<<inode2<<" "<<inode3);
+
+    // triangle points must be in trigonometric order if face is Forward
+    // else they must be put clockwise
+
+    bool triangleIsWellOriented = faceIsForward;
+
+    SMDS_MeshElement * elt;
+    if (triangleIsWellOriented)
+      elt = meshDS->AddFace(n1, n2, n3);
+    else
+      elt = meshDS->AddFace(n1, n3, n2);
+
+    meshDS->SetMeshElementOnShape(elt, faceID);
+    m++;
+  }
+
+  // remove bad elements build on vertices shared by wires
+
+  list<const SMDS_MeshNode*>::iterator itN = myNodesOnCommonV.begin();
+  for ( ; itN != myNodesOnCommonV.end(); itN++ )
+  {
+    const SMDS_MeshNode* node = *itN;
+    SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
+    while ( invElemIt->more() )
+    {
+      const SMDS_MeshElement* elem = invElemIt->next();
+      SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+      int nbSame = 0;
+      while ( itN->more() )
+        if ( itN->next() == node)
+          nbSame++;
+      if (nbSame > 1) {
+        MESSAGE( "RM bad element " << elem->GetID());
+        meshDS->RemoveElement( elem );
+      }
+    }
+  }
+
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh,
+       const TopoDS_Shape & aShape)
+{
+       //MESSAGE("StdMeshers_MEFISTO_2D::ComputeEdgeElementLength");
+       // **** a mettre dans SMESH_2D_Algo ?
+
+       const TopoDS_Face & FF = TopoDS::Face(aShape);
+       //bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
+       TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
+
+       double meanElementLength = 100;
+       double wireLength = 0;
+       int wireElementsNumber = 0;
+       for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
+       {
+               const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
+               for (TopExp_Explorer expe(W, TopAbs_EDGE); expe.More(); expe.Next())
+               {
+                       const TopoDS_Edge & E = TopoDS::Edge(expe.Current());
+                       int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
+                       double length = EdgeLength(E);
+                       wireLength += length;
+                       wireElementsNumber += nb;
+               }
+       }
+       if (wireElementsNumber)
+               meanElementLength = wireLength / wireElementsNumber;
+       //SCRUTE(meanElementLength);
+       return meanElementLength;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+ostream & StdMeshers_MEFISTO_2D::SaveTo(ostream & save)
+{
+  return save;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+istream & StdMeshers_MEFISTO_2D::LoadFrom(istream & load)
+{
+  return load;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+ostream & operator <<(ostream & save, StdMeshers_MEFISTO_2D & hyp)
+{
+  return hyp.SaveTo( save );
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+istream & operator >>(istream & load, StdMeshers_MEFISTO_2D & hyp)
+{
+  return hyp.LoadFrom( load );
+}
diff --git a/src/StdMeshers/StdMeshers_Penta_3D.cxx b/src/StdMeshers/StdMeshers_Penta_3D.cxx
new file mode 100644 (file)
index 0000000..ad6ebc8
--- /dev/null
@@ -0,0 +1,1582 @@
+//  SMESH StdMeshers_Penta_3D implementaion of SMESH idl descriptions
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : StdMeshers_Penta_3D.cxx
+//  Module : SMESH
+
+#include "StdMeshers_Penta_3D.hxx"
+
+#include "utilities.h"
+#include "Utils_ExceptHandlers.hxx"
+
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_VolumeOfNodes.hxx"
+#include "SMDS_VolumeTool.hxx"
+#include "SMESHDS_SubMesh.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_subMesh.hxx"
+#include "SMESH_MeshEditor.hxx"
+
+#include <BRep_Tool.hxx>
+#include <TopAbs_ShapeEnum.hxx>
+#include <TopExp.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Shell.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <gp_Pnt.hxx>
+
+#include <stdio.h>
+#include <algorithm>
+
+using namespace std;
+
+typedef map < int, int, less<int> >::iterator   \
+  StdMeshers_IteratorOfDataMapOfIntegerInteger;
+
+//=======================================================================
+//function : StdMeshers_Penta_3D
+//purpose  : 
+//=======================================================================
+StdMeshers_Penta_3D::StdMeshers_Penta_3D()
+: myErrorStatus(1)
+{
+  myTol3D=0.1;
+  myWallNodesMaps.resize( SMESH_Block::NbFaces() );
+  myShapeXYZ.resize( SMESH_Block::NbSubShapes() );
+}
+//=======================================================================
+//function : Compute
+//purpose  : 
+//=======================================================================
+bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh, 
+                                 const TopoDS_Shape& aShape)
+{
+  MESSAGE("StdMeshers_Penta_3D::Compute()");
+  //
+  myErrorStatus=0;
+  //
+  bool bOK=false;
+  //
+  myShape=aShape;
+  SetMesh(aMesh);
+  //
+  CheckData();
+  if (myErrorStatus){
+    return bOK;
+  }
+  //
+  MakeBlock();
+    if (myErrorStatus){
+    return bOK;
+  }
+  //
+  MakeNodes();
+  if (myErrorStatus){
+    return bOK;
+  }
+  //
+  MakeConnectingMap();
+  //
+  ClearMeshOnFxy1();
+  if (myErrorStatus) {
+    return bOK;
+  }
+  //
+  MakeMeshOnFxy1();
+  if (myErrorStatus) {
+    return bOK;
+  }
+  //
+  MakeVolumeMesh();
+  //
+  return !bOK;
+}
+//=======================================================================
+//function : MakeNodes
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::MakeNodes()
+{
+  myErrorStatus=0;
+  //
+  const int aNbSIDs=9;
+  int i, j, k, ij, iNbN, aNodeID, aSize, iErr;
+  double aX, aY, aZ;
+  SMESH_Block::TShapeID aSID, aSIDs[aNbSIDs]={
+    SMESH_Block::ID_V000, SMESH_Block::ID_V100, 
+    SMESH_Block::ID_V110, SMESH_Block::ID_V010,
+    SMESH_Block::ID_Ex00, SMESH_Block::ID_E1y0, 
+    SMESH_Block::ID_Ex10, SMESH_Block::ID_E0y0,
+    SMESH_Block::ID_Fxy0
+  }; 
+  //
+  SMESH_Mesh* pMesh=GetMesh();
+  //
+  // 1. Define the sizes of mesh
+  //
+  // 1.1 Horizontal size
+  myJSize=0;
+  for (i=0; i<aNbSIDs; ++i) {
+    const TopoDS_Shape& aS=myBlock.Shape(aSIDs[i]);
+    SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aS);
+    ASSERT(aSubMesh);
+    SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS();
+    iNbN=aSM->NbNodes();
+    myJSize+=iNbN;
+  }
+  //printf("***  Horizontal: number of nodes summary=%d\n", myJSize);
+  //
+  // 1.2 Vertical size
+  myISize=2;
+  {
+    const TopoDS_Shape& aS=myBlock.Shape(SMESH_Block::ID_E00z);
+    SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aS);
+    ASSERT(aSubMesh);
+    SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS();
+    iNbN=aSM->NbNodes();
+    myISize+=iNbN;
+  }
+  //printf("***  Vertical: number of nodes on edges and vertices=%d\n", myISize);
+  //
+  aSize=myISize*myJSize;
+  myTNodes.resize(aSize);
+  //
+  StdMeshers_TNode aTNode;
+  gp_XYZ aCoords;
+  gp_Pnt aP3D;
+  //
+  // 2. Fill the repers on base face (Z=0)
+  i=0; j=0;
+  // vertices
+  for (k=0; k<aNbSIDs; ++k) {
+    aSID=aSIDs[k];
+    const TopoDS_Shape& aS=myBlock.Shape(aSID);
+    SMDS_NodeIteratorPtr ite =pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes();
+    while(ite->more()) {
+      const SMDS_MeshNode* aNode = ite->next();
+      aNodeID=aNode->GetID();
+      //
+      aTNode.SetNode(aNode);
+      aTNode.SetShapeSupportID(aSID);
+      aTNode.SetBaseNodeID(aNodeID);
+      //
+      if ( SMESH_Block::IsEdgeID (aSID))
+      {
+        const SMDS_EdgePosition* epos =
+          static_cast<const SMDS_EdgePosition*>(aNode->GetPosition().get());
+        myBlock.ComputeParameters( epos->GetUParameter(), aS, aCoords );
+      }
+      else {
+        aX=aNode->X();
+        aY=aNode->Y();
+        aZ=aNode->Z();
+        aP3D.SetCoord(aX, aY, aZ);
+        myBlock.ComputeParameters(aP3D, aS, aCoords);
+      }
+      iErr=myBlock.ErrorStatus();
+      if (iErr) {
+        MESSAGE("StdMeshers_Penta_3D::MakeNodes()," <<
+                "SMESHBlock: ComputeParameters operation failed");
+        myErrorStatus=101; // SMESHBlock: ComputeParameters operation failed
+        return;
+      }
+      aTNode.SetNormCoord(aCoords);
+      ij=i*myJSize+j;
+      myTNodes[ij]=aTNode;
+      ++j;
+    }
+  }
+  /*
+  //DEB
+  {
+    int iShapeSupportID, iBaseNodeID;
+    //
+    //printf("\n\n*** Base Face\n");
+    i=0;
+    for (j=0; j<myJSize; ++j) {
+      ij=i*myJSize+j;
+      const StdMeshers_TNode& aTNode=myTNodes[ij];
+      iShapeSupportID=aTNode.ShapeSupportID();
+      iBaseNodeID=aTNode.BaseNodeID();
+      const gp_XYZ& aXYZ=aTNode.NormCoord();
+      printf("*** j:%d bID#%d iSS:%d { %lf %lf %lf }\n",
+            j,  iBaseNodeID, iShapeSupportID, aXYZ.X(),  aXYZ.Y(), aXYZ.Z());
+    }
+  }
+  */
+  //DEB
+  //return; //zz
+  //
+  // 3. Finding of Z-layers
+//   vector<double> aZL(myISize);
+//   vector<double>::iterator aItZL1, aItZL2 ;
+//   //
+//   const TopoDS_Shape& aE00z=myBlock.Shape(SMESH_Block::ID_E00z);
+//   SMDS_NodeIteratorPtr aItaE00z =
+//     pMesh->GetSubMeshContaining(aE00z)->GetSubMeshDS()->GetNodes();
+//   //
+//   aZL[0]=0.;
+//   i=1;
+//   while (aItaE00z->more()) {
+//     const SMDS_MeshNode* aNode=aItaE00z->next();
+//     const SMDS_EdgePosition* epos =
+//       static_cast<const SMDS_EdgePosition*>(aNode->GetPosition().get());
+//     myBlock.ComputeParameters( epos->GetUParameter(), aE00z, aCoords );
+//     iErr=myBlock.ErrorStatus();
+//     if (iErr) {
+//       MESSAGE("StdMeshers_Penta_3D::MakeNodes()," <<
+//               "SMESHBlock: ComputeParameters operation failed");
+//       myErrorStatus=101; // SMESHBlock: ComputeParameters operation failed
+//       return;
+//     }
+//     aZL[i]=aCoords.Z();
+//     ++i;
+//   }
+//   aZL[i]=1.;
+//   //
+//   aItZL1=aZL.begin();
+//   aItZL2=aZL.end();
+//   //
+//   // Sorting the layers
+//   sort(aItZL1, aItZL2);
+  //DEB
+  /*
+  printf("** \n\n Layers begin\n");
+  for(i=0, aItZL=aItZL1; aItZL!=aItZL2; ++aItZL, ++i) {
+    printf(" #%d : %lf\n", i, *aItZL);
+  } 
+  printf("** Layers end\n");
+  */
+  //DEB
+  //
+  //
+
+  // 3.1 Fill maps of wall nodes
+  SMESH_Block::TShapeID wallFaceID[4] = {
+    SMESH_Block::ID_Fx0z, SMESH_Block::ID_Fx1z,
+    SMESH_Block::ID_F0yz, SMESH_Block::ID_F1yz
+    };
+  SMESH_Block::TShapeID baseEdgeID[4] = {
+    SMESH_Block::ID_Ex00, SMESH_Block::ID_Ex10,
+    SMESH_Block::ID_E0y0, SMESH_Block::ID_E1y0
+    };
+  for ( i = 0; i < 4; ++i ) {
+    int fIndex = SMESH_Block::ShapeIndex( wallFaceID[ i ]);
+    bool ok = LoadIJNodes (myWallNodesMaps[ fIndex ],
+                           TopoDS::Face( myBlock.Shape( wallFaceID[ i ] )),
+                           TopoDS::Edge( myBlock.Shape( baseEdgeID[ i ] )),
+                           pMesh->GetMeshDS());
+    if ( !ok ) {
+      myErrorStatus = i + 1;
+      MESSAGE(" Cant LoadIJNodes() from a wall face " << myErrorStatus );
+      return;
+    }
+  }
+
+  // 3.2 find node columns for vertical edges and edge IDs
+  vector<const SMDS_MeshNode*> * verticEdgeNodes[ 4 ];
+  SMESH_Block::TShapeID          verticEdgeID   [ 4 ];
+  for ( i = 0; i < 4; ++i ) { // 4 first base nodes are nodes on vertices
+    // edge ID
+    SMESH_Block::TShapeID eID, vID = aSIDs[ i ];
+    ShapeSupportID(false, vID, eID);
+    verticEdgeID[ i ] = eID;
+    // column nodes
+    StdMeshers_TNode& aTNode = myTNodes[ i ];
+    verticEdgeNodes[ i ] = 0;
+    for ( j = 0; j < 4; ++j ) { // loop on 4 wall faces
+      int fIndex = SMESH_Block::ShapeIndex( wallFaceID[ j ]);
+      StdMeshers_IJNodeMap & ijNodes= myWallNodesMaps[ fIndex ];
+      if ( ijNodes.begin()->second[0] == aTNode.Node() )
+        verticEdgeNodes[ i ] = & ijNodes.begin()->second;
+      else if ( ijNodes.rbegin()->second[0] == aTNode.Node() )
+        verticEdgeNodes[ i ] = & ijNodes.rbegin()->second;
+      if ( verticEdgeNodes[ i ] )
+        break;
+    }
+  }
+
+  // 3.3 set XYZ of vertices, and initialize of the rest
+  SMESHDS_Mesh* aMesh = GetMesh()->GetMeshDS();
+  for ( int id = SMESH_Block::ID_V000; id < SMESH_Block::ID_Shell; ++id )
+  {
+    if ( SMESH_Block::IsVertexID( id )) {
+      TopoDS_Shape V = myBlock.Shape( id );
+      SMESHDS_SubMesh* sm = aMesh->MeshElements( V );
+      const SMDS_MeshNode* n = sm->GetNodes()->next();
+      myShapeXYZ[ id ].SetCoord( n->X(), n->Y(), n->Z() );
+    }
+    else
+      myShapeXYZ[ id ].SetCoord( 0., 0., 0. );
+  }
+
+
+  // 4. Fill the rest repers
+  bool bIsUpperLayer;
+  int iBNID;
+  SMESH_Block::TShapeID aSSID, aBNSSID;
+  StdMeshers_TNode aTN;
+  //
+  for (j=0; j<myJSize; ++j)
+  {
+    // base node info
+    const StdMeshers_TNode& aBN=myTNodes[j];
+    aBNSSID=(SMESH_Block::TShapeID)aBN.ShapeSupportID();
+    iBNID=aBN.BaseNodeID();
+    const gp_XYZ& aBNXYZ=aBN.NormCoord();
+    bool createNode = ( aBNSSID == SMESH_Block::ID_Fxy0 );
+    //
+    // set XYZ on horizontal edges and get node columns of faces:
+    // 2 columns for each face, between which a base node is located
+    vector<const SMDS_MeshNode*>* nColumns[8];
+    double ratio[4]; // base node position between columns [0.-1.]
+    if ( createNode )
+      for ( k = 0; k < 4; ++k )
+        ratio[ k ] = SetHorizEdgeXYZ (aBNXYZ, wallFaceID[ k ],
+                                      nColumns[k*2], nColumns[k*2+1]);
+    //
+    // XYZ on the bottom and top faces
+    const SMDS_MeshNode* n = aBN.Node();
+    myShapeXYZ[ SMESH_Block::ID_Fxy0 ].SetCoord( n->X(), n->Y(), n->Z() );
+    myShapeXYZ[ SMESH_Block::ID_Fxy1 ].SetCoord( 0., 0., 0. );
+    //
+    // first create or find a top node, then the rest ones in a column
+    for (i=myISize-1; i>0; --i)
+    {
+      if ( createNode ) {
+        // set XYZ on vertical edges and faces
+        for ( k = 0; k < 4; ++k ) {
+          const SMDS_MeshNode* n = (*verticEdgeNodes[ k ]) [ i ];
+          myShapeXYZ[ verticEdgeID[ k ] ].SetCoord( n->X(), n->Y(), n->Z() );
+          //
+          n = (*nColumns[k*2]) [ i ];
+          gp_XYZ xyz( n->X(), n->Y(), n->Z() );
+          myShapeXYZ[ wallFaceID[ k ]] = ( 1. - ratio[ k ]) * xyz;
+          n = (*nColumns[k*2+1]) [ i ];
+          xyz.SetCoord( n->X(), n->Y(), n->Z() );
+          myShapeXYZ[ wallFaceID[ k ]] += ratio[ k ] * xyz;
+        }
+      }
+      // fill current node info
+      //   -index in aTNodes
+      ij=i*myJSize+j; 
+      //   -normalized coordinates  
+      aX=aBNXYZ.X();  
+      aY=aBNXYZ.Y();
+      //aZ=aZL[i];
+      aZ=(double)i/(double)(myISize-1);
+      aCoords.SetCoord(aX, aY, aZ);
+      //
+      //   suporting shape ID
+      bIsUpperLayer=(i==(myISize-1));
+      ShapeSupportID(bIsUpperLayer, aBNSSID, aSSID);
+      if (myErrorStatus) {
+        MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
+       return;
+      }
+      //
+      aTN.SetShapeSupportID(aSSID);
+      aTN.SetNormCoord(aCoords);
+      aTN.SetBaseNodeID(iBNID);
+      //
+      if (aSSID!=SMESH_Block::ID_NONE){
+       // try to find the node
+       const TopoDS_Shape& aS=myBlock.Shape((int)aSSID);
+       FindNodeOnShape(aS, aCoords, i, aTN);
+      }
+      else{
+       // create node and get it id
+       CreateNode (bIsUpperLayer, aCoords, aTN);
+        //
+        if ( bIsUpperLayer ) {
+          const SMDS_MeshNode* n = aTN.Node();
+          myShapeXYZ[ SMESH_Block::ID_Fxy1 ].SetCoord( n->X(), n->Y(), n->Z() );
+        }
+      }
+      if (myErrorStatus) {
+        MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
+       return;
+      }
+      //
+      myTNodes[ij]=aTN;
+    }
+  }
+  //DEB
+  /*
+  {
+    int iSSID, iBNID, aID;
+    //
+    for (i=0; i<myISize; ++i) {
+      printf(" Layer# %d\n", i);
+      for (j=0; j<myJSize; ++j) {
+       ij=i*myJSize+j; 
+       const StdMeshers_TNode& aTN=myTNodes[ij];
+       //const StdMeshers_TNode& aTN=aTNodes[ij];
+       const gp_XYZ& aXYZ=aTN.NormCoord();
+       iSSID=aTN.ShapeSupportID();
+       iBNID=aTN.BaseNodeID();
+       //
+       const SMDS_MeshNode* aNode=aTN.Node();
+       aID=aNode->GetID(); 
+       aX=aNode->X();
+       aY=aNode->Y();
+       aZ=aNode->Z();
+       printf("*** j:%d BNID#%d iSSID:%d ID:%d { %lf %lf %lf },  { %lf %lf %lf }\n",
+              j,  iBNID, iSSID, aID, aXYZ.X(),  aXYZ.Y(), aXYZ.Z(), aX, aY, aZ);
+      }
+    }
+  }
+  */
+  //DEB t
+}
+//=======================================================================
+//function : FindNodeOnShape
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS,
+                                         const gp_XYZ&       aParams,
+                                          const int           z,
+                                         StdMeshers_TNode&   aTN)
+{
+  myErrorStatus=0;
+  //
+  double aX, aY, aZ, aD, aTol2, minD;
+  gp_Pnt aP1, aP2;
+  //
+  SMESH_Mesh* pMesh=GetMesh();
+  aTol2=myTol3D*myTol3D;
+  minD = 1.e100;
+  SMDS_MeshNode* pNode=NULL;
+  //
+  if ( aS.ShapeType() == TopAbs_FACE ||
+       aS.ShapeType() == TopAbs_EDGE )
+  {
+    // find a face ID to which aTN belongs to
+    int faceID;
+    if ( aS.ShapeType() == TopAbs_FACE )
+      faceID = myBlock.ShapeID( aS );
+    else { // edge maybe vertical or top horizontal
+      gp_XYZ aCoord = aParams;
+      if ( aCoord.Z() == 1. )
+        aCoord.SetZ( 0.5 ); // move from top down
+      else
+        aCoord.SetX( 0.5 ); // move along X
+      faceID = SMESH_Block::GetShapeIDByParams( aCoord );
+    }
+    ASSERT( SMESH_Block::IsFaceID( faceID ));
+    int fIndex = SMESH_Block::ShapeIndex( faceID );
+    StdMeshers_IJNodeMap & ijNodes= myWallNodesMaps[ fIndex ];
+    // look for a base node in ijNodes
+    const SMDS_MeshNode* baseNode = pMesh->GetMeshDS()->FindNode( aTN.BaseNodeID() );
+    StdMeshers_IJNodeMap::const_iterator par_nVec = ijNodes.begin();
+    for ( ; par_nVec != ijNodes.end(); par_nVec++ )
+      if ( par_nVec->second[ 0 ] == baseNode ) {
+        pNode=(SMDS_MeshNode*)par_nVec->second.at( z );
+        aTN.SetNode(pNode);
+        return;
+      }
+  }
+  //
+  myBlock.Point(aParams, aS, aP1);
+  //
+  SMDS_NodeIteratorPtr ite=
+    pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes();
+  while(ite->more()) {
+    const SMDS_MeshNode* aNode = ite->next();
+    aX=aNode->X();
+    aY=aNode->Y();
+    aZ=aNode->Z();
+    aP2.SetCoord(aX, aY, aZ);
+    aD=(double)aP1.SquareDistance(aP2);
+    //printf("** D=%lf ", aD, aTol2);
+    if (aD < minD) {
+      pNode=(SMDS_MeshNode*)aNode;
+      aTN.SetNode(pNode);
+      minD = aD;
+      //printf(" Ok\n");
+      if (aD<aTol2)
+        return; 
+    }
+  }
+  //
+  //printf(" KO\n");
+  //aTN.SetNode(pNode);
+  //MESSAGE("StdMeshers_Penta_3D::FindNodeOnShape(), can not find the node");
+  //myErrorStatus=11; // can not find the node;
+}
+
+//=======================================================================
+//function : SetHorizEdgeXYZ
+//purpose  : 
+//=======================================================================
+
+double StdMeshers_Penta_3D::SetHorizEdgeXYZ(const gp_XYZ&                  aBaseNodeParams,
+                                            const int                      aFaceID,
+                                            vector<const SMDS_MeshNode*>*& aCol1,
+                                            vector<const SMDS_MeshNode*>*& aCol2)
+{
+  // find base and top edges of the face
+  vector< int > edgeVec; // 0-base, 1-top
+  SMESH_Block::GetFaceEdgesIDs( aFaceID, edgeVec );
+  //
+  int coord = SMESH_Block::GetCoordIndOnEdge( edgeVec[ 0 ] );
+  double param = aBaseNodeParams.Coord( coord );
+  if ( !myBlock.IsForwadEdge( edgeVec[ 0 ] ))
+    param = 1. - param;
+  //
+  // look for columns around param
+  StdMeshers_IJNodeMap & ijNodes =
+    myWallNodesMaps[ SMESH_Block::ShapeIndex( aFaceID )];
+  StdMeshers_IJNodeMap::iterator par_nVec_1 = ijNodes.begin();
+  while ( par_nVec_1->first < param )
+    par_nVec_1++;
+  StdMeshers_IJNodeMap::iterator par_nVec_2 = par_nVec_1;
+  //
+  double r = 0;
+  if ( par_nVec_1 != ijNodes.begin() ) {
+    par_nVec_1--;
+    r = ( param - par_nVec_1->first ) / ( par_nVec_2->first - par_nVec_1->first );
+  }
+  aCol1 = & par_nVec_1->second;
+  aCol2 = & par_nVec_2->second;
+
+  // base edge
+  const SMDS_MeshNode* n1 = aCol1->front();
+  const SMDS_MeshNode* n2 = aCol2->front();
+  gp_XYZ xyz1( n1->X(), n1->Y(), n1->Z() ), xyz2( n2->X(), n2->Y(), n2->Z() );
+  myShapeXYZ[ edgeVec[ 0 ] ] = ( 1. - r ) * xyz1 + r * xyz2;
+
+  // top edge
+  n1 = aCol1->back();
+  n2 = aCol2->back();
+  xyz1.SetCoord( n1->X(), n1->Y(), n1->Z() );
+  xyz2.SetCoord( n2->X(), n2->Y(), n2->Z() );
+  myShapeXYZ[ edgeVec[ 1 ] ] = ( 1. - r ) * xyz1 + r * xyz2;
+
+  return r;
+}
+
+//=======================================================================
+//function : MakeVolumeMesh
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::MakeVolumeMesh()
+{
+  myErrorStatus=0;
+  //
+  int i, j, ij, ik, i1, i2, aSSID; 
+  //
+  SMESH_Mesh*   pMesh =GetMesh();
+  SMESHDS_Mesh* meshDS=pMesh->GetMeshDS();
+  //
+  int shapeID = meshDS->ShapeToIndex( myShape );
+  //
+  // 1. Set Node In Volume
+  ik=myISize-1;
+  for (i=1; i<ik; ++i){
+    for (j=0; j<myJSize; ++j){
+      ij=i*myJSize+j;
+      const StdMeshers_TNode& aTN=myTNodes[ij];
+      aSSID=aTN.ShapeSupportID();
+      if (aSSID==SMESH_Block::ID_NONE) {
+       SMDS_MeshNode* aNode=(SMDS_MeshNode*)aTN.Node();
+       meshDS->SetNodeInVolume(aNode, shapeID);
+      }
+    }
+  }
+  //
+  // 2. Make pentahedrons
+  int aID0, k , aJ[3];
+  vector<const SMDS_MeshNode*> aN;
+  //
+  SMDS_ElemIteratorPtr itf, aItNodes;
+  //
+  const TopoDS_Face& aFxy0=
+    TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy0));
+  SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0);
+  SMESHDS_SubMesh *aSM0=aSubMesh0->GetSubMeshDS();
+  //
+  itf=aSM0->GetElements();
+  while(itf->more()) {
+    const SMDS_MeshElement* pE0=itf->next();
+    //
+    int nbFaceNodes = pE0->NbNodes();
+    if ( aN.size() < nbFaceNodes * 2 )
+      aN.resize( nbFaceNodes * 2 );
+    //
+    k=0;
+    aItNodes=pE0->nodesIterator();
+    while (aItNodes->more()) {
+      const SMDS_MeshElement* pNode=aItNodes->next();
+      aID0=pNode->GetID();
+      aJ[k]=GetIndexOnLayer(aID0);
+      if (myErrorStatus) {
+        MESSAGE("StdMeshers_Penta_3D::MakeVolumeMesh");
+       return;
+      }
+      //
+      ++k;
+    }
+    //
+    bool forward = true;
+    for (i=0; i<ik; ++i){
+      i1=i;
+      i2=i+1;
+      for(j=0; j<nbFaceNodes; ++j) {
+       ij=i1*myJSize+aJ[j];
+       const StdMeshers_TNode& aTN1=myTNodes[ij];
+       const SMDS_MeshNode* aN1=aTN1.Node();
+       aN[j]=aN1;
+       //
+       ij=i2*myJSize+aJ[j];
+       const StdMeshers_TNode& aTN2=myTNodes[ij];
+       const SMDS_MeshNode* aN2=aTN2.Node();
+       aN[j+nbFaceNodes]=aN2;
+      }
+      // check if volume orientation will be ok
+      if ( i == 0 ) {
+        SMDS_VolumeTool vTool;
+        switch ( nbFaceNodes ) {
+        case 3: {
+          SMDS_VolumeOfNodes tmpVol (aN[0], aN[1], aN[2],
+                                     aN[3], aN[4], aN[5]);
+          vTool.Set( &tmpVol );
+          break;
+        }
+        case 4: {
+          SMDS_VolumeOfNodes tmpVol(aN[0], aN[1], aN[2], aN[3],
+                                    aN[4], aN[5], aN[6], aN[7]);
+          vTool.Set( &tmpVol );
+          break;
+        }
+        default:
+          continue;
+        }
+        forward = vTool.IsForward();
+      }
+      // add volume
+      SMDS_MeshVolume* aV = 0;
+      switch ( nbFaceNodes ) {
+      case 3:
+        if ( forward )
+          aV = meshDS->AddVolume(aN[0], aN[1], aN[2],
+                                 aN[3], aN[4], aN[5]);
+        else
+          aV = meshDS->AddVolume(aN[0], aN[2], aN[1],
+                                 aN[3], aN[5], aN[4]);
+        break;
+      case 4:
+        if ( forward )
+          aV = meshDS->AddVolume(aN[0], aN[1], aN[2], aN[3],
+                                 aN[4], aN[5], aN[6], aN[7]);
+        else
+          aV = meshDS->AddVolume(aN[0], aN[3], aN[2], aN[1],
+                                 aN[4], aN[7], aN[6], aN[5]);
+        break;
+      default:
+        continue;
+      }
+      meshDS->SetMeshElementOnShape(aV, shapeID);
+    }
+  }
+}
+
+//=======================================================================
+//function : MakeMeshOnFxy1
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::MakeMeshOnFxy1()
+{
+  myErrorStatus=0;
+  //
+  int aID0, aJ, aLevel, ij, aNbNodes, k;
+  //
+  SMDS_NodeIteratorPtr itn;
+  SMDS_ElemIteratorPtr itf, aItNodes;
+  SMDSAbs_ElementType aElementType;
+  //
+  const TopoDS_Face& aFxy0=
+    TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy0));
+  const TopoDS_Face& aFxy1=
+    TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy1));
+  //
+  SMESH_Mesh* pMesh=GetMesh();
+  SMESHDS_Mesh * meshDS = pMesh->GetMeshDS();
+  //
+  SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0);
+  SMESHDS_SubMesh *aSM0=aSubMesh0->GetSubMeshDS();
+  //
+  // set nodes on aFxy1
+  aLevel=myISize-1;
+  itn=aSM0->GetNodes();
+  aNbNodes=aSM0->NbNodes();
+  //printf("** aNbNodes=%d\n", aNbNodes);
+  while(itn->more()) {
+    const SMDS_MeshNode* aN0=itn->next();
+    aID0=aN0->GetID();
+    aJ=GetIndexOnLayer(aID0);
+    if (myErrorStatus) {
+      MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() ");
+      return;
+    }
+    //
+    ij=aLevel*myJSize+aJ;
+    const StdMeshers_TNode& aTN1=myTNodes[ij];
+    SMDS_MeshNode* aN1=(SMDS_MeshNode*)aTN1.Node();
+    //
+    meshDS->SetNodeOnFace(aN1, aFxy1);
+  }
+  //
+  // set elements on aFxy1
+  vector<const SMDS_MeshNode*> aNodes1;
+  //
+  itf=aSM0->GetElements();
+  while(itf->more()) {
+    const SMDS_MeshElement * pE0=itf->next();
+    aElementType=pE0->GetType();
+    if (!aElementType==SMDSAbs_Face) {
+      continue;
+    }
+    aNbNodes=pE0->NbNodes();
+//     if (aNbNodes!=3) {
+//       continue;
+//     }
+    if ( aNodes1.size() < aNbNodes )
+      aNodes1.resize( aNbNodes );
+    //
+    k=aNbNodes-1; // reverse a face
+    aItNodes=pE0->nodesIterator();
+    while (aItNodes->more()) {
+      const SMDS_MeshElement* pNode=aItNodes->next();
+      aID0=pNode->GetID();
+      aJ=GetIndexOnLayer(aID0);
+      if (myErrorStatus) {
+        MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() ");
+       return;
+      }
+      //
+      ij=aLevel*myJSize+aJ;
+      const StdMeshers_TNode& aTN1=myTNodes[ij];
+      const SMDS_MeshNode* aN1=aTN1.Node();
+      aNodes1[k]=aN1;
+      --k;
+    }
+    SMDS_MeshFace * face = 0;
+    switch ( aNbNodes ) {
+    case 3:
+      face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]);
+      break;
+    case 4:
+      face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]);
+      break;
+    default:
+      continue;
+    }
+    meshDS->SetMeshElementOnShape(face, aFxy1);
+  }
+}
+//=======================================================================
+//function : ClearMeshOnFxy1
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::ClearMeshOnFxy1()
+{
+  myErrorStatus=0;
+  //
+  SMESH_subMesh* aSubMesh;
+  SMESH_Mesh* pMesh=GetMesh();
+  //
+  const TopoDS_Shape& aFxy1=myBlock.Shape(SMESH_Block::ID_Fxy1);
+  aSubMesh = pMesh->GetSubMeshContaining(aFxy1);
+  if (aSubMesh)
+    aSubMesh->ComputeStateEngine( SMESH_subMesh::CLEAN );
+}
+
+//=======================================================================
+//function : GetIndexOnLayer
+//purpose  : 
+//=======================================================================
+int StdMeshers_Penta_3D::GetIndexOnLayer(const int aID)
+{
+  myErrorStatus=0;
+  //
+  int j=-1;
+  StdMeshers_IteratorOfDataMapOfIntegerInteger aMapIt;
+  //
+  aMapIt=myConnectingMap.find(aID);
+  if (aMapIt==myConnectingMap.end()) {
+    myErrorStatus=200;
+    return j;
+  }
+  j=(*aMapIt).second;
+  return j;
+}
+//=======================================================================
+//function : MakeConnectingMap
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::MakeConnectingMap()
+{
+  int j, aBNID;
+  //
+  for (j=0; j<myJSize; ++j) {
+    const StdMeshers_TNode& aBN=myTNodes[j];
+    aBNID=aBN.BaseNodeID();
+    myConnectingMap[aBNID]=j;
+  }
+}
+//=======================================================================
+//function : CreateNode
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer,
+                                    const gp_XYZ& aParams,
+                                    StdMeshers_TNode& aTN)
+{
+  myErrorStatus=0;
+  //
+  // int iErr;
+  double aX, aY, aZ;
+  //
+  gp_Pnt aP;
+  //
+  SMDS_MeshNode* pNode=NULL; 
+  aTN.SetNode(pNode);  
+  //
+//   if (bIsUpperLayer) {
+//     // point on face Fxy1
+//     const TopoDS_Shape& aS=myBlock.Shape(SMESH_Block::ID_Fxy1);
+//     myBlock.Point(aParams, aS, aP);
+//   }
+//   else {
+//     // point inside solid
+//     myBlock.Point(aParams, aP);
+//   }
+  if (bIsUpperLayer)
+  {
+    double u = aParams.X(), v = aParams.Y();
+    double u1 = ( 1. - u ), v1 = ( 1. - v );
+    aP.ChangeCoord()  = myShapeXYZ[ SMESH_Block::ID_Ex01 ] * v1;
+    aP.ChangeCoord() += myShapeXYZ[ SMESH_Block::ID_Ex11 ] * v;
+    aP.ChangeCoord() += myShapeXYZ[ SMESH_Block::ID_E0y1 ] * u1;
+    aP.ChangeCoord() += myShapeXYZ[ SMESH_Block::ID_E1y1 ] * u;
+
+    aP.ChangeCoord() -= myShapeXYZ[ SMESH_Block::ID_V001 ] * u1 * v1;
+    aP.ChangeCoord() -= myShapeXYZ[ SMESH_Block::ID_V101 ] * u  * v1;
+    aP.ChangeCoord() -= myShapeXYZ[ SMESH_Block::ID_V011 ] * u1 * v;
+    aP.ChangeCoord() -= myShapeXYZ[ SMESH_Block::ID_V111 ] * u  * v;
+  }
+  else
+  {
+    SMESH_Block::ShellPoint( aParams, myShapeXYZ, aP.ChangeCoord() );
+  }
+  //
+//   iErr=myBlock.ErrorStatus();
+//   if (iErr) {
+//     myErrorStatus=12; // can not find the node point;
+//     return;
+//   }
+  //
+  aX=aP.X(); aY=aP.Y(); aZ=aP.Z(); 
+  //
+  SMESH_Mesh* pMesh=GetMesh();
+  SMESHDS_Mesh* pMeshDS=pMesh->GetMeshDS();
+  //
+  pNode = pMeshDS->AddNode(aX, aY, aZ);
+  aTN.SetNode(pNode);
+}
+//=======================================================================
+//function : ShapeSupportID
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::ShapeSupportID(const bool bIsUpperLayer,
+                                        const SMESH_Block::TShapeID aBNSSID,
+                                        SMESH_Block::TShapeID& aSSID)
+{
+  myErrorStatus=0;
+  //
+  switch (aBNSSID) {
+    case SMESH_Block::ID_V000:
+      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V001 : SMESH_Block::ID_E00z;
+      break;
+    case SMESH_Block::ID_V100:
+      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V101 : SMESH_Block::ID_E10z;
+      break; 
+    case SMESH_Block::ID_V110:
+      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V111 : SMESH_Block::ID_E11z;
+      break;
+    case SMESH_Block::ID_V010:
+      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V011 : SMESH_Block::ID_E01z;
+      break;
+    case SMESH_Block::ID_Ex00:
+      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_Ex01 : SMESH_Block::ID_Fx0z;
+      break;
+    case SMESH_Block::ID_Ex10:
+      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_Ex11 : SMESH_Block::ID_Fx1z;
+      break; 
+    case SMESH_Block::ID_E0y0:
+      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_E0y1 : SMESH_Block::ID_F0yz;
+      break; 
+    case SMESH_Block::ID_E1y0:
+      aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_E1y1 : SMESH_Block::ID_F1yz;
+      break; 
+    case SMESH_Block::ID_Fxy0:
+      aSSID=SMESH_Block::ID_NONE;//(bIsUpperLayer) ?  Shape_ID_Fxy1 : Shape_ID_NONE;
+      break;   
+    default:
+      aSSID=SMESH_Block::ID_NONE;
+      myErrorStatus=10; // Can not find supporting shape ID
+      break;
+  }
+  return;
+}
+//=======================================================================
+//function : MakeBlock
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::MakeBlock()
+{
+  myErrorStatus=0;
+  //
+  bool bFound;
+  int i, j, iNbEV, iNbE, iErr, iCnt, iNbNodes, iNbF;
+  //
+  TopoDS_Vertex aV000, aV001;
+  TopoDS_Shape aFTr;
+  TopTools_IndexedDataMapOfShapeListOfShape aMVES;
+  TopTools_IndexedMapOfShape aME ,aMEV, aM;
+  TopTools_ListIteratorOfListOfShape aIt;
+  //
+  TopExp::MapShapes(myShape, TopAbs_FACE, aM);
+  //
+  // 0. Find triangulated face aFTr
+  SMDSAbs_ElementType aElementType;
+  SMESH_Mesh* pMesh=GetMesh();
+  //
+  iCnt=0;
+  iNbF=aM.Extent();
+  for (i=1; i<=iNbF; ++i) {
+    const TopoDS_Shape& aF=aM(i);
+    SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aF);
+    ASSERT(aSubMesh);
+    SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS();
+    SMDS_ElemIteratorPtr itf=aSM->GetElements();
+    while(itf->more()) {
+      const SMDS_MeshElement * pElement=itf->next();
+      aElementType=pElement->GetType();
+      if (aElementType==SMDSAbs_Face) {
+       iNbNodes=pElement->NbNodes();
+       if (iNbNodes==3) {
+         aFTr=aF;
+         ++iCnt;
+         if (iCnt>1) {
+            MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
+           myErrorStatus=5; // more than one face has triangulation
+           return;
+         }
+         break; // next face
+       }
+      }
+    }
+  }
+  // 
+  // 1. Vetrices V00, V001;
+  //
+  TopExp::MapShapes(aFTr, TopAbs_EDGE, aME);
+  TopExp::MapShapesAndAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, aMVES);
+  //
+  // 1.1 Base vertex V000
+  iNbE=aME.Extent();
+  if (iNbE!=4){
+    MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
+    myErrorStatus=7; // too few edges are in base face aFTr 
+    return;
+  }
+  const TopoDS_Edge& aE1=TopoDS::Edge(aME(1));
+  aV000=TopExp::FirstVertex(aE1);
+  //
+  const TopTools_ListOfShape& aLE=aMVES.FindFromKey(aV000);
+  aIt.Initialize(aLE);
+  for (; aIt.More(); aIt.Next()) {
+    const TopoDS_Shape& aEx=aIt.Value();
+    aMEV.Add(aEx);
+  }
+  iNbEV=aMEV.Extent();
+  if (iNbEV!=3){
+    MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
+    myErrorStatus=7; // too few edges meet in base vertex 
+    return;
+  }
+  //
+  // 1.2 Vertex V001
+  bFound=false;
+  for (j=1; j<=iNbEV; ++j) {
+    const TopoDS_Shape& aEx=aMEV(j);
+    if (!aME.Contains(aEx)) {
+      TopoDS_Vertex aV[2];
+      //
+      const TopoDS_Edge& aE=TopoDS::Edge(aEx);
+      TopExp::Vertices(aE, aV[0], aV[1]);
+      for (i=0; i<2; ++i) {
+       if (!aV[i].IsSame(aV000)) {
+         aV001=aV[i];
+         bFound=!bFound;
+         break;
+       }
+      }
+    }
+  }
+  //
+  if (!bFound) {
+    MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
+    myErrorStatus=8; // can not find reper V001 
+    return;
+  }
+  //DEB
+  //gp_Pnt aP000, aP001;
+  //
+  //aP000=BRep_Tool::Pnt(TopoDS::Vertex(aV000));
+  //printf("*** aP000 { %lf, %lf, %lf }\n", aP000.X(), aP000.Y(), aP000.Z());
+  //aP001=BRep_Tool::Pnt(TopoDS::Vertex(aV001));
+  //printf("*** aP001 { %lf, %lf, %lf }\n", aP001.X(), aP001.Y(), aP001.Z());
+  //DEB
+  //
+  aME.Clear();
+  TopExp::MapShapes(myShape, TopAbs_SHELL, aME);
+  iNbE=aME.Extent();
+  if (iNbE!=1) {
+    MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
+    myErrorStatus=9; // number of shells in source shape !=1 
+    return;
+  }
+  //
+  // 2. Load Block
+  const TopoDS_Shell& aShell=TopoDS::Shell(aME(1));
+  myBlock.Load(aShell, aV000, aV001);
+  iErr=myBlock.ErrorStatus();
+  if (iErr) {
+    MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
+    myErrorStatus=100; // SMESHBlock: Load operation failed
+    return;
+  }
+}
+//=======================================================================
+//function : CheckData
+//purpose  : 
+//=======================================================================
+void StdMeshers_Penta_3D::CheckData()
+{
+  myErrorStatus=0;
+  //
+  int i, iNb;
+  int iNbEx[]={8, 12, 6};
+  //
+  TopAbs_ShapeEnum aST;
+  TopAbs_ShapeEnum aSTEx[]={
+    TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE
+  }; 
+  TopTools_IndexedMapOfShape aM;
+  //
+  if (myShape.IsNull()){
+    MESSAGE("StdMeshers_Penta_3D::CheckData() ");
+    myErrorStatus=2; // null shape
+    return;
+  }
+  //
+  aST=myShape.ShapeType();
+  if (!(aST==TopAbs_SOLID || aST==TopAbs_SHELL)) {
+    MESSAGE("StdMeshers_Penta_3D::CheckData() ");
+    myErrorStatus=3; // not compatible type of shape
+    return;
+  }
+  //
+  for (i=0; i<3; ++i) {
+    aM.Clear();
+    TopExp::MapShapes(myShape, aSTEx[i], aM);
+    iNb=aM.Extent();
+    if (iNb!=iNbEx[i]){
+      MESSAGE("StdMeshers_Penta_3D::CheckData() ");
+      myErrorStatus=4; // number of subshape is not compatible
+      return;
+    }
+  }
+}
+
+//=======================================================================
+//function : LoadIJNodes
+//purpose  : Load nodes bound to theFace into column (vectors) and rows
+//           of theIJNodes.
+//           The value of theIJNodes map is a vector of ordered nodes so
+//           that the 0-the one lies on theBaseEdge.
+//           The key of theIJNodes map is a normalized parameter of each
+//           0-the node on theBaseEdge.
+//=======================================================================
+
+bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
+                                      const TopoDS_Face&     theFace,
+                                      const TopoDS_Edge&     theBaseEdge,
+                                      SMESHDS_Mesh*          theMesh)
+{
+  // get vertices of theBaseEdge
+  TopoDS_Vertex vfb, vlb, vft; // first and last, bottom and top vertices
+  TopoDS_Edge eFrw = TopoDS::Edge( theBaseEdge.Oriented( TopAbs_FORWARD ));
+  TopExp::Vertices( eFrw, vfb, vlb );
+
+  // find the other edges of theFace and orientation of e1
+  TopoDS_Edge e1, e2, eTop;
+  bool rev1, CumOri = false;
+  TopExp_Explorer exp( theFace, TopAbs_EDGE );
+  int nbEdges = 0;
+  for ( ; exp.More(); exp.Next() )
+  {
+    if ( ++nbEdges > 4 )
+      return false; // more than 4 edges in theFace
+    TopoDS_Edge e = TopoDS::Edge( exp.Current() );
+    if ( theBaseEdge.IsSame( e ))
+      continue;
+    TopoDS_Vertex vCommon;
+    if ( !TopExp::CommonVertex( theBaseEdge, e, vCommon ))
+      eTop = e;
+    else if ( vCommon.IsSame( vfb )) {
+      e1 = e;
+      vft = TopExp::LastVertex( e1, CumOri );
+      rev1 = vfb.IsSame( vft );
+      if ( rev1 )
+        vft = TopExp::FirstVertex( e1, CumOri );
+    }
+    else
+      e2 = e;
+  }
+  if ( nbEdges < 4 )
+    return false; // lass than 4 edges in theFace
+
+  // submeshes corresponding to shapes
+  SMESHDS_SubMesh* smFace = theMesh->MeshElements( theFace );
+  SMESHDS_SubMesh* smb = theMesh->MeshElements( theBaseEdge );
+  SMESHDS_SubMesh* smt = theMesh->MeshElements( eTop );
+  SMESHDS_SubMesh* sm1 = theMesh->MeshElements( e1 );
+  SMESHDS_SubMesh* sm2 = theMesh->MeshElements( e2 );
+  SMESHDS_SubMesh* smVfb = theMesh->MeshElements( vfb );
+  SMESHDS_SubMesh* smVlb = theMesh->MeshElements( vlb );
+  SMESHDS_SubMesh* smVft = theMesh->MeshElements( vft );
+  if (!smFace || !smb || !smt || !sm1 || !sm2 || !smVfb || !smVlb || !smVft ) {
+    MESSAGE( "NULL submesh " <<smFace<<" "<<smb<<" "<<smt<<" "<<
+            sm1<<" "<<sm2<<" "<<smVfb<<" "<<smVlb<<" "<<smVft);
+    return false;
+  }
+  if ( smb->NbNodes() != smt->NbNodes() || sm1->NbNodes() != sm2->NbNodes() ) {
+    MESSAGE(" Diff nb of nodes on opposite edges" );
+    return false;
+  }
+  if (smVfb->NbNodes() != 1 || smVlb->NbNodes() != 1 || smVft->NbNodes() != 1) {
+    MESSAGE("Empty submesh of vertex");
+    return false;
+  }
+  if ( sm1->NbNodes() * smb->NbNodes() != smFace->NbNodes() ) {
+    MESSAGE( "Wrong nb face nodes: " <<
+            sm1->NbNodes()<<" "<<smb->NbNodes()<<" "<<smFace->NbNodes());
+    return false;
+  }
+  // IJ size
+  int vsize = sm1->NbNodes() + 2;
+  int hsize = smb->NbNodes() + 2;
+
+  // load nodes from theBaseEdge
+
+  set<const SMDS_MeshNode*> loadedNodes;
+  const SMDS_MeshNode* nullNode = 0;
+
+  vector<const SMDS_MeshNode*> & nVecf = theIJNodes[ 0.];
+  nVecf.resize( vsize, nullNode );
+  loadedNodes.insert( nVecf[ 0 ] = smVfb->GetNodes()->next() );
+
+  vector<const SMDS_MeshNode*> & nVecl = theIJNodes[ 1.];
+  nVecl.resize( vsize, nullNode );
+  loadedNodes.insert( nVecl[ 0 ] = smVlb->GetNodes()->next() );
+
+  double f, l;
+  BRep_Tool::Range( eFrw, f, l );
+  double range = l - f;
+  SMDS_NodeIteratorPtr nIt = smb->GetNodes();
+  const SMDS_MeshNode* node;
+  while ( nIt->more() )
+  {
+    node = nIt->next();
+    const SMDS_EdgePosition* pos =
+      dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition().get() );
+    if ( !pos ) return false;
+    double u = ( pos->GetUParameter() - f ) / range;
+    vector<const SMDS_MeshNode*> & nVec = theIJNodes[ u ];
+    nVec.resize( vsize, nullNode );
+    loadedNodes.insert( nVec[ 0 ] = node );
+  }
+  if ( theIJNodes.size() != hsize ) {
+    MESSAGE( "Wrong node positions on theBaseEdge" );
+    return false;
+  }
+
+  // load nodes from e1
+
+  map< double, const SMDS_MeshNode*> sortedNodes; // sort by param on edge
+  nIt = sm1->GetNodes();
+  while ( nIt->more() )
+  {
+    node = nIt->next();
+    const SMDS_EdgePosition* pos =
+      dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition().get() );
+    if ( !pos ) return false;
+    sortedNodes.insert( make_pair( pos->GetUParameter(), node ));
+  }
+  loadedNodes.insert( nVecf[ vsize - 1 ] = smVft->GetNodes()->next() );
+  map< double, const SMDS_MeshNode*>::iterator u_n = sortedNodes.begin();
+  int row = rev1 ? vsize - 1 : 0;
+  for ( ; u_n != sortedNodes.end(); u_n++ )
+  {
+    if ( rev1 ) row--;
+    else        row++;
+    loadedNodes.insert( nVecf[ row ] = u_n->second );
+  }
+
+  // try to load the rest nodes
+
+  // get all faces from theFace
+  set<const SMDS_MeshElement*> allFaces, foundFaces;
+  SMDS_ElemIteratorPtr eIt = smFace->GetElements();
+  while ( eIt->more() ) {
+    const SMDS_MeshElement* e = eIt->next();
+    if ( e->GetType() == SMDSAbs_Face )
+      allFaces.insert( e );
+  }
+  // Starting from 2 neighbour nodes on theBaseEdge, look for a face
+  // the nodes belong to, and between the nodes of the found face,
+  // look for a not loaded node considering this node to be the next
+  // in a column of the starting second node. Repeat, starting
+  // from nodes next to the previous starting nodes in their columns,
+  // and so on while a face can be found. Then go the the next pair
+  // of nodes on theBaseEdge.
+  StdMeshers_IJNodeMap::iterator par_nVec_1 = theIJNodes.begin();
+  StdMeshers_IJNodeMap::iterator par_nVec_2 = par_nVec_1;
+  // loop on columns
+  int col = 0;
+  for ( par_nVec_2++; par_nVec_2 != theIJNodes.end(); par_nVec_1++, par_nVec_2++ )
+  {
+    col++;
+    row = 0;
+    const SMDS_MeshNode* n1 = par_nVec_1->second[ row ];
+    const SMDS_MeshNode* n2 = par_nVec_2->second[ row ];
+    const SMDS_MeshElement* face = 0;
+    do {
+      // look for a face by 2 nodes
+      face = SMESH_MeshEditor::FindFaceInSet( n1, n2, allFaces, foundFaces );
+      if ( face )
+      {
+        int nbFaceNodes = face->NbNodes();
+        if ( nbFaceNodes > 4 ) {
+          MESSAGE(" Too many nodes in a face: " << nbFaceNodes );
+          return false;
+        }
+        // look for a not loaded node of the <face>
+        bool found = false;
+        const SMDS_MeshNode* n3 = 0; // a node defferent from n1 and n2
+        eIt = face->nodesIterator() ;
+        while ( !found && eIt->more() ) {
+          node = static_cast<const SMDS_MeshNode*>( eIt->next() );
+          found = loadedNodes.insert( node ).second;
+          if ( !found && node != n1 && node != n2 )
+            n3 = node;
+        }
+        if ( found ) {
+          if ( ++row > vsize - 1 ) {
+            MESSAGE( "Too many nodes in column "<< col <<": "<< row+1);
+            return false;
+          }
+          par_nVec_2->second[ row ] = node;
+          foundFaces.insert( face );
+          n2 = node;
+          if ( nbFaceNodes == 4 )
+            n1 = par_nVec_1->second[ row ];
+        }
+        else if (nbFaceNodes == 3 &&
+                 n3 == par_nVec_1->second[ row ] )
+          n1 = n3;
+        else {
+          MESSAGE( "Not quad mesh, column "<< col );
+          return false;
+        }
+      }
+    } while ( face && n1 && n2 );
+
+    if ( row < vsize - 1 ) {
+      MESSAGE( "Too few nodes in column "<< col <<": "<< row+1);
+      MESSAGE( "Base node 1: "<< par_nVec_1->second[0]);
+      MESSAGE( "Base node 2: "<< par_nVec_2->second[0]);
+      MESSAGE( "Current node 1: "<< n1);
+      MESSAGE( "Current node 2: "<< n2);
+      MESSAGE( "first base node: "<< theIJNodes.begin()->second[0]);
+      MESSAGE( "last base node: "<< theIJNodes.rbegin()->second[0]);
+      return false;
+    }
+  } // loop on columns
+
+  return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//
+//   StdMeshers_SMESHBlock
+//
+//////////////////////////////////////////////////////////////////////////
+
+//=======================================================================
+//function : StdMeshers_SMESHBlock
+//purpose  : 
+//=======================================================================
+StdMeshers_SMESHBlock::StdMeshers_SMESHBlock()
+{
+  myErrorStatus=1;
+  myIsEdgeForward.resize( SMESH_Block::NbEdges(), -1 );
+}
+
+//=======================================================================
+//function : IsForwadEdge
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_SMESHBlock::IsForwadEdge(const int theEdgeID)
+{
+  int index = myTBlock.ShapeIndex( theEdgeID );
+  if ( !myTBlock.IsEdgeID( theEdgeID ))
+    return false;
+
+  if ( myIsEdgeForward[ index ] < 0 )
+    myIsEdgeForward[ index ] =
+      myTBlock.IsForwardEdge( TopoDS::Edge( Shape( theEdgeID )), myShapeIDMap );
+
+  return myIsEdgeForward[ index ];
+}
+
+//=======================================================================
+//function : ErrorStatus
+//purpose  : 
+//=======================================================================
+int StdMeshers_SMESHBlock::ErrorStatus() const
+{
+  return myErrorStatus;
+}
+//=======================================================================
+//function : Load
+//purpose  : 
+//=======================================================================
+void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell)
+{
+  
+  TopoDS_Vertex aV000, aV001;
+  //
+  Load(theShell, aV000, aV001);
+}
+//=======================================================================
+//function : Load
+//purpose  : 
+//=======================================================================
+void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell,
+                                const TopoDS_Vertex& theV000,
+                                const TopoDS_Vertex& theV001)
+{
+  myErrorStatus=0;
+  //
+  myShell=theShell;
+  //
+  bool bOk;
+  //
+  myShapeIDMap.Clear();  
+  bOk=myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap);
+  if (!bOk) {
+    myErrorStatus=2;
+    return;
+  }
+}
+//=======================================================================
+//function : ComputeParameters
+//purpose  : 
+//=======================================================================
+void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt, 
+                                             gp_XYZ& theXYZ)
+{
+  ComputeParameters(thePnt, myShell, theXYZ);
+}
+//=======================================================================
+//function : ComputeParameters
+//purpose  : 
+//=======================================================================
+void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt,
+                                             const TopoDS_Shape& theShape,
+                                             gp_XYZ& theXYZ)
+{
+  myErrorStatus=0;
+  //
+  int aID;
+  bool bOk;
+  //
+  aID=ShapeID(theShape);
+  if (myErrorStatus) {
+    return;
+  }
+  bOk=myTBlock.ComputeParameters(thePnt, theXYZ, aID);
+  if (!bOk) {
+    myErrorStatus=4; // problems with computation Parameters 
+    return;
+  }
+}
+
+//=======================================================================
+//function : ComputeParameters
+//purpose  : 
+//=======================================================================
+
+void StdMeshers_SMESHBlock::ComputeParameters(const double& theU,
+                                              const TopoDS_Shape& theShape,
+                                              gp_XYZ& theXYZ)
+{
+  myErrorStatus=0;
+  //
+  int aID;
+  bool bOk=false;
+  //
+  aID=ShapeID(theShape);
+  if (myErrorStatus) {
+    return;
+  }
+  if ( SMESH_Block::IsEdgeID( aID ))
+      bOk=myTBlock.EdgeParameters( aID, theU, theXYZ );
+  if (!bOk) {
+    myErrorStatus=4; // problems with computation Parameters 
+    return;
+  }
+}
+
+//=======================================================================
+//function : Point
+//purpose  : 
+//=======================================================================
+ void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams,
+                                  gp_Pnt& aP3D)
+{
+  TopoDS_Shape aS;
+  //
+  Point(theParams, aS, aP3D);
+}
+//=======================================================================
+//function : Point
+//purpose  : 
+//=======================================================================
+ void StdMeshers_SMESHBlock::Point(const gp_XYZ& theParams,
+                                  const TopoDS_Shape& theShape,
+                                  gp_Pnt& aP3D)
+{
+  myErrorStatus=0;
+  //
+  int aID;
+  bool bOk=false;
+  gp_XYZ aXYZ(99.,99.,99.);
+  aP3D.SetXYZ(aXYZ);
+  //
+  if (theShape.IsNull()) {
+    bOk=myTBlock.ShellPoint(theParams, aXYZ);
+  }
+  //
+  else {
+    aID=ShapeID(theShape);
+    if (myErrorStatus) {
+      return;
+    }
+    //
+    if (SMESH_Block::IsVertexID(aID)) {
+      bOk=myTBlock.VertexPoint(aID, aXYZ);
+    }
+    else if (SMESH_Block::IsEdgeID(aID)) {
+      bOk=myTBlock.EdgePoint(aID, theParams, aXYZ);
+    }
+    //
+    else if (SMESH_Block::IsFaceID(aID)) {
+      bOk=myTBlock.FacePoint(aID, theParams, aXYZ);
+    }
+  }
+  if (!bOk) {
+    myErrorStatus=4; // problems with point computation 
+    return;
+  }
+  aP3D.SetXYZ(aXYZ);
+}
+//=======================================================================
+//function : ShapeID
+//purpose  : 
+//=======================================================================
+int StdMeshers_SMESHBlock::ShapeID(const TopoDS_Shape& theShape)
+{
+  myErrorStatus=0;
+  //
+  int aID=-1;
+  TopoDS_Shape aSF, aSR;
+  //
+  aSF=theShape;
+  aSF.Orientation(TopAbs_FORWARD);
+  aSR=theShape;
+  aSR.Orientation(TopAbs_REVERSED);
+  //
+  if (myShapeIDMap.Contains(aSF)) {
+    aID=myShapeIDMap.FindIndex(aSF);
+    return aID;
+  }
+  if (myShapeIDMap.Contains(aSR)) {
+    aID=myShapeIDMap.FindIndex(aSR);
+    return aID;
+  }
+  myErrorStatus=2; // unknown shape;
+  return aID;
+}
+//=======================================================================
+//function : Shape
+//purpose  : 
+//=======================================================================
+const TopoDS_Shape& StdMeshers_SMESHBlock::Shape(const int theID)
+{
+  myErrorStatus=0;
+  //
+  int aNb;
+  //
+  aNb=myShapeIDMap.Extent();
+  if (theID<1 || theID>aNb) {
+    myErrorStatus=3; // ID is out of range
+    return myEmptyShape;
+  }
+  //
+  const TopoDS_Shape& aS=myShapeIDMap.FindKey(theID);
+  return aS;
+}
diff --git a/src/StdMeshers_I/StdMeshers_Arithmetic1D_i.hxx b/src/StdMeshers_I/StdMeshers_Arithmetic1D_i.hxx
new file mode 100644 (file)
index 0000000..090f0a7
--- /dev/null
@@ -0,0 +1,66 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : StdMeshers_Arithmetic1D_i.hxx
+//  Author : Damien COQUERET, OCC
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_ARITHMETIC1D_I_HXX_
+#define _SMESH_ARITHMETIC1D_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_Arithmetic1D.hxx"
+
+// ======================================================
+// Arithmetic 1D hypothesis
+// ======================================================
+class StdMeshers_Arithmetic1D_i:
+  public virtual POA_StdMeshers::StdMeshers_Arithmetic1D,
+  public virtual SMESH_Hypothesis_i
+{
+public:
+  // Constructor
+  StdMeshers_Arithmetic1D_i( PortableServer::POA_ptr thePOA,
+                            int                     theStudyId,
+                           ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_Arithmetic1D_i();
+
+  // Set length
+  void SetLength( CORBA::Double theLength, CORBA::Boolean theIsStart )
+    throw ( SALOME::SALOME_Exception );
+  // Get length
+  CORBA::Double GetLength(CORBA::Boolean theIsStart);
+
+  // Get implementation
+  ::StdMeshers_Arithmetic1D* GetImpl();
+  
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
diff --git a/src/StdMeshers_I/StdMeshers_Deflection1D_i.hxx b/src/StdMeshers_I/StdMeshers_Deflection1D_i.hxx
new file mode 100644 (file)
index 0000000..138b1d9
--- /dev/null
@@ -0,0 +1,70 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : StdMeshers_Deflection1D_i.hxx
+//           Moved here from SMESH_LocalLength_i.hxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_Deflection1D_I_HXX_
+#define _SMESH_Deflection1D_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_Deflection1D.hxx"
+
+class SMESH_Gen;
+
+// ======================================================
+// Local Length hypothesis
+// ======================================================
+class StdMeshers_Deflection1D_i:
+  public virtual POA_StdMeshers::StdMeshers_Deflection1D,
+  public virtual SMESH_Hypothesis_i
+{
+public:
+  // Constructor
+  StdMeshers_Deflection1D_i( PortableServer::POA_ptr thePOA,
+                       int                     theStudyId,
+                       ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_Deflection1D_i();
+
+  // Set deflection
+  void SetDeflection( CORBA::Double theLength )
+    throw ( SALOME::SALOME_Exception );
+  // Get deflection
+  CORBA::Double GetDeflection();
+
+  // Get implementation
+  ::StdMeshers_Deflection1D* GetImpl();
+  
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
+
diff --git a/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.cxx b/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.cxx
new file mode 100644 (file)
index 0000000..35d871c
--- /dev/null
@@ -0,0 +1,135 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : StdMeshers_LengthFromEdges_i.cxx
+//           Moved here from SMESH_LengthFromEdges_i.cxx
+//  Author : Nadir BOUHAMOU CEA/DEN, Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+using namespace std;
+#include "StdMeshers_LengthFromEdges_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ *  StdMeshers_LengthFromEdges_i::StdMeshers_LengthFromEdges_i
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_LengthFromEdges_i::StdMeshers_LengthFromEdges_i( PortableServer::POA_ptr thePOA,
+                                                 int                     theStudyId,
+                                                 ::SMESH_Gen*            theGenImpl )
+     : SALOME::GenericObj_i( thePOA ), 
+       SMESH_Hypothesis_i( thePOA )
+{
+  MESSAGE( "StdMeshers_LengthFromEdges_i::StdMeshers_LengthFromEdges_i" );
+  myBaseImpl = new ::StdMeshers_LengthFromEdges( theGenImpl->GetANewId(),
+                                           theStudyId,
+                                           theGenImpl );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_LengthFromEdges_i::~StdMeshers_LengthFromEdges_i
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_LengthFromEdges_i::~StdMeshers_LengthFromEdges_i()
+{
+  MESSAGE( "StdMeshers_LengthFromEdges_i::~StdMeshers_LengthFromEdges_i" );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_LengthFromEdges_i::SetMode
+ *
+ *  Set mode
+ */
+//=============================================================================
+
+void StdMeshers_LengthFromEdges_i::SetMode( CORBA::Long theMode )
+  throw (SALOME::SALOME_Exception)
+{
+  MESSAGE( "StdMeshers_LengthFromEdges_i::SetMode" );
+  ASSERT( myBaseImpl );
+  try {
+    this->GetImpl()->SetMode( theMode );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+                                 SALOME::BAD_PARAM );
+  }
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_LengthFromEdges_i::GetMode
+ *
+ *  Get mode
+ */
+//=============================================================================
+
+CORBA::Long StdMeshers_LengthFromEdges_i::GetMode()
+{
+  MESSAGE( "StdMeshers_LengthFromEdges_i::GetMode" );
+  ASSERT( myBaseImpl );
+  return this->GetImpl()->GetMode();
+}
+
+
+//=============================================================================
+/*!
+ *  StdMeshers_LengthFromEdges_i::GetImpl
+ *
+ *  Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_LengthFromEdges* StdMeshers_LengthFromEdges_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_LengthFromEdges_i::GetImpl" );
+  return ( ::StdMeshers_LengthFromEdges* )myBaseImpl;
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether hypothesis supports given entity type 
+  * \param type - dimension (see SMESH::Dimension enumeration)
+  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ * 
+ * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================  
+CORBA::Boolean StdMeshers_LengthFromEdges_i::IsDimSupported( SMESH::Dimension type )
+{
+  return type == SMESH::DIM_2D;
+}
+
diff --git a/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.hxx b/src/StdMeshers_I/StdMeshers_LengthFromEdges_i.hxx
new file mode 100644 (file)
index 0000000..1075278
--- /dev/null
@@ -0,0 +1,68 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : StdMeshers_LengthFromEdges_i.hxx
+//           Moved here from SMESH_LengthFromEdges_i.hxx
+//  Author : Nadir BOUHAMOU CEA/DEN, Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_LENGTHFROMEDGES_I_HXX_
+#define _SMESH_LENGTHFROMEDGES_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_LengthFromEdges.hxx"
+
+// ======================================================
+// Length from edges hypothesis
+// ======================================================
+class StdMeshers_LengthFromEdges_i:
+  public virtual POA_StdMeshers::StdMeshers_LengthFromEdges,
+  public virtual SMESH_Hypothesis_i
+{
+public:
+  // Constructor
+  StdMeshers_LengthFromEdges_i( PortableServer::POA_ptr thePOA,
+                           int                     theStudyId,
+                           ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_LengthFromEdges_i();
+
+  // Set mode
+  void SetMode( CORBA::Long theMode )
+    throw ( SALOME::SALOME_Exception );
+  // Get mode
+  CORBA::Long GetMode();
+
+  // Get implementation
+  ::StdMeshers_LengthFromEdges* GetImpl();
+  
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
+
diff --git a/src/StdMeshers_I/StdMeshers_LocalLength_i.hxx b/src/StdMeshers_I/StdMeshers_LocalLength_i.hxx
new file mode 100644 (file)
index 0000000..f0b6b21
--- /dev/null
@@ -0,0 +1,70 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : StdMeshers_LocalLength_i.hxx
+//           Moved here from SMESH_LocalLength_i.hxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_LOCALLENGTH_I_HXX_
+#define _SMESH_LOCALLENGTH_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_LocalLength.hxx"
+
+class SMESH_Gen;
+
+// ======================================================
+// Local Length hypothesis
+// ======================================================
+class StdMeshers_LocalLength_i:
+  public virtual POA_StdMeshers::StdMeshers_LocalLength,
+  public virtual SMESH_Hypothesis_i
+{
+public:
+  // Constructor
+  StdMeshers_LocalLength_i( PortableServer::POA_ptr thePOA,
+                       int                     theStudyId,
+                       ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_LocalLength_i();
+
+  // Set length
+  void SetLength( CORBA::Double theLength )
+    throw ( SALOME::SALOME_Exception );
+  // Get length
+  CORBA::Double GetLength();
+
+  // Get implementation
+  ::StdMeshers_LocalLength* GetImpl();
+  
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
+
diff --git a/src/StdMeshers_I/StdMeshers_MaxElementArea_i.hxx b/src/StdMeshers_I/StdMeshers_MaxElementArea_i.hxx
new file mode 100644 (file)
index 0000000..39dde76
--- /dev/null
@@ -0,0 +1,67 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : StdMeshers_MaxElementArea_i.hxx
+//           Moved here from SMESH_MaxElementArea_i.hxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_MAXELEMENTAREA_I_HXX_
+#define _SMESH_MAXELEMENTAREA_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_MaxElementArea.hxx"
+
+// ======================================================
+// Maximum Element Area hypothesis
+// ======================================================
+class StdMeshers_MaxElementArea_i:
+  public virtual POA_StdMeshers::StdMeshers_MaxElementArea,
+  public virtual SMESH_Hypothesis_i
+{
+public:
+  // Constructor
+  StdMeshers_MaxElementArea_i( PortableServer::POA_ptr thePOA,
+                          int                     theStudyId,
+                         ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_MaxElementArea_i();
+
+  // Set maximum element area 
+  void SetMaxElementArea( CORBA::Double theArea )
+    throw ( SALOME::SALOME_Exception );
+  // Get maximum element area 
+  CORBA::Double GetMaxElementArea();
+
+  // Get implementation
+  ::StdMeshers_MaxElementArea* GetImpl();
+  
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
diff --git a/src/StdMeshers_I/StdMeshers_MaxElementVolume_i.hxx b/src/StdMeshers_I/StdMeshers_MaxElementVolume_i.hxx
new file mode 100644 (file)
index 0000000..928fab5
--- /dev/null
@@ -0,0 +1,67 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : StdMeshers_MaxElementVolume_i.hxx
+//           Moved here from SMESH_MaxElementVolume_i.hxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_MAXELEMENTVOLUME_I_HXX_
+#define _SMESH_MAXELEMENTVOLUME_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_MaxElementVolume.hxx"
+
+// ======================================================
+// Maximum Element Volume hypothesis
+// ======================================================
+class StdMeshers_MaxElementVolume_i:
+  public virtual POA_StdMeshers::StdMeshers_MaxElementVolume,
+  public virtual SMESH_Hypothesis_i
+{
+public:
+  // Constructor
+  StdMeshers_MaxElementVolume_i( PortableServer::POA_ptr thePOA,
+                            int                     theStudyId,
+                            ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_MaxElementVolume_i();
+
+  // Set maximum element volume
+  void SetMaxElementVolume( CORBA::Double theVolume )
+    throw (SALOME::SALOME_Exception);
+  // Get maximum element volume
+  CORBA::Double GetMaxElementVolume();
+
+  // Get implementation
+  ::StdMeshers_MaxElementVolume* GetImpl();
+  
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
diff --git a/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.cxx b/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.cxx
new file mode 100644 (file)
index 0000000..8940cf7
--- /dev/null
@@ -0,0 +1,81 @@
+//  SMESH StdMeshers_I : idl implementation based on 'SMESH' unit's classes
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : StdMeshers_NotConformAllowed_i.cxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+using namespace std;
+using namespace std;
+#include "StdMeshers_NotConformAllowed_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ *  Constructor: 
+ *  _name is related to the class name: prefix = SMESH_ ; suffix = _i .
+ */
+//=============================================================================
+
+StdMeshers_NotConformAllowed_i::StdMeshers_NotConformAllowed_i
+                                (PortableServer::POA_ptr thePOA,
+                                 int                     studyId,
+                                 ::SMESH_Gen*            genImpl)
+     : SALOME::GenericObj_i( thePOA ), 
+       SMESH_Hypothesis_i( thePOA )
+{
+  MESSAGE("StdMeshers_NotConformAllowed_i::StdMeshers_NotConformAllowed_i");
+  myBaseImpl = new ::StdMeshers_NotConformAllowed(genImpl->GetANewId(),
+                                                  studyId,
+                                                  genImpl);
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+StdMeshers_NotConformAllowed_i::~StdMeshers_NotConformAllowed_i()
+{
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether hypothesis supports given entity type 
+  * \param type - dimension (see SMESH::Dimension enumeration)
+  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ * 
+ * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================  
+CORBA::Boolean StdMeshers_NotConformAllowed_i::IsDimSupported( SMESH::Dimension /*type*/ )
+{
+  return true;
+}
+
+
+
diff --git a/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.hxx b/src/StdMeshers_I/StdMeshers_NotConformAllowed_i.hxx
new file mode 100644 (file)
index 0000000..ceddb32
--- /dev/null
@@ -0,0 +1,57 @@
+//  SMESH StdMeshers_I : idl implementation based on 'SMESH' unit's classes
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : StdMeshers_NotConformAllowed_i.hxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+#ifndef _StdMeshers_NotConformAllowed_I_HXX_
+#define _StdMeshers_NotConformAllowed_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+
+#include "StdMeshers_NotConformAllowed.hxx"
+
+class StdMeshers_NotConformAllowed_i:
+  public POA_StdMeshers::StdMeshers_NotConformAllowed,
+  public SMESH_Hypothesis_i
+{
+public:
+  StdMeshers_NotConformAllowed_i(PortableServer::POA_ptr thePOA,
+                                 int studyId,
+                                 ::SMESH_Gen* genImpl);
+  virtual ~StdMeshers_NotConformAllowed_i();
+  
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+
+protected:
+  ::StdMeshers_NotConformAllowed* _impl;
+};
+
+#endif
+
diff --git a/src/StdMeshers_I/StdMeshers_Propagation_i.cxx b/src/StdMeshers_I/StdMeshers_Propagation_i.cxx
new file mode 100644 (file)
index 0000000..4e03874
--- /dev/null
@@ -0,0 +1,91 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  CEA
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+//  File   : StdMeshers_Propagation_i.cxx
+//  Module : SMESH
+//  $Header$
+
+using namespace std;
+#include "StdMeshers_Propagation_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ *  StdMeshers_Propagation_i::StdMeshers_Propagation_i
+ *
+ *  Constructor
+ */
+//=============================================================================
+StdMeshers_Propagation_i::StdMeshers_Propagation_i (PortableServer::POA_ptr thePOA,
+                                                    int                     theStudyId,
+                                                    ::SMESH_Gen*            theGenImpl )
+     : SALOME::GenericObj_i( thePOA ), 
+       SMESH_Hypothesis_i( thePOA )
+{
+  MESSAGE( "StdMeshers_Propagation_i::StdMeshers_Propagation_i" );
+  myBaseImpl = new ::StdMeshers_Propagation(theGenImpl->GetANewId(),
+                                            theStudyId,
+                                            theGenImpl);
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_Propagation_i::~StdMeshers_Propagation_i
+ *
+ *  Destructor
+ */
+//=============================================================================
+StdMeshers_Propagation_i::~StdMeshers_Propagation_i()
+{
+  MESSAGE( "StdMeshers_Propagation_i::~StdMeshers_Propagation_i" );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_Propagation_i::GetImpl
+ *
+ *  Get implementation
+ */
+//=============================================================================
+::StdMeshers_Propagation* StdMeshers_Propagation_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_Propagation_i::GetImpl" );
+  return ( ::StdMeshers_Propagation* )myBaseImpl;
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether hypothesis supports given entity type 
+  * \param type - dimension (see SMESH::Dimension enumeration)
+  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ * 
+ * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================  
+CORBA::Boolean StdMeshers_Propagation_i::IsDimSupported( SMESH::Dimension type )
+{
+  return type == SMESH::DIM_1D;
+}
+
diff --git a/src/StdMeshers_I/StdMeshers_Propagation_i.hxx b/src/StdMeshers_I/StdMeshers_Propagation_i.hxx
new file mode 100644 (file)
index 0000000..ca130bc
--- /dev/null
@@ -0,0 +1,60 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  CEA
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org or email : webmaster.salome@opencascade.org
+//
+//
+//
+//  File   : StdMeshers_Propagation_i.hxx
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_PROPAGATION_I_HXX_
+#define _SMESH_PROPAGATION_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_Propagation.hxx"
+
+class SMESH_Gen;
+
+// ======================================================
+// Propagation hypothesis
+// ======================================================
+class StdMeshers_Propagation_i:
+  public virtual POA_StdMeshers::StdMeshers_Propagation,
+  public virtual SMESH_Hypothesis_i
+{
+public:
+  // Constructor
+  StdMeshers_Propagation_i (PortableServer::POA_ptr thePOA,
+                            int                     theStudyId,
+                            ::SMESH_Gen*            theGenImpl);
+  // Destructor
+  virtual ~StdMeshers_Propagation_i();
+
+  // Get implementation
+  ::StdMeshers_Propagation* GetImpl();
+  
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
diff --git a/src/StdMeshers_I/StdMeshers_StartEndLength_i.hxx b/src/StdMeshers_I/StdMeshers_StartEndLength_i.hxx
new file mode 100644 (file)
index 0000000..d937f93
--- /dev/null
@@ -0,0 +1,70 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
+// 
+//  This library is free software; you can redistribute it and/or 
+//  modify it under the terms of the GNU Lesser General Public 
+//  License as published by the Free Software Foundation; either 
+//  version 2.1 of the License. 
+// 
+//  This library is distributed in the hope that it will be useful, 
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//  Lesser General Public License for more details. 
+// 
+//  You should have received a copy of the GNU Lesser General Public 
+//  License along with this library; if not, write to the Free Software 
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
+// 
+//  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+//
+//
+//
+//  File   : StdMeshers_StartEndLength_i.hxx
+//           Moved here from SMESH_LocalLength_i.hxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_StartEndLength_I_HXX_
+#define _SMESH_StartEndLength_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_StartEndLength.hxx"
+
+class SMESH_Gen;
+
+// ======================================================
+// Local Length hypothesis
+// ======================================================
+class StdMeshers_StartEndLength_i:
+  public virtual POA_StdMeshers::StdMeshers_StartEndLength,
+  public virtual SMESH_Hypothesis_i
+{
+public:
+  // Constructor
+  StdMeshers_StartEndLength_i(PortableServer::POA_ptr thePOA,
+                              int                     theStudyId,
+                              ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_StartEndLength_i();
+
+  // Set length
+  void SetLength( CORBA::Double theLength, CORBA::Boolean theIsStart )
+    throw ( SALOME::SALOME_Exception );
+  // Get length
+  CORBA::Double GetLength(CORBA::Boolean theIsStart);
+
+  // Get implementation
+  ::StdMeshers_StartEndLength* GetImpl();
+  
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
+