//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
//
//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
//
//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//

//  File   : SMESH_MeshEditor.idl
//
#ifndef _SMESH_MESHEDITOR_IDL_
#define _SMESH_MESHEDITOR_IDL_

#include "SMESH_Mesh.idl"

module SMESH
{
  /*!
   * This interface makes modifications on the Mesh - removing elements and nodes etc.
   */
  interface NumericalFunctor;
  interface SMESH_MeshEditor
  {
    /*!
     * \brief Wrap a sequence of ids in a SMESH_IDSource
     */
    SMESH_IDSource MakeIDSource(in long_array IDsOfElements);

    boolean RemoveElements(in long_array IDsOfElements);

    boolean RemoveNodes(in long_array IDsOfNodes);

    long AddNode(in double x, in double y, in double z);

    /*!
     *  Create 0D element on the given node.
     *  \param IdOfNode Node IDs for creation of element.
     */
    long Add0DElement(in long IDOfNode);

    /*!
     *  Create edge, either linear and quadratic (this is determed
     *  by number of given nodes).
     *  \param IdsOfNodes List of node IDs for creation of element.
     *  Needed order of nodes in this list corresponds to description
     *  of MED. This description is located by the following link:
     *   http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
     */
    long AddEdge(in long_array IDsOfNodes);

    /*!
     *  Create face, either linear and quadratic (this is determed
     *  by number of given nodes).
     *  \param IdsOfNodes List of node IDs for creation of element.
     *  Needed order of nodes in this list corresponds to description
     *  of MED. This description is located by the following link:
     *   http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
     */
    long AddFace(in long_array IDsOfNodes);

    long AddPolygonalFace(in long_array IdsOfNodes);

    /*!
     *  Create volume, either linear and quadratic (this is determed
     *  by number of given nodes).
     *  \param IdsOfNodes List of node IDs for creation of element.
     *  Needed order of nodes in this list corresponds to description
     *  of MED. This description is located by the following link:
     *   http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
     */
    long AddVolume(in long_array IDsOfNodes);

    /*!
     *  Create volume of many faces, giving nodes for each face.
     *  \param IdsOfNodes List of node IDs for volume creation face by face.
     *  \param Quantities List of integer values, Quantities[i]
     *         gives quantity of nodes in face number i.
     */
    long AddPolyhedralVolume (in long_array IdsOfNodes,
                              in long_array Quantities);

    /*!
     *  Create volume of many faces, giving IDs of existing faces.
     *  \param IdsOfFaces List of face IDs for volume creation.
     *  \note The created volume will refer only to nodes
     *        of the given faces, not to the faces itself.
     */
    long AddPolyhedralVolumeByFaces (in long_array IdsOfFaces);

    /*!
     * \brief Bind a node to a vertex
      * \param NodeID - node ID
      * \param VertexID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
     */
    void SetNodeOnVertex(in long NodeID, in long VertexID)
      raises (SALOME::SALOME_Exception);
    /*!
     * \brief Store node position on an edge
      * \param NodeID - node ID
      * \param EdgeID - edge ID available through GEOM_Object.GetSubShapeIndices()[0]
      * \param paramOnEdge - parameter on edge where the node is located
     */
    void SetNodeOnEdge(in long NodeID, in long EdgeID, in double paramOnEdge)
      raises (SALOME::SALOME_Exception);
    /*!
     * \brief Store node position on a face
      * \param NodeID - node ID
      * \param FaceID - face ID available through GEOM_Object.GetSubShapeIndices()[0]
      * \param u - U parameter on face where the node is located
      * \param v - V parameter on face where the node is located
     */
    void SetNodeOnFace(in long NodeID, in long FaceID, in double u, in double v)
      raises (SALOME::SALOME_Exception);
    /*!
     * \brief Bind a node to a solid
      * \param NodeID - node ID
      * \param SolidID - vertex ID available through GEOM_Object.GetSubShapeIndices()[0]
     */
    void SetNodeInVolume(in long NodeID, in long SolidID)
      raises (SALOME::SALOME_Exception);
    /*!
     * \brief Bind an element to a shape
      * \param ElementID - element ID
      * \param ShapeID - shape ID available through GEOM_Object.GetSubShapeIndices()[0]
     */
    void SetMeshElementOnShape(in long ElementID, in long ShapeID)
      raises (SALOME::SALOME_Exception);


