//  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_Filter.idl
//  Author : Alexey Petrov, OCC
//
#ifndef _SMESH_FILTER_IDL_
#define _SMESH_FILTER_IDL_

#include "SALOME_Exception.idl"
#include "SALOME_GenericObj.idl"
#include "GEOM_Gen.idl"
#include "SMESH_Mesh.idl"

module SMESH
{

  /*!
  * Enumeration of functor types
  */
  enum FunctorType
  {
    FT_AspectRatio,
    FT_AspectRatio3D,
    FT_Warping,   
    FT_MinimumAngle,
    FT_Taper,       
    FT_Skew,         
    FT_Area,          
    FT_Volume3D,          
    FT_FreeBorders,
    FT_FreeEdges,
    FT_FreeNodes,
    FT_FreeFaces,
    FT_MultiConnection,
    FT_MultiConnection2D,
    FT_Length,
    FT_Length2D,
    FT_BelongToGeom,
    FT_BelongToPlane,
    FT_BelongToCylinder,
    FT_BelongToGenSurface,
    FT_LyingOnGeom,
    FT_RangeOfIds,
    FT_BadOrientedVolume,
    FT_LinearOrQuadratic,
    FT_GroupColor,
    FT_ElemGeomType,
    FT_LessThan,
    FT_MoreThan,
    FT_EqualTo,
    FT_LogicalNOT,
    FT_LogicalAND,
    FT_LogicalOR,
    FT_Undefined
  };

  /*!
  * Base interface for all functors ( i.e. numerical functors and predicates )
  */
  interface Functor: SALOME::GenericObj
  {
    void            SetMesh( in SMESH_Mesh theMesh );
    FunctorType     GetFunctorType();
    ElementType     GetElementType();
  };



  /*!
  * Numerical functors are intended for calculating value by Id of mesh entity
  */
  interface NumericalFunctor: Functor
  {
    double GetValue( in long theElementId );

    /*!
    * Set precision for calculation. It is a position after point which is
    * used to functor value after calculation.
    */
    void   SetPrecision( in long thePrecision );
    long   GetPrecision();
  };
  interface MinimumAngle    : NumericalFunctor{};
  interface AspectRatio     : NumericalFunctor{};
  interface AspectRatio3D   : NumericalFunctor{};
  interface Warping         : NumericalFunctor{};
  interface Taper           : NumericalFunctor{};
  interface Skew            : NumericalFunctor{};
  interface Area            : NumericalFunctor{};
  interface Volume3D        : NumericalFunctor{};
  interface Length          : NumericalFunctor{};
  interface Length2D        : NumericalFunctor
  {
    struct Value
    {
      double myLength;
      long myPnt1, myPnt2;
    };
    typedef sequence<Value> Values;
    Values GetValues();
  };
  interface MultiConnection   : NumericalFunctor{};
  interface MultiConnection2D : NumericalFunctor
  {
    struct Value
    {
      long myNbConnects;
      long myPnt1, myPnt2;
    };
    
    typedef sequence<Value> Values;
    Values GetValues();
  };
  
  /*!
  * Predicates are intended for verification of criteria,
  *            must return bool value by mesh id
  */
  interface Predicate: Functor
  {
    boolean IsSatisfy( in long thEntityId );
  };

  /*!
   * Logical functor (predicate) "Bad Oriented Volume".
   * Verify whether a mesh volume is incorrectly oriented from
   * the point of view of MED convention
   */
  interface BadOrientedVolume: Predicate {};

  /*!
   * Logical functor (predicate) "Belong To Geometry".
   * Verify whether mesh element or node belong to pointed Geom Object
   */
  interface BelongToGeom: Predicate
  {
    void SetGeom( in GEOM::GEOM_Object theGeom );
    void SetElementType( in ElementType theType );

    /*! The tolerance is used only if there is no submesh on the shape
     */
    void    SetTolerance( in double theToler );
    double  GetTolerance();

    void   SetShapeName( in string theName );
    void   SetShape( in string theID, in string theName );
    string GetShapeName();
    string GetShapeID();
  };

  /*!
  * Logical functor (predicate) "Belong To Surface".
  * Base interface for "belong to plane" and "belong to cylinder"
  * and "Belong To Generic Surface" interfaces
  */
  interface BelongToSurface: Predicate
  {
    void    SetTolerance( in double theToler );
    double  GetTolerance();
    void    SetShapeName( in string theName, in ElementType theType );
    void    SetShape( in string theID, in string theName, in ElementType theType );
    string  GetShapeName();
    string  GetShapeID();
    /*!
    * Limit surface extent to bounding box of boundaries (edges)
    * in surface parametric space. Boundaries are ignored by default
    */
    void    SetUseBoundaries( in boolean theUseBndRestrictions );
    boolean GetUseBoundaries();
  };