    boolean MoveNode(in long NodeID, in double x, in double y, in double z);

    boolean InverseDiag(in long NodeID1, in long NodeID2);

    boolean DeleteDiag(in long NodeID1, in long NodeID2);

    boolean Reorient(in long_array IDsOfElements);

    boolean ReorientObject(in SMESH_IDSource theObject);

    /*!
     * \brief Fuse neighbour triangles into quadrangles.
     * \param theElems     The triangles to be fused.
     * \param theCriterion Is used to choose a neighbour to fuse with.
     * \param theMaxAngle  Is a max angle between element normals at which fusion
     *                     is still performed; theMaxAngle is mesured in radians.
     * \return TRUE in case of success, FALSE otherwise.
     */
    boolean TriToQuad (in long_array       IDsOfElements,
		       in NumericalFunctor Criterion,
		       in double           MaxAngle);

    /*!
     * \brief Fuse neighbour triangles into quadrangles.
     *
     * Behaves like the above method, taking list of elements from \a theObject
     */
    boolean TriToQuadObject (in SMESH_IDSource   theObject,
			     in NumericalFunctor Criterion,
			     in double           MaxAngle);

    /*!
     * \brief Split quadrangles into triangles.
     * \param theElems     The faces to be splitted.
     * \param theCriterion Is used to choose a diagonal for splitting.
     * \return TRUE in case of success, FALSE otherwise.
     */
    boolean QuadToTri (in long_array       IDsOfElements,
		       in NumericalFunctor Criterion);

    /*!
     * \brief Split quadrangles into triangles.
     *
     * Behaves like the above method, taking list of elements from \a theObject
     */
    boolean QuadToTriObject (in SMESH_IDSource   theObject,
			     in NumericalFunctor Criterion);

    /*!
     * \brief Split quadrangles into triangles.
     * \param theElems  The faces to be splitted.
     * \param the13Diag Is used to choose a diagonal for splitting.
     * \return TRUE in case of success, FALSE otherwise.
     */
    boolean SplitQuad (in long_array IDsOfElements,
		       in boolean    Diag13);

    /*!
     * \brief Split quadrangles into triangles.
     *
     * Behaves like the above method, taking list of elements from \a theObject
     */
    boolean SplitQuadObject (in SMESH_IDSource theObject,
			     in boolean        Diag13);

    /*!
     *  Find better splitting of the given quadrangle.
     *  \param IDOfQuad  ID of the quadrangle to be splitted.
     *  \param Criterion A criterion to choose a diagonal for splitting.
     *  \return 1 if 1-3 diagonal is better, 2 if 2-4
     *          diagonal is better, 0 if error occurs.
     */
    long BestSplit (in long             IDOfQuad,
		    in NumericalFunctor Criterion);

    /*!
     * \brief Split volumic elements into tetrahedrons
     *  \param elems - elements to split
     *  \param methodFlags - flags passing splitting method:
     *         1 - split the hexahedron into 5 tetrahedrons
     *         2 - split the hexahedron into 6 tetrahedrons
     */
    void SplitVolumesIntoTetra(in SMESH_IDSource elems, in short methodFlags)
      raises (SALOME::SALOME_Exception);


    enum Smooth_Method { LAPLACIAN_SMOOTH, CENTROIDAL_SMOOTH };

    boolean Smooth(in long_array    IDsOfElements,
                   in long_array    IDsOfFixedNodes,
                   in long          MaxNbOfIterations,
                   in double        MaxAspectRatio,
                   in Smooth_Method Method);

    boolean SmoothObject(in SMESH_IDSource  theObject,
			 in long_array      IDsOfFixedNodes,
			 in long            MaxNbOfIterations,
			 in double          MaxAspectRatio,
			 in Smooth_Method   Method);

    boolean SmoothParametric(in long_array    IDsOfElements,
                             in long_array    IDsOfFixedNodes,
                             in long          MaxNbOfIterations,
                             in double        MaxAspectRatio,
                             in Smooth_Method Method);

    boolean SmoothParametricObject(in SMESH_IDSource  theObject,
                                   in long_array      IDsOfFixedNodes,
                                   in long            MaxNbOfIterations,
                                   in double          MaxAspectRatio,
                                   in Smooth_Method   Method);

    void ConvertToQuadratic(in boolean theForce3d);

    boolean ConvertFromQuadratic();

    void RenumberNodes();

    void RenumberElements();

    /*!
     * \brief Genarate dim+1 elements by rotation of given elements around axis
     * \param IDsOfElements - elements to ratate
     * \param Axix - rotation axis
     * \param AngleInRadians - rotation angle
     * \param NbOfSteps - number of elements to generate from one element
     */
    void RotationSweep(in long_array       IDsOfElements,
                       in AxisStruct       Axix,
                       in double           AngleInRadians,
                       in long             NbOfSteps,
                       in double           Tolerance);
    /*!
     * \brief Same as previous but additionally create groups of elements
     *  generated from elements belonging to preexisting groups
     */
    ListOfGroups RotationSweepMakeGroups(in long_array       IDsOfElements,
                                         in AxisStruct       Axix,
                                         in double           AngleInRadians,
                                         in long             NbOfSteps,
                                         in double           Tolerance);
    /*!
     * \brief Genarate dim+1 elements by rotation of the object around axis
     * \param theObject - object containing elements to ratate
     * \param Axix - rotation axis
     * \param AngleInRadians - rotation angle
     * \param NbOfSteps - number of elements to generate from one element
     */
    void RotationSweepObject(in SMESH_IDSource  theObject,
			     in AxisStruct      Axix,
			     in double          AngleInRadians,
			     in long            NbOfSteps,
			     in double          Tolerance);
    /*!
     * \brief Same as previous but additionally create groups of elements
     *  generated from elements belonging to preexisting groups
     */
    ListOfGroups RotationSweepObjectMakeGroups(in SMESH_IDSource  theObject,
                                               in AxisStruct      Axix,
                                               in double          AngleInRadians,
                                               in long            NbOfSteps,
                                               in double          Tolerance);
    /*!
     * \brief Genarate dim+1 elements by rotation of the object around axis
     * \param theObject - object containing elements to ratate
     * \param Axix - rotation axis
     * \param AngleInRadians - rotation angle
     * \param NbOfSteps - number of elements to generate from one element
     */
    void RotationSweepObject1D(in SMESH_IDSource  theObject,
			       in AxisStruct      Axix,
			       in double          AngleInRadians,
			       in long            NbOfSteps,
			       in double          Tolerance);
    /*!
     * \brief Same as previous but additionally create groups of elements
     *  generated from elements belonging to preexisting groups
     */
    ListOfGroups RotationSweepObject1DMakeGroups(in SMESH_IDSource  theObject,
						 in AxisStruct      Axix,
						 in double          AngleInRadians,
						 in long            NbOfSteps,
						 in double          Tolerance);
    /*!
     * \brief Genarate dim+1 elements by rotation of the object around axis
     * \param theObject - object containing elements to ratate
     * \param Axix - rotation axis
     * \param AngleInRadians - rotation angle
     * \param NbOfSteps - number of elements to generate from one element
     */
    void RotationSweepObject2D(in SMESH_IDSource  theObject,
			       in AxisStruct      Axix,
			       in double          AngleInRadians,
			       in long            NbOfSteps,
			       in double          Tolerance);
    /*!
     * \brief Same as previous but additionally create groups of elements
     *  generated from elements belonging to preexisting groups
     */
    ListOfGroups RotationSweepObject2DMakeGroups(in SMESH_IDSource  theObject,
						 in AxisStruct      Axix,
						 in double          AngleInRadians,
						 in long            NbOfSteps,
						 in double          Tolerance);
    /*!
     * \brief Genarate dim+1 elements by extrusion of elements along vector
     * \param IDsOfElements - elements to sweep
     * \param StepVector - vector giving direction and distance of an extrusion step
     * \param NbOfSteps - number of elements to generate from one element
     */
    void ExtrusionSweep(in long_array      IDsOfElements,
                        in DirStruct       StepVector,
                        in long            NbOfSteps);
    /*!
     * \brief Same as previous but additionally create groups of elements
     *  generated from elements belonging to preexisting groups
     */
    ListOfGroups ExtrusionSweepMakeGroups(in long_array      IDsOfElements,
                                          in DirStruct       StepVector,
                                          in long            NbOfSteps);
   /*!
    * Generate new elements by extrusion of theElements 
    * by StepVector by NbOfSteps
    * param ExtrFlags set flags for performing extrusion
    * param SewTolerance - uses for comparing locations of nodes if flag
    *   EXTRUSION_FLAG_SEW is set
    */
    void AdvancedExtrusion(in long_array      IDsOfElements,
                           in DirStruct       StepVector,
                           in long            NbOfSteps,
			   in long            ExtrFlags,
			   in double          SewTolerance);
    /*!
     * \brief Same as previous but additionally create groups of elements
     *  generated from elements belonging to preexisting groups
     */
    ListOfGroups AdvancedExtrusionMakeGroups(in long_array      IDsOfElements,
                                             in DirStruct       StepVector,
                                             in long            NbOfSteps,
                                             in long            ExtrFlags,
                                             in double          SewTolerance);