  /*!
  * Logical functor (predicate) "Belong To Plane".
  * Verify whether mesh element lie on pointed Geom planar object
  */
  interface BelongToPlane: BelongToSurface
  {
    void   SetPlane( in GEOM::GEOM_Object theGeom, in ElementType theType );
  };

  /*!
  * Logical functor (predicate) "Belong To Cylinder".
  * Verify whether mesh element lie on pointed Geom cylindrical object
  */
  interface BelongToCylinder: BelongToSurface
  {
    void   SetCylinder( in GEOM::GEOM_Object theGeom, in ElementType theType );
  };

  /*!
  * Logical functor (predicate) "Belong To Generic Surface".
  * Verify whether mesh element lie in pointed Geom cylindrical object
  */
  interface BelongToGenSurface: BelongToSurface
  {
    void   SetSurface( in GEOM::GEOM_Object theGeom, in ElementType theType );
  };

  /*!
  * Logical functor (predicate) "Lying On Geometry".
  * Verify whether mesh element or node lying or partially lying on the pointed Geom Object
  */
  interface LyingOnGeom: Predicate
  {
    void SetGeom( in GEOM::GEOM_Object theGeom );
    void SetElementType( in ElementType theType );

    /*! The tolerance is used only if there is no submesh on the shape
     */
    void    SetTolerance( in double theToler );
    double  GetTolerance();

    void   SetShapeName( in string theName );
    void   SetShape( in string theID, in string theName );
    string GetShapeName();    
    string GetShapeID(); 
  };
 
  /*!
  * Logical functor (predicate) "Free borders".
  * Verify whether 1D mesh element is free ( i.e. connected to one face only )
  */
  interface FreeBorders: Predicate{};

  /*!
  * Logical functor (predicate) "Free edges".
  * Verify whether 2D mesh element has free edges( i.e. edges connected to one face only )
  */
  interface FreeEdges: Predicate
  {
    struct Border
    {
      long myElemId;
      long myPnt1, myPnt2;
    };
    typedef sequence<Border> Borders;
    Borders GetBorders();
  };

  /*!
  * Logical functor (predicate) "Free nodes".
  * Verify whether mesh has free nodes( i.e. nodes are not connected to any element )
  */
  interface FreeNodes: Predicate{};
 
  /*!
  * Logical functor (predicate) "Free faces".
  * Verify whether 2D mesh element is free ( i.e. connected to one volume only )
  */
  interface FreeFaces: Predicate{};

  /*!
  * Abstract logical functor (predicate) "RangeOfIds".
  * Verify whether an Entity Id belongs to defined sequence of id's
  */
  interface RangeOfIds: Predicate
  {
    void            SetRange( in long_array theIds );
    boolean         SetRangeStr( in string theRange );
    string          GetRangeStr();

    void            SetElementType( in ElementType theType );
  };

  /*!
  * Comparator. Predicate for compare value calculated
  *             by numerical functor with threshold value
  */
  interface Comparator: Predicate
  {
    void    SetMargin( in double theValue );
    void    SetNumFunctor( in NumericalFunctor theFunct );
    double  GetMargin();
  };
  interface LessThan: Comparator{};
  interface MoreThan: Comparator{};
  interface EqualTo : Comparator
  {
    void    SetTolerance( in double theToler );
    double  GetTolerance();
  };

  /*!
  * Logical predicates are intended for compose predicates using boolean operations
  */
  interface Logical: Predicate{};

  interface LogicalNOT: Logical
  {
    void SetPredicate(in Predicate thePredicate);
  };

  interface LogicalBinary: Logical
{
    void SetPredicate1( in Predicate thePredicate );
    void SetPredicate2( in Predicate thePredicate );
  };

  interface LogicalAND: LogicalBinary{};
  interface LogicalOR : LogicalBinary{};

  /*!
   * Logical functor (predicate) "Is element Linear or Quadratic".
   * Verify whether a mesh element is linear
   */
  interface LinearOrQuadratic: Predicate {
    void            SetElementType( in ElementType theType );
  };

  /*!
  * Functor "Group Color"
  * Returns color of group to which mesh element belongs to
  */
  interface GroupColor : Predicate{
    void            SetElementType( in ElementType theType );
    void            SetColorStr( in string theColor );
    string          GetColorStr();
  };

  /*!
  * Functor "Element geometry type"
  * Returns is element has indicated geometry type
  */
  interface ElemGeomType : Predicate{
    void            SetElementType ( in ElementType  theType );
    void            SetGeometryType( in GeometryType theType );
  };