    void ExtrusionSweepObject(in SMESH_IDSource  theObject,
			      in DirStruct       StepVector,
			      in long            NbOfSteps);
    ListOfGroups ExtrusionSweepObjectMakeGroups(in SMESH_IDSource  theObject,
                                                in DirStruct       StepVector,
                                                in long            NbOfSteps);

    void ExtrusionSweepObject1D(in SMESH_IDSource theObject,
				in DirStruct      StepVector,
				in long           NbOfSteps);
    ListOfGroups ExtrusionSweepObject1DMakeGroups(in SMESH_IDSource theObject,
                                                  in DirStruct      StepVector,
                                                  in long           NbOfSteps);

    void ExtrusionSweepObject2D(in SMESH_IDSource theObject,
				in DirStruct      StepVector,
				in long           NbOfSteps);
    ListOfGroups ExtrusionSweepObject2DMakeGroups(in SMESH_IDSource theObject,
                                                  in DirStruct      StepVector,
                                                  in long           NbOfSteps);

    enum Extrusion_Error {
      EXTR_OK,
      EXTR_NO_ELEMENTS,
      EXTR_PATH_NOT_EDGE,
      EXTR_BAD_PATH_SHAPE,
      EXTR_BAD_STARTING_NODE,
      EXTR_BAD_ANGLES_NUMBER,
      EXTR_CANT_GET_TANGENT
      };

    ListOfGroups ExtrusionAlongPathX(in long_array        IDsOfElements,
				     in SMESH_IDSource    Path,
				     in long              NodeStart,
				     in boolean           HasAngles,
				     in double_array      Angles,
				     in boolean           LinearVariation,
				     in boolean           HasRefPoint,
				     in PointStruct       RefPoint,
				     in boolean           MakeGroups,
				     in ElementType       ElemType,
				     out Extrusion_Error  Error);

    ListOfGroups ExtrusionAlongPathObjX(in SMESH_IDSource    theObject,
					in SMESH_IDSource    Path,
					in long              NodeStart,
					in boolean           HasAngles,
					in double_array      Angles,
					in boolean           LinearVariation,
					in boolean           HasRefPoint,
					in PointStruct       RefPoint,
					in boolean           MakeGroups,
					in ElementType       ElemType,
					out Extrusion_Error  Error);

    Extrusion_Error ExtrusionAlongPath(in long_array        IDsOfElements,
				       in SMESH_Mesh        PathMesh,
				       in GEOM::GEOM_Object PathShape,
				       in long              NodeStart,
				       in boolean           HasAngles,
				       in double_array      Angles,
				       in boolean           HasRefPoint,
				       in PointStruct       RefPoint);
    ListOfGroups ExtrusionAlongPathMakeGroups(in long_array        IDsOfElements,
                                              in SMESH_Mesh        PathMesh,
                                              in GEOM::GEOM_Object PathShape,
                                              in long              NodeStart,
                                              in boolean           HasAngles,
                                              in double_array      Angles,
                                              in boolean           HasRefPoint,
                                              in PointStruct       RefPoint,
                                              out Extrusion_Error  Error);

    Extrusion_Error ExtrusionAlongPathObject(in SMESH_IDSource    theObject,
					     in SMESH_Mesh        PathMesh,
					     in GEOM::GEOM_Object PathShape,
					     in long              NodeStart,
					     in boolean           HasAngles,
					     in double_array      Angles,
					     in boolean           HasRefPoint,
					     in PointStruct       RefPoint);
    ListOfGroups ExtrusionAlongPathObjectMakeGroups(in SMESH_IDSource    theObject,
                                                    in SMESH_Mesh        PathMesh,
                                                    in GEOM::GEOM_Object PathShape,
                                                    in long              NodeStart,
                                                    in boolean           HasAngles,
                                                    in double_array      Angles,
                                                    in boolean           HasRefPoint,
                                                    in PointStruct       RefPoint,
                                                    out Extrusion_Error  Error);

    Extrusion_Error ExtrusionAlongPathObject1D(in SMESH_IDSource    theObject,
					       in SMESH_Mesh        PathMesh,
					       in GEOM::GEOM_Object PathShape,
					       in long              NodeStart,
					       in boolean           HasAngles,
					       in double_array      Angles,
					       in boolean           HasRefPoint,
					       in PointStruct       RefPoint);
    ListOfGroups ExtrusionAlongPathObject1DMakeGroups(in SMESH_IDSource    theObject,
						      in SMESH_Mesh        PathMesh,
						      in GEOM::GEOM_Object PathShape,
						      in long              NodeStart,
						      in boolean           HasAngles,
						      in double_array      Angles,
						      in boolean           HasRefPoint,
						      in PointStruct       RefPoint,
						      out Extrusion_Error  Error);

    Extrusion_Error ExtrusionAlongPathObject2D(in SMESH_IDSource    theObject,
					       in SMESH_Mesh        PathMesh,
					       in GEOM::GEOM_Object PathShape,
					       in long              NodeStart,
					       in boolean           HasAngles,
					       in double_array      Angles,
					       in boolean           HasRefPoint,
					       in PointStruct       RefPoint);
    ListOfGroups ExtrusionAlongPathObject2DMakeGroups(in SMESH_IDSource    theObject,
						      in SMESH_Mesh        PathMesh,
						      in GEOM::GEOM_Object PathShape,
						      in long              NodeStart,
						      in boolean           HasAngles,
						      in double_array      Angles,
						      in boolean           HasRefPoint,
						      in PointStruct       RefPoint,
						      out Extrusion_Error  Error);

   /*!
    * Compute rotation angles for ExtrusionAlongPath as linear variation
    * of given angles along path steps
    * param PathMesh mesh containing a 1D sub-mesh on the edge, along 
    *                which proceeds the extrusion
    * param PathShape is shape(edge); as the mesh can be complex, the edge 
    *                 is used to define the sub-mesh for the path
    */
    double_array LinearAnglesVariation(in SMESH_Mesh        PathMesh,
                                       in GEOM::GEOM_Object PathShape,
                                       in double_array      Angles);

    enum MirrorType { POINT, AXIS, PLANE };

    void Mirror (in long_array IDsOfElements,
                 in AxisStruct Mirror,
                 in MirrorType Type,
                 in boolean    Copy);
    ListOfGroups MirrorMakeGroups (in long_array IDsOfElements,
                                   in AxisStruct Mirror,
                                   in MirrorType Type);
    SMESH_Mesh MirrorMakeMesh (in long_array IDsOfElements,
                               in AxisStruct Mirror,
                               in MirrorType Type,
                               in boolean    CopyGroups,
                               in string     MeshName);

    void MirrorObject (in SMESH_IDSource theObject,
		       in AxisStruct     Mirror,
		       in MirrorType     Type,
		       in boolean        Copy);
    ListOfGroups MirrorObjectMakeGroups (in SMESH_IDSource theObject,
                                         in AxisStruct     Mirror,
                                         in MirrorType     Type);
    SMESH_Mesh MirrorObjectMakeMesh (in SMESH_IDSource theObject,
                                     in AxisStruct     Mirror,
                                     in MirrorType     Type,
                                     in boolean        CopyGroups,
                                     in string         MeshName);

    void Translate (in long_array IDsOfElements,
                    in DirStruct  Vector,
                    in boolean    Copy);
    ListOfGroups TranslateMakeGroups (in long_array IDsOfElements,
                                      in DirStruct  Vector);
    SMESH_Mesh TranslateMakeMesh (in long_array IDsOfElements,
                                  in DirStruct  Vector,
                                  in boolean    CopyGroups,
                                  in string     MeshName);