  /*!
  *  Filter
  */
  interface Filter: SALOME::GenericObj, SMESH_IDSource
  {
    /*!
    * Structure containing information about one criterion
    *   Type          - FT_Taper, FT_Skew ...
    *   Compare       - FT_LessThan, FT_MoreThan, FT_EqualTo
    *   Threshold     - threshold value
    *   UnaryOp       - unary logical operation: FT_LogicalNOT or FT_Undefined
    *   BinaryOp      - binary logical operation FT_LogicalAND, FT_LogicalOR or
    *                   (FT_Undefined must be for the last criterion)
    *   ThresholdStr  - Threshold value defined as string. Used for:
    *                   1. Diaposon of identifiers. Example: "1,2,3,5-10,12,27-29"
    *                   2. BelongToGeom predicate for storing name of shape
    *                   3. GroupColor predicate for storing group color "0.2;0;0.5"
    *   ThresholdID   - One more threshold value defined as string. Used for:
    *                   1. BelongToGeom predicate for storing id of shape
    *   Tolerance     - Tolerance is used for comparators (EqualTo comparision) and for
    *                   "Belong to plane" and "Belong to cylinder" predicates
    *   TypeOfElement - type of element SMESH::NODE, SMESH::FACE (used by BelongToGeom predicate only)
    *   Precision     - Precision of numerical functors
    */
    struct Criterion
    {
      long        Type;
      long        Compare;
      double      Threshold;
      string      ThresholdStr;
      string      ThresholdID;
      long        UnaryOp;
      long        BinaryOp;
      double      Tolerance;
      ElementType TypeOfElement;
      long        Precision;
    };

    typedef sequence<Criterion> Criteria;

    void          SetPredicate( in Predicate thePredicate );
    void          SetMesh( in SMESH_Mesh theMesh );

    long_array    GetElementsId( in SMESH_Mesh theMesh );
    ElementType   GetElementType();
    Predicate     GetPredicate();

    boolean       GetCriteria( out Criteria theCriteria );
    boolean       SetCriteria( in Criteria theCriteria );
  };


  /*!
  *  Interface for working with library of filters
  */
  interface FilterLibrary : SALOME::GenericObj
  {
    /*!
    *  Copy filter from library by name (new filter is created)
    */
    Filter        Copy( in string theFilterName );

    /*!
    * Methods for editing library
    */
    boolean       Add     ( in string theFilterName, in Filter theFilter );
    boolean       AddEmpty( in string theFilterName, in ElementType theType ); // add empty filter
    boolean       Delete  ( in string theFilterName );
    boolean       Replace ( in string theFilterName, in string theNewName, in Filter theFilter );

    /*!
    *  Save library on disk
    */
    boolean       Save();
    boolean       SaveAs( in string aFileName );

    /*!
    * Query methods
    */
    boolean       IsPresent( in string aFilterName );
    long          NbFilters( in ElementType aType );
    string_array  GetNames( in ElementType aType );
    string_array  GetAllNames();
    void          SetFileName( in string aFilterName );
    string        GetFileName();
  };


  /*!
  * Interface of Filter manager
  */
  interface FilterManager: SALOME::GenericObj
  {
    /*!
    *  Create numerical functors
    */
    MinimumAngle      CreateMinimumAngle();
    AspectRatio       CreateAspectRatio();
    AspectRatio3D     CreateAspectRatio3D();
    Warping           CreateWarping();
    Taper             CreateTaper();
    Skew              CreateSkew();
    Area              CreateArea();
    Volume3D          CreateVolume3D();
    Length            CreateLength();
    Length2D          CreateLength2D();
    MultiConnection   CreateMultiConnection();
    MultiConnection2D CreateMultiConnection2D();

    /*!
    *  Create logical functors ( predicates )
    */
    BelongToGeom      CreateBelongToGeom();
    BelongToPlane     CreateBelongToPlane();
    BelongToCylinder  CreateBelongToCylinder();
    BelongToGenSurface CreateBelongToGenSurface();

    LyingOnGeom       CreateLyingOnGeom();

    FreeBorders       CreateFreeBorders();
    FreeEdges         CreateFreeEdges();
    FreeNodes         CreateFreeNodes();
    FreeFaces         CreateFreeFaces();

    RangeOfIds        CreateRangeOfIds();

    BadOrientedVolume CreateBadOrientedVolume();
    LinearOrQuadratic CreateLinearOrQuadratic();

    GroupColor        CreateGroupColor();
    ElemGeomType      CreateElemGeomType();

    /*!
    *  Create comparators ( predicates )
    */
    LessThan          CreateLessThan();
    MoreThan          CreateMoreThan();
    EqualTo           CreateEqualTo();

    /*!
    *  Create boolean operations ( predicates )
    */
    LogicalNOT        CreateLogicalNOT();
    LogicalAND        CreateLogicalAND();
    LogicalOR         CreateLogicalOR();

    /*!
    *  Create filter
    */
    Filter            CreateFilter();

    /*!
    *  Load filter library. If libary does not exist it is created
    */
    FilterLibrary     LoadLibrary( in string aFileName );

    /*!
    *  Create new library
    */
    FilterLibrary     CreateLibrary();

    /*!
    *  Delete library
    */
    boolean           DeleteLibrary( in string aFileName );
  };
};


#endif