    void TranslateObject (in SMESH_IDSource theObject,
			  in DirStruct      Vector,
			  in boolean        Copy);
    ListOfGroups TranslateObjectMakeGroups (in SMESH_IDSource theObject,
                                            in DirStruct      Vector);
    SMESH_Mesh TranslateObjectMakeMesh (in SMESH_IDSource theObject,
                                        in DirStruct      Vector,
                                        in boolean        CopyGroups,
                                        in string         MeshName);

    void Scale (in SMESH_IDSource theObject,
                in PointStruct    thePoint,
                in double_array   theScaleFact,
                in boolean        Copy);
    ListOfGroups ScaleMakeGroups (in SMESH_IDSource theObject,
                                  in PointStruct    thePoint,
                                  in double_array   theScaleFact);
    SMESH_Mesh ScaleMakeMesh (in SMESH_IDSource theObject,
                              in PointStruct    thePoint,
                              in double_array   theScaleFact,
                              in boolean        CopyGroups,
                              in string         MeshName);

    void Rotate (in long_array IDsOfElements,
                 in AxisStruct Axis,
                 in double     AngleInRadians,
                 in boolean    Copy);
    ListOfGroups RotateMakeGroups (in long_array IDsOfElements,
                                   in AxisStruct Axis,
                                   in double     AngleInRadians);
    SMESH_Mesh RotateMakeMesh (in long_array IDsOfElements,
                               in AxisStruct Axis,
                               in double     AngleInRadians,
                               in boolean    CopyGroups,
                               in string     MeshName);

    void RotateObject (in SMESH_IDSource theObject,
		       in AxisStruct     Axis,
		       in double         AngleInRadians,
		       in boolean        Copy);
    ListOfGroups RotateObjectMakeGroups (in SMESH_IDSource theObject,
                                         in AxisStruct     Axis,
                                         in double         AngleInRadians);
    SMESH_Mesh RotateObjectMakeMesh (in SMESH_IDSource theObject,
                                     in AxisStruct     Axis,
                                     in double         AngleInRadians,
                                     in boolean        CopyGroups,
                                     in string         MeshName);

    void FindCoincidentNodes (in  double              Tolerance,
                              out array_of_long_array GroupsOfNodes);

    void FindCoincidentNodesOnPart (in  SMESH_IDSource      SubMeshOrGroup,
				    in  double              Tolerance,
				    out array_of_long_array GroupsOfNodes);

    void MergeNodes (in array_of_long_array GroupsOfNodes);

    /*!
     * \brief Find elements built on the same nodes.
     * \param MeshOrSubMeshOrGroup Mesh or SubMesh, or Group of elements for searching.
     * \return List of groups of equal elements.
     */
    void FindEqualElements (in  SMESH_IDSource      MeshOrSubMeshOrGroup,
			    out array_of_long_array GroupsOfElementsID);

    /*!
     * \brief Merge elements in each given group.
     * \param GroupsOfElementsID Groups of elements for merging.
     */
    void MergeElements(in array_of_long_array GroupsOfElementsID);

    /*!
     * \brief Merge equal elements in the whole mesh.
     */
    void MergeEqualElements();
    
    /*!
     * If the given ID is a valid node ID (nodeID > 0), just move this node, else
     * move the node closest to the point to point's location and return ID of the node
     */
    long MoveClosestNodeToPoint(in double x, in double y, in double z, in long nodeID);

    /*!
     * Return ID of node closest to a given point
     */
    long FindNodeClosestTo(in double x, in double y, in double z);

    /*!
     * Return elements of given type where the given point is IN or ON.
     *
     * 'ALL' type means elements of any type excluding nodes and 0D elements
     */
    long_array FindElementsByPoint(in double x, in double y, in double z, in ElementType type);

    /*!
     * Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
     * TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
     */
    short GetPointState(in double x, in double y, in double z);

    enum Sew_Error {
      SEW_OK,
      SEW_BORDER1_NOT_FOUND,
      SEW_BORDER2_NOT_FOUND,
      SEW_BOTH_BORDERS_NOT_FOUND,
      SEW_BAD_SIDE_NODES,
      SEW_VOLUMES_TO_SPLIT,
      // for SewSideElements() only:
      SEW_DIFF_NB_OF_ELEMENTS,
      SEW_TOPO_DIFF_SETS_OF_ELEMENTS,
      SEW_BAD_SIDE1_NODES,
      SEW_BAD_SIDE2_NODES
      };

    Sew_Error SewFreeBorders (in long FirstNodeID1,
                              in long SecondNodeID1,
                              in long LastNodeID1,
                              in long FirstNodeID2,
                              in long SecondNodeID2,
                              in long LastNodeID2,
			      in boolean CreatePolygons,
			      in boolean CreatePolyedrs);

    Sew_Error SewConformFreeBorders (in long FirstNodeID1,
                                     in long SecondNodeID1,
                                     in long LastNodeID1,
                                     in long FirstNodeID2,
                                     in long SecondNodeID2);

    Sew_Error SewBorderToSide (in long FirstNodeIDOnFreeBorder,
                               in long SecondNodeIDOnFreeBorder,
                               in long LastNodeIDOnFreeBorder,
                               in long FirstNodeIDOnSide,
                               in long LastNodeIDOnSide,
			       in boolean CreatePolygons,
			       in boolean CreatePolyedrs);

    Sew_Error SewSideElements (in long_array IDsOfSide1Elements,
                               in long_array IDsOfSide2Elements,
                               in long       NodeID1OfSide1ToMerge,
                               in long       NodeID1OfSide2ToMerge,
                               in long       NodeID2OfSide1ToMerge,
                               in long       NodeID2OfSide2ToMerge);

   /*!
    * Set new nodes for given element.
    * If number of nodes is not corresponded to type of
    * element - returns false
    */
    boolean ChangeElemNodes(in long ide, in long_array newIDs);

   /*!
    * Return data of mesh edition preview which is computed provided 
    * that the editor was obtained trough SMESH_Mesh::GetMeshEditPreviewer()
    */
    MeshPreviewStruct GetPreviewData();

   /*!
    * If during last operation of MeshEditor some nodes were
    * created this method returns list of it's IDs, if new nodes
    * not creared - returns empty list
    */
    long_array GetLastCreatedNodes();

   /*!
    * If during last operation of MeshEditor some elements were
    * created this method returns list of it's IDs, if new elements
    * not creared - returns empty list
    */
    long_array GetLastCreatedElems();

    /*!
     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
     * \param theNodes - identifiers of nodes to be doubled
     * \param theModifiedElems - identifiers of elements to be updated by the new (doubled) 
     *        nodes. If list of element identifiers is empty then nodes are doubled but 
     *        they not assigned to elements
     *        \return TRUE if operation has been completed successfully, FALSE otherwise
     * \sa DoubleNode(), DoubleNodeGroup(), DoubleNodeGroups()
    */
    boolean DoubleNodes( in long_array theNodes, in long_array theModifiedElems ); 

    /*!
    * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
    * This method provided for convenience works as DoubleNodes() described above.
    * \param theNodeId - identifier of node to be doubled.
    * \param theModifiedElems - identifiers of elements to be updated.
    * \return TRUE if operation has been completed successfully, FALSE otherwise
    * \sa DoubleNodes(), DoubleNodeGroup(), DoubleNodeGroups()
    */
    boolean DoubleNode( in long theNodeId, in long_array theModifiedElems ); 

    /*!
    * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
    * This method provided for convenience works as DoubleNodes() described above.
    * \param theNodes - group of nodes to be doubled.
    * \param theModifiedElems - group of elements to be updated.
    * \return TRUE if operation has been completed successfully, FALSE otherwise
    * \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups()
    */
    boolean DoubleNodeGroup( in SMESH_GroupBase theNodes, 
                             in SMESH_GroupBase theModifiedElems );

    /*!
    \brief Creates a hole in a mesh by doubling the nodes of some particular elements
    This method provided for convenience works as DoubleNodes() described above.
    \param theNodes - list of groups of nodes to be doubled
    \param theModifiedElems - list of groups of elements to be updated.
    \return TRUE if operation has been completed successfully, FALSE otherwise
    \sa DoubleNode(), DoubleNodeGroup(), DoubleNodes()
    */
    boolean DoubleNodeGroups( in ListOfGroups theNodes, 
                              in ListOfGroups theModifiedElems );
    
    /*!
     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
     * \param theElems - the list of elements (edges or faces) to be replicated
     *        The nodes for duplication could be found from these elements
     * \param theNodesNot - list of nodes to NOT replicate
     * \param theAffectedElems - the list of elements (cells and edges) to which the 
     *        replicated nodes should be associated to.
     * \return TRUE if operation has been completed successfully, FALSE otherwise
     * \sa DoubleNodeGroup(), DoubleNodeGroups()
    */
    boolean DoubleNodeElem( in long_array theElems,
                            in long_array theNodesNot,
                            in long_array theAffectedElems ); 

    /*!
     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
     * \param theElems - the list of elements (edges or faces) to be replicated
     *        The nodes for duplication could be found from these elements
     * \param theNodesNot - list of nodes to NOT replicate
     * \param theShape - shape to detect affected elements (element which geometric center
     *        located on or inside shape).
     *        The replicated nodes should be associated to affected elements.
     * \return TRUE if operation has been completed successfully, FALSE otherwise
     * \sa DoubleNodeGroupInRegion(), DoubleNodeGroupsInRegion()
    */
    boolean DoubleNodeElemInRegion( in long_array theElems,
                                    in long_array theNodesNot,
                                    in GEOM::GEOM_Object theShape );

    /*!
     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
     * This method provided for convenience works as DoubleNodes() described above.
     * \param theElems - group of of elements (edges or faces) to be replicated
     * \param theNodesNot - group of nodes not to replicated
     * \param theAffectedElems - group of elements to which the replicated nodes
     *        should be associated to.
     * \return TRUE if operation has been completed successfully, FALSE otherwise
     * \sa DoubleNodes(), DoubleNodeGroups()
    */
    boolean DoubleNodeElemGroup( in SMESH_GroupBase theElems, 
                                 in SMESH_GroupBase theNodesNot,
                                 in SMESH_GroupBase theAffectedElems );

    /*!
     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
     * This method provided for convenience works as DoubleNodes() described above.
     * \param theElems - group of elements (edges or faces) to be replicated
     * \param theNodesNot - group of nodes not to replicated
     * \param theShape - shape to detect affected elements (element which geometric center
     *        located on or inside shape).
     *        The replicated nodes should be associated to affected elements.
     * \return TRUE if operation has been completed successfully, FALSE otherwise
     * \sa DoubleNodesInRegion(), DoubleNodeGroupsInRegion()
    */
    boolean DoubleNodeElemGroupInRegion( in SMESH_GroupBase theElems, 
                                     in SMESH_GroupBase theNodesNot,
                                     in GEOM::GEOM_Object theShape );

    /*!
     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
     * This method provided for convenience works as DoubleNodes() described above.
     * \param theElems - list of groups of elements (edges or faces) to be replicated
     * \param theNodesNot - list of groups of nodes not to replicated
     * \param theAffectedElems - group of elements to which the replicated nodes
     *        should be associated to.
     * \return TRUE if operation has been completed successfully, FALSE otherwise
     * \sa DoubleNodeGroup(), DoubleNodes()
    */
    boolean DoubleNodeElemGroups( in ListOfGroups theElems,
                                  in ListOfGroups theNodesNot,
                                  in ListOfGroups theAffectedElems );

    /*!
     * \brief Creates a hole in a mesh by doubling the nodes of some particular elements
     * This method provided for convenience works as DoubleNodes() described above.
     * \param theElems - list of groups of elements (edges or faces) to be replicated
     * \param theNodesNot - list of groups of nodes not to replicated
     * \param theShape - shape to detect affected elements (element which geometric center
     *        located on or inside shape).
     *        The replicated nodes should be associated to affected elements.
     * \return TRUE if operation has been completed successfully, FALSE otherwise
     * \sa DoubleNodeGroupInRegion(), DoubleNodesInRegion()
    */
    boolean DoubleNodeElemGroupsInRegion( in ListOfGroups theElems,
                                          in ListOfGroups theNodesNot,
                                          in GEOM::GEOM_Object theShape );

    /*!
     * \brief Generated skin mesh (containing 2D cells) from 3D mesh
     * The created 2D mesh elements based on nodes of free faces of boundary volumes
     * \return TRUE if operation has been completed successfully, FALSE otherwise
     */
    boolean Make2DMeshFrom3D();

  };
};

#endif
