]> SALOME platform Git repositories - modules/smesh.git/commitdiff
Salome HOME
Merge imn/IMACS branch into imn/IMACS_8_3_0 imn/IMACS_8_3_0
authorrnv <rnv@opencascade.com>
Thu, 23 Nov 2017 15:52:07 +0000 (18:52 +0300)
committerrnv <rnv@opencascade.com>
Fri, 24 Nov 2017 13:40:48 +0000 (16:40 +0300)
1  2 
src/OBJECT/SMESH_Actor.cxx
src/OBJECT/SMESH_ActorDef.h
src/SMESHUtils/SMESH_MeshAlgos.cxx
src/SMESH_SWIG_WITHIHM/libSMESH_Swig.cxx
src/SMESH_SWIG_WITHIHM/libSMESH_Swig.h
src/SMESH_SWIG_WITHIHM/libSMESH_Swig.i

index 43e4bca326bbb20bca69a07c2da16599f7bf9e79,7159bc19763bbb3b6ae0456b6bcacf2f69dc1869..70b24aa43e63a285bcb2136c6be8c069c2d43b16
@@@ -126,7 -126,6 +126,7 @@@ SMESH_ActorDef::SMESH_ActorDef(
  
    myIsPointsVisible = false;
    myIsEntityModeCache = false;
 +  myRepresentationCache = 0;
  
    myHighlightActor = SMESH_SVTKActor::New();
    myHighlightActor->Delete(); // vtkSmartPointer!
@@@ -1430,6 -1429,10 +1430,10 @@@ double* SMESH_ActorDef::GetNodeCoord(in
    return myPickableActor->GetNodeCoord(theObjID);
  }
  
+ int SMESH_ActorDef::GetNodeVtkId(int theObjID)
+ {
+   return myPickableActor->GetNodeVtkId(theObjID);
+ }
  
  int SMESH_ActorDef::GetElemObjId(int theVtkID)
  {
@@@ -1471,8 -1474,8 +1475,8 @@@ void SMESH_ActorDef::SetVisibility(int 
  
    myScalarBarActor->VisibilityOff();
  
 -  if(GetVisibility()){
 -    if(theIsUpdateRepersentation)
 +  if ( GetVisibility() ) {
 +    if ( theIsUpdateRepersentation )
        SetRepresentation(GetRepresentation());
  
      if(myControlMode != eNone) {
  
  void SMESH_ActorDef::SetEntityMode(unsigned int theMode)
  {
 -  myEntityState = eAllEntity;
 +  unsigned int anObjectEntities = eAllEntity; // entities present in my object
  
    if(!myVisualObj->GetNbEntities(SMDSAbs_0DElement)) {
 -    myEntityState &= ~e0DElements;
 +    anObjectEntities &= ~e0DElements;
      theMode &= ~e0DElements;
    }
  
    if(!myVisualObj->GetNbEntities(SMDSAbs_Ball)) {
 -    myEntityState &= ~eBallElem;
 +    anObjectEntities &= ~eBallElem;
      theMode &= ~eBallElem;
    }
  
    if(!myVisualObj->GetNbEntities(SMDSAbs_Edge)) {
 -    myEntityState &= ~eEdges;
 +    anObjectEntities &= ~eEdges;
      theMode &= ~eEdges;
    }
  
    if(!myVisualObj->GetNbEntities(SMDSAbs_Face)) {
 -    myEntityState &= ~eFaces;
 +    anObjectEntities &= ~eFaces;
      theMode &= ~eFaces;
    }
  
    if(!myVisualObj->GetNbEntities(SMDSAbs_Volume)) {
 -    myEntityState &= ~eVolumes;
 +    anObjectEntities &= ~eVolumes;
      theMode &= ~eVolumes;
    }
  
        theMode |= eVolumes;
    }
  
 -  myBaseActor->myGeomFilter->SetInside(myEntityMode != myEntityState);
 +  myBaseActor->myGeomFilter->SetInside(myEntityMode != anObjectEntities);
  
 -  myEntityMode = theMode;
 -
 -  VTKViewer_ExtractUnstructuredGrid* aFilter = myBaseActor->GetExtractUnstructuredGrid();
 -  aFilter->ClearRegisteredCellsWithType();
 -  VTKViewer_ExtractUnstructuredGrid* aHightFilter = myHighlitableActor->GetExtractUnstructuredGrid();
 -  aHightFilter->ClearRegisteredCellsWithType();
 -
 -  bool isPassAll =
 -    (( myEntityMode & e0DElements || myVisualObj->GetNbEntities(SMDSAbs_0DElement) == 0 ) &&
 -     ( myEntityMode & eBallElem   || myVisualObj->GetNbEntities(SMDSAbs_Ball)      == 0 ) &&
 -     ( myEntityMode & eEdges      || myVisualObj->GetNbEntities(SMDSAbs_Edge)      == 0 ) &&
 -     ( myEntityMode & eFaces      || myVisualObj->GetNbEntities(SMDSAbs_Face)      == 0 ) &&
 -     ( myEntityMode & eVolumes    || myVisualObj->GetNbEntities(SMDSAbs_Volume)    == 0 ));
 -  if ( isPassAll && myEntityMode )
 +  if ( anObjectEntities == 0 && myRepresentation != ePoint ) // no elements, show nodes
    {
 -    aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::ePassAll);
 -    aHightFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::ePassAll);
 +    myRepresentationCache = GetRepresentation();
 +    SetRepresentation( ePoint );
    }
 -  else
 +
 +  if ( myEntityMode != theMode )
    {
 -    aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
 -    aHightFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
 +    myEntityMode = theMode; // entities to show
  
 -    if (myEntityMode & e0DElements) {
 -      aFilter->RegisterCellsWithType(VTK_VERTEX);
 -      aHightFilter->RegisterCellsWithType(VTK_VERTEX);
 -    }
 +    // Set cell types to extract
 +
 +    VTKViewer_ExtractUnstructuredGrid*    aFilter = myBaseActor->GetExtractUnstructuredGrid();
 +    VTKViewer_ExtractUnstructuredGrid* aHltFilter = myHighlitableActor->GetExtractUnstructuredGrid();
 +    aFilter->ClearRegisteredCellsWithType();
 +    aHltFilter->ClearRegisteredCellsWithType();
  
 -    if (myEntityMode & eBallElem) {
 -      aFilter->RegisterCellsWithType(VTK_POLY_VERTEX);
 +    bool isPassAll = ( myEntityMode == anObjectEntities && myEntityMode );
 +    if ( isPassAll )
 +    {
 +      aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::ePassAll);
 +      aHltFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::ePassAll);
      }
 +    else
 +    {
 +      aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
 +      aHltFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
  
 -    if (myEntityMode & eEdges) {
 -      aFilter->RegisterCellsWithType(VTK_LINE);
 -      aFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE);
 +      if (myEntityMode & e0DElements) {
 +        aFilter->RegisterCellsWithType(VTK_VERTEX);
 +        aHltFilter->RegisterCellsWithType(VTK_VERTEX);
 +      }
  
 -      aHightFilter->RegisterCellsWithType(VTK_LINE);
 -      aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE);
 -    }
 +      if (myEntityMode & eBallElem) {
 +        aFilter->RegisterCellsWithType(VTK_POLY_VERTEX);
 +      }
  
 -    if (myEntityMode & eFaces) {
 -      aFilter->RegisterCellsWithType(VTK_TRIANGLE);
 -      aFilter->RegisterCellsWithType(VTK_QUAD);
 -      aFilter->RegisterCellsWithType(VTK_POLYGON);
 -      aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
 -      aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
 -      aFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON);
 -      aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
 -      aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE);
 -
 -      aHightFilter->RegisterCellsWithType(VTK_TRIANGLE);
 -      aHightFilter->RegisterCellsWithType(VTK_QUAD);
 -      aHightFilter->RegisterCellsWithType(VTK_POLYGON);
 -      aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
 -      aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
 -      aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON);
 -      aHightFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
 -      aHightFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE);
 -    }
 +      if (myEntityMode & eEdges) {
 +        aFilter->RegisterCellsWithType(VTK_LINE);
 +        aFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE);
  
 -    if (myEntityMode & eVolumes) {
 -      aFilter->RegisterCellsWithType(VTK_TETRA);
 -      aFilter->RegisterCellsWithType(VTK_VOXEL);
 -      aFilter->RegisterCellsWithType(VTK_HEXAHEDRON);
 -      aFilter->RegisterCellsWithType(VTK_WEDGE);
 -      aFilter->RegisterCellsWithType(VTK_PYRAMID);
 -      aFilter->RegisterCellsWithType(VTK_HEXAGONAL_PRISM);
 -      aFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA);
 -      aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
 -      aFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON);
 -      aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
 -      aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
 -      aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
 -      aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
 -
 -      aHightFilter->RegisterCellsWithType(VTK_TETRA);
 -      aHightFilter->RegisterCellsWithType(VTK_VOXEL);
 -      aHightFilter->RegisterCellsWithType(VTK_HEXAHEDRON);
 -      aHightFilter->RegisterCellsWithType(VTK_WEDGE);
 -      aHightFilter->RegisterCellsWithType(VTK_PYRAMID);
 -      aHightFilter->RegisterCellsWithType(VTK_HEXAGONAL_PRISM);
 -      aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA);
 -      aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
 -      aHightFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON);
 -      aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
 -      aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
 -      aHightFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
 -      aHightFilter->RegisterCellsWithType(VTK_POLYHEDRON);
 +        aHltFilter->RegisterCellsWithType(VTK_LINE);
 +        aHltFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE);
 +      }
 +
 +      if (myEntityMode & eFaces) {
 +        aFilter->RegisterCellsWithType(VTK_TRIANGLE);
 +        aFilter->RegisterCellsWithType(VTK_QUAD);
 +        aFilter->RegisterCellsWithType(VTK_POLYGON);
 +        aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
 +        aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
 +        aFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON);
 +        aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
 +        aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE);
 +
 +        aHltFilter->RegisterCellsWithType(VTK_TRIANGLE);
 +        aHltFilter->RegisterCellsWithType(VTK_QUAD);
 +        aHltFilter->RegisterCellsWithType(VTK_POLYGON);
 +        aHltFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE);
 +        aHltFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD);
 +        aHltFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON);
 +        aHltFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD);
 +        aHltFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE);
 +      }
 +
 +      if (myEntityMode & eVolumes) {
 +        aFilter->RegisterCellsWithType(VTK_TETRA);
 +        aFilter->RegisterCellsWithType(VTK_VOXEL);
 +        aFilter->RegisterCellsWithType(VTK_HEXAHEDRON);
 +        aFilter->RegisterCellsWithType(VTK_WEDGE);
 +        aFilter->RegisterCellsWithType(VTK_PYRAMID);
 +        aFilter->RegisterCellsWithType(VTK_HEXAGONAL_PRISM);
 +        aFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA);
 +        aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
 +        aFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON);
 +        aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
 +        aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
 +        aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
 +        aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
 +
 +        aHltFilter->RegisterCellsWithType(VTK_TETRA);
 +        aHltFilter->RegisterCellsWithType(VTK_VOXEL);
 +        aHltFilter->RegisterCellsWithType(VTK_HEXAHEDRON);
 +        aHltFilter->RegisterCellsWithType(VTK_WEDGE);
 +        aHltFilter->RegisterCellsWithType(VTK_PYRAMID);
 +        aHltFilter->RegisterCellsWithType(VTK_HEXAGONAL_PRISM);
 +        aHltFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA);
 +        aHltFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
 +        aHltFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON);
 +        aHltFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
 +        aHltFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
 +        aHltFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
 +        aHltFilter->RegisterCellsWithType(VTK_POLYHEDRON);
 +      }
      }
 +    if ( GetVisibility() )
 +      aFilter->Update();
 +    if (MYDEBUG) MESSAGE(aFilter->GetOutput()->GetNumberOfCells());
    }
 -  if ( GetVisibility() )
 -    aFilter->Update();
 -  if (MYDEBUG) MESSAGE(aFilter->GetOutput()->GetNumberOfCells());
 -  SetVisibility(GetVisibility(),false);
 +
 +  SetVisibility( GetVisibility(), myRepresentationCache != 0 );
  }
  
  void SMESH_ActorDef::SetRepresentation (int theMode)
    int aNb0Ds     = myVisualObj->GetNbEntities(SMDSAbs_0DElement);
    int aNbBalls   = myVisualObj->GetNbEntities(SMDSAbs_Ball);
  
 +  if ( myRepresentationCache && aNbEdges + aNbFaces + aNbVolumes + aNb0Ds + aNbBalls )
 +  {
 +    theMode = myRepresentationCache;
 +    if ( theMode == eSurface && aNbFaces + aNbVolumes == 0 )
 +      theMode = eEdge;
 +    else
 +      myRepresentationCache = 0;
 +  }
 +
    if (theMode < 0) {
      myRepresentation = eSurface;
      if (!aNbFaces && !aNbVolumes && !aNbBalls && aNbEdges) {
      case eLength:
      case eMultiConnection:
        aProp = aBackProp = my1DProp;
 -      if(myRepresentation != ePoint)
 +      if ( myRepresentation != ePoint )
          aReperesent = SMESH_DeviceActor::eInsideframe;
        break;
      default:;
@@@ -2000,9 -1987,9 +2004,9 @@@ void SMESH_ActorDef::Update(
      SetFacesOriented(myIsFacesOriented);
    }
  
 -  if(myVisualObj->GetEntitiesFlag()) {
 -    myEntityMode |= myVisualObj->GetEntitiesState();
 -  }
 +  // if(myVisualObj->GetEntitiesFlag()) { IPAL53915
 +  //   myEntityMode |= myVisualObj->GetEntitiesState();
 +  // }
  
    SetEntityMode(GetEntityMode());
    SetVisibility(GetVisibility());
index dd8879ec6527b3fd4b6965a7eb33e5b66abd2c73,746b5b76f504599d20e2745bdffddffbc3c61439..3b9d9c68f97a4de811e5531ed78b268ce4ddf815
@@@ -150,6 -150,7 +150,7 @@@ class SMESH_ActorDef : public SMESH_Act
  
    virtual int GetNodeObjId(int theVtkID);
    virtual double* GetNodeCoord(int theObjID);
+   virtual int GetNodeVtkId(int theObjID);
  
    virtual int GetElemObjId(int theVtkID);
    virtual vtkCell* GetElemCell(int theObjID);
    SMESH_DeviceActor* my0DExtActor;
  
    unsigned int myEntityMode;
 -  unsigned int myEntityState;
    unsigned int myEntityModeCache;
 +  int  myRepresentationCache;
    bool myIsEntityModeCache;
    bool myIsPointsVisible;
  
index 1eae5f7818e23d205812d4330a7e8437c34349cb,4bcfc1d97ac42121e6d072fbf0723c15f237efdb..69ba8fb5b70198dbf3f2213e3467b860b699de09
@@@ -35,6 -35,8 +35,8 @@@
  #include "SMDS_VolumeTool.hxx"
  #include "SMESH_OctreeNode.hxx"
  
+ #include <Utils_SALOME_Exception.hxx>
  #include <GC_MakeSegment.hxx>
  #include <GeomAPI_ExtremaCurveCurve.hxx>
  #include <Geom_Line.hxx>
@@@ -228,15 -230,16 +230,16 @@@ namespace // Utils used in SMESH_Elemen
                        SMDSAbs_ElementType  elemType,
                        SMDS_ElemIteratorPtr theElemIt = SMDS_ElemIteratorPtr(),
                        double               tolerance = NodeRadius );
-     void getElementsNearPoint( const gp_Pnt& point, TIDSortedElemSet& foundElems );
-     void getElementsNearLine ( const gp_Ax1& line, TIDSortedElemSet& foundElems);
-     void getElementsInSphere ( const gp_XYZ& center,
-                                const double  radius, TIDSortedElemSet& foundElems);
-     size_t getSize() { return std::max( _size, _elements.size() ); }
-     virtual ~ElementBndBoxTree();
+     void prepare(); // !!!call it before calling the following methods!!!
+     void getElementsNearPoint( const gp_Pnt& point, vector<const SMDS_MeshElement*>& foundElems );
+     void getElementsNearLine ( const gp_Ax1& line,  vector<const SMDS_MeshElement*>& foundElems);
+     void getElementsInSphere ( const gp_XYZ&                    center,
+                                const double                     radius,
+                                vector<const SMDS_MeshElement*>& foundElems);
+     ElementBndBoxTree* getLeafAtPoint( const gp_XYZ& point );
  
    protected:
-     ElementBndBoxTree():_size(0) {}
+     ElementBndBoxTree() {}
      SMESH_Octree* newChild() const { return new ElementBndBoxTree; }
      void          buildChildrenData();
      Bnd_B3d*      buildRootBox();
      struct ElementBox : public Bnd_B3d
      {
        const SMDS_MeshElement* _element;
-       int                     _refCount; // an ElementBox can be included in several tree branches
-       ElementBox(const SMDS_MeshElement* elem, double tolerance);
+       bool                    _isMarked;
+       void init(const SMDS_MeshElement* elem, double tolerance);
      };
      vector< ElementBox* > _elements;
-     size_t                _size;
+     typedef ObjectPool< ElementBox > TElementBoxPool;
+     //!< allocator of ElementBox's and SMESH_TreeLimit
+     struct LimitAndPool : public SMESH_TreeLimit
+     {
+       TElementBoxPool            _elBoPool;
+       std::vector< ElementBox* > _markedElems;
+       LimitAndPool():SMESH_TreeLimit( MaxLevel, /*minSize=*/0. ) {}
+     };
+     LimitAndPool* getLimitAndPool() const
+     {
+       SMESH_TreeLimit* limitAndPool = const_cast< SMESH_TreeLimit* >( myLimit );
+       return static_cast< LimitAndPool* >( limitAndPool );
+     }
    };
  
    //================================================================================
     */
    //================================================================================
  
-   ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, SMDS_ElemIteratorPtr theElemIt, double tolerance)
-     :SMESH_Octree( new SMESH_TreeLimit( MaxLevel, /*minSize=*/0. ))
+   ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh&     mesh,
+                                        SMDSAbs_ElementType  elemType,
+                                        SMDS_ElemIteratorPtr theElemIt,
+                                        double               tolerance)
+     :SMESH_Octree( new LimitAndPool() )
    {
      int nbElems = mesh.GetMeshInfo().NbElements( elemType );
      _elements.reserve( nbElems );
  
+     TElementBoxPool& elBoPool = getLimitAndPool()->_elBoPool;
      SMDS_ElemIteratorPtr elemIt = theElemIt ? theElemIt : mesh.elementsIterator( elemType );
      while ( elemIt->more() )
-       _elements.push_back( new ElementBox( elemIt->next(),tolerance  ));
+     {
+       ElementBox* eb = elBoPool.getNew();
+       eb->init( elemIt->next(), tolerance );
+       _elements.push_back( eb );
+     }
      compute();
    }
  
-   //================================================================================
-   /*!
-    * \brief Destructor
-    */
-   //================================================================================
-   ElementBndBoxTree::~ElementBndBoxTree()
-   {
-     for ( size_t i = 0; i < _elements.size(); ++i )
-       if ( --_elements[i]->_refCount <= 0 )
-         delete _elements[i];
-   }
    //================================================================================
    /*!
     * \brief Return the maximal box
        for (int j = 0; j < 8; j++)
        {
          if ( !_elements[i]->IsOut( *myChildren[j]->getBox() ))
-         {
-           _elements[i]->_refCount++;
            ((ElementBndBoxTree*)myChildren[j])->_elements.push_back( _elements[i]);
-         }
        }
-       _elements[i]->_refCount--;
      }
-     _size = _elements.size();
+     //_size = _elements.size();
      SMESHUtils::FreeVector( _elements ); // = _elements.clear() + free memory
  
      for (int j = 0; j < 8; j++)
        if ((int) child->_elements.size() <= MaxNbElemsInLeaf )
          child->myIsLeaf = true;
  
-       if ( child->_elements.capacity() - child->_elements.size() > 1000 )
+       if ( child->isLeaf() && child->_elements.capacity() > child->_elements.size() )
          SMESHUtils::CompactVector( child->_elements );
      }
    }
  
+   //================================================================================
+   /*!
+    * \brief Un-mark all elements
+    */
+   //================================================================================
+   void ElementBndBoxTree::prepare()
+   {
+     // TElementBoxPool& elBoPool = getElementBoxPool();
+     // for ( size_t i = 0; i < elBoPool.nbElements(); ++i )
+     //   const_cast< ElementBox* >( elBoPool[ i ])->_isMarked = false;
+   }
    //================================================================================
    /*!
     * \brief Return elements which can include the point
     */
    //================================================================================
  
-   void ElementBndBoxTree::getElementsNearPoint( const gp_Pnt&     point,
-                                                 TIDSortedElemSet& foundElems)
+   void ElementBndBoxTree::getElementsNearPoint( const gp_Pnt&                    point,
+                                                 vector<const SMDS_MeshElement*>& foundElems)
    {
      if ( getBox()->IsOut( point.XYZ() ))
        return;
  
      if ( isLeaf() )
      {
+       LimitAndPool* pool = getLimitAndPool();
        for ( size_t i = 0; i < _elements.size(); ++i )
-         if ( !_elements[i]->IsOut( point.XYZ() ))
-           foundElems.insert( _elements[i]->_element );
+         if ( !_elements[i]->IsOut( point.XYZ() ) &&
+              !_elements[i]->_isMarked )
+         {
+           foundElems.push_back( _elements[i]->_element );
+           _elements[i]->_isMarked = true;
+           pool->_markedElems.push_back( _elements[i] );
+         }
      }
      else
      {
        for (int i = 0; i < 8; i++)
          ((ElementBndBoxTree*) myChildren[i])->getElementsNearPoint( point, foundElems );
+       if ( level() == 0 )
+       {
+         LimitAndPool* pool = getLimitAndPool();
+         for ( size_t i = 0; i < pool->_markedElems.size(); ++i )
+           pool->_markedElems[i]->_isMarked = false;
+         pool->_markedElems.clear();
+       }
      }
    }
  
     */
    //================================================================================
  
-   void ElementBndBoxTree::getElementsNearLine( const gp_Ax1&     line,
-                                                TIDSortedElemSet& foundElems)
+   void ElementBndBoxTree::getElementsNearLine( const gp_Ax1&                    line,
+                                                vector<const SMDS_MeshElement*>& foundElems)
    {
      if ( getBox()->IsOut( line ))
        return;
  
      if ( isLeaf() )
      {
+       LimitAndPool* pool = getLimitAndPool();
        for ( size_t i = 0; i < _elements.size(); ++i )
-         if ( !_elements[i]->IsOut( line ))
-           foundElems.insert( _elements[i]->_element );
+         if ( !_elements[i]->IsOut( line ) &&
+              !_elements[i]->_isMarked )
+         {
+           foundElems.push_back( _elements[i]->_element );
+           _elements[i]->_isMarked = true;
+           pool->_markedElems.push_back( _elements[i] );
+         }
      }
      else
      {
        for (int i = 0; i < 8; i++)
          ((ElementBndBoxTree*) myChildren[i])->getElementsNearLine( line, foundElems );
+       if ( level() == 0 )
+       {
+         LimitAndPool* pool = getLimitAndPool();
+         for ( size_t i = 0; i < pool->_markedElems.size(); ++i )
+           pool->_markedElems[i]->_isMarked = false;
+         pool->_markedElems.clear();
+       }
      }
    }
  
     */
    //================================================================================
  
-   void ElementBndBoxTree::getElementsInSphere ( const gp_XYZ&     center,
-                                                 const double      radius,
-                                                 TIDSortedElemSet& foundElems)
+   void ElementBndBoxTree::getElementsInSphere ( const gp_XYZ&                    center,
+                                                 const double                     radius,
+                                                 vector<const SMDS_MeshElement*>& foundElems)
    {
      if ( getBox()->IsOut( center, radius ))
        return;
  
      if ( isLeaf() )
      {
+       LimitAndPool* pool = getLimitAndPool();
        for ( size_t i = 0; i < _elements.size(); ++i )
-         if ( !_elements[i]->IsOut( center, radius ))
-           foundElems.insert( _elements[i]->_element );
+         if ( !_elements[i]->IsOut( center, radius ) &&
+              !_elements[i]->_isMarked )
+         {
+           foundElems.push_back( _elements[i]->_element );
+           _elements[i]->_isMarked = true;
+           pool->_markedElems.push_back( _elements[i] );
+         }
      }
      else
      {
        for (int i = 0; i < 8; i++)
          ((ElementBndBoxTree*) myChildren[i])->getElementsInSphere( center, radius, foundElems );
+       if ( level() == 0 )
+       {
+         LimitAndPool* pool = getLimitAndPool();
+         for ( size_t i = 0; i < pool->_markedElems.size(); ++i )
+           pool->_markedElems[i]->_isMarked = false;
+         pool->_markedElems.clear();
+       }
+     }
+   }
+   //================================================================================
+   /*!
+    * \brief Return a leaf including a point
+    */
+   //================================================================================
+   ElementBndBoxTree* ElementBndBoxTree::getLeafAtPoint( const gp_XYZ& point )
+   {
+     if ( getBox()->IsOut( point ))
+       return 0;
+     if ( isLeaf() )
+     {
+       return this;
      }
+     else
+     {
+       for (int i = 0; i < 8; i++)
+         if ( ElementBndBoxTree* l = ((ElementBndBoxTree*) myChildren[i])->getLeafAtPoint( point ))
+           return l;
+     }
+     return 0;
    }
  
    //================================================================================
     */
    //================================================================================
  
-   ElementBndBoxTree::ElementBox::ElementBox(const SMDS_MeshElement* elem, double tolerance)
+   void ElementBndBoxTree::ElementBox::init(const SMDS_MeshElement* elem, double tolerance)
    {
      _element  = elem;
-     _refCount = 1;
+     _isMarked = false;
      SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
      while ( nIt->more() )
-       Add( SMESH_TNodeXYZ( nIt->next() ));
+       Add( SMESH_NodeXYZ( nIt->next() ));
      Enlarge( tolerance );
    }
  
@@@ -476,13 -566,16 +566,16 @@@ struct SMESH_ElementSearcherImpl: publi
    virtual const SMDS_MeshElement* FindClosestTo( const gp_Pnt&       point,
                                                   SMDSAbs_ElementType type );
  
-   void GetElementsNearLine( const gp_Ax1&                      line,
-                             SMDSAbs_ElementType                type,
-                             vector< const SMDS_MeshElement* >& foundElems);
-   void GetElementsInSphere( const gp_XYZ&                      center,
-                             const double                       radius,
-                             SMDSAbs_ElementType                type,
-                             vector< const SMDS_MeshElement* >& foundElems);
+   virtual void GetElementsNearLine( const gp_Ax1&                      line,
+                                     SMDSAbs_ElementType                type,
+                                     vector< const SMDS_MeshElement* >& foundElems);
+   virtual void GetElementsInSphere( const gp_XYZ&                      center,
+                                     const double                       radius,
+                                     SMDSAbs_ElementType                type,
+                                     vector< const SMDS_MeshElement* >& foundElems);
+   virtual gp_XYZ Project(const gp_Pnt&            point,
+                          SMDSAbs_ElementType      type,
+                          const SMDS_MeshElement** closestElem);
    double getTolerance();
    bool getIntersParamOnLine(const gp_Lin& line, const SMDS_MeshElement* face,
                              const double tolerance, double & param);
@@@ -604,7 -697,7 +697,7 @@@ bool SMESH_ElementSearcherImpl::getInte
      anExtCC.Init( lineCurve, edge.Value() );
      if ( anExtCC.NbExtrema() > 0 && anExtCC.LowerDistance() <= tol)
      {
-       Quantity_Parameter pl, pe;
+       Standard_Real pl, pe;
        anExtCC.LowerDistanceParameters( pl, pe );
        param += pl;
        if ( ++nbInts == 2 )
@@@ -771,9 -864,13 +864,13 @@@ FindElementsByPoint(const gp_Pnt
      {
        _ebbTree[_elementType] = new ElementBndBoxTree( *_mesh, type, _meshPartIt, tolerance );
      }
-     TIDSortedElemSet suspectElems;
+     else
+     {
+       _ebbTree[ type ]->prepare();
+     }
+     vector< const SMDS_MeshElement* > suspectElems;
      _ebbTree[ type ]->getElementsNearPoint( point, suspectElems );
-     TIDSortedElemSet::iterator elem = suspectElems.begin();
+     vector< const SMDS_MeshElement* >::iterator elem = suspectElems.begin();
      for ( ; elem != suspectElems.end(); ++elem )
        if ( !SMESH_MeshAlgos::IsOut( *elem, point, tolerance ))
          foundElements.push_back( *elem );
@@@ -801,8 -898,10 +898,10 @@@ SMESH_ElementSearcherImpl::FindClosestT
      ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
      if ( !ebbTree )
        ebbTree = new ElementBndBoxTree( *_mesh, type, _meshPartIt );
+     else
+       ebbTree->prepare();
  
-     TIDSortedElemSet suspectElems;
+     vector<const SMDS_MeshElement*> suspectElems;
      ebbTree->getElementsNearPoint( point, suspectElems );
  
      if ( suspectElems.empty() && ebbTree->maxSize() > 0 )
          radius = ebbTree->maxSize() / pow( 2., getTreeHeight()) / 2;
        while ( suspectElems.empty() )
        {
+         ebbTree->prepare();
          ebbTree->getElementsInSphere( point.XYZ(), radius, suspectElems );
          radius *= 1.1;
        }
      }
      double minDist = std::numeric_limits<double>::max();
      multimap< double, const SMDS_MeshElement* > dist2face;
-     TIDSortedElemSet::iterator elem = suspectElems.begin();
+     vector<const SMDS_MeshElement*>::iterator elem = suspectElems.begin();
      for ( ; elem != suspectElems.end(); ++elem )
      {
        double dist = SMESH_MeshAlgos::GetDistance( *elem, point );
@@@ -886,6 -986,8 +986,8 @@@ TopAbs_State SMESH_ElementSearcherImpl:
    ElementBndBoxTree*& ebbTree = _ebbTree[ SMDSAbs_Face ];
    if ( !ebbTree )
      ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
+   else
+     ebbTree->prepare();
  
    // Algo: analyse transition of a line starting at the point through mesh boundary;
    // try three lines parallel to axis of the coordinate system and perform rough
      gp_Ax1 lineAxis( point, axisDir[axis]);
      gp_Lin line    ( lineAxis );
  
-     TIDSortedElemSet suspectFaces; // faces possibly intersecting the line
+     vector<const SMDS_MeshElement*> suspectFaces; // faces possibly intersecting the line
+     if ( axis > 0 ) ebbTree->prepare();
      ebbTree->getElementsNearLine( lineAxis, suspectFaces );
  
      // Intersect faces with the line
  
      map< double, TInters > & u2inters = paramOnLine2TInters[ axis ];
-     TIDSortedElemSet::iterator face = suspectFaces.begin();
+     vector<const SMDS_MeshElement*>::iterator face = suspectFaces.begin();
      for ( ; face != suspectFaces.end(); ++face )
      {
        // get face plane
@@@ -1114,10 -1217,10 +1217,10 @@@ void SMESH_ElementSearcherImpl::GetElem
    ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
    if ( !ebbTree )
      ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
+   else
+     ebbTree->prepare();
  
-   TIDSortedElemSet suspectFaces; // elements possibly intersecting the line
-   ebbTree->getElementsNearLine( line, suspectFaces );
-   foundElems.assign( suspectFaces.begin(), suspectFaces.end());
+   ebbTree->getElementsNearLine( line, foundElems );
  }
  
  //=======================================================================
@@@ -1135,10 -1238,59 +1238,59 @@@ void SMESH_ElementSearcherImpl::GetElem
    ElementBndBoxTree*& ebbTree = _ebbTree[ type ];
    if ( !ebbTree )
      ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt );
+   else
+     ebbTree->prepare();
  
-   TIDSortedElemSet suspectFaces; // elements possibly intersecting the line
-   ebbTree->getElementsInSphere( center, radius, suspectFaces );
-   foundElems.assign( suspectFaces.begin(), suspectFaces.end() );
+   ebbTree->getElementsInSphere( center, radius, foundElems );
+ }
+ //=======================================================================
+ /*
+  * \brief Return a projection of a given point to a mesh.
+  *        Optionally return the closest element
+  */
+ //=======================================================================
+ gp_XYZ SMESH_ElementSearcherImpl::Project(const gp_Pnt&            point,
+                                           SMDSAbs_ElementType      type,
+                                           const SMDS_MeshElement** closestElem)
+ {
+   _elementType = type;
+   if ( _mesh->GetMeshInfo().NbElements( _elementType ) == 0 )
+     throw SALOME_Exception( LOCALIZED( "No elements of given type in the mesh" ));
+   ElementBndBoxTree*& ebbTree = _ebbTree[ _elementType ];
+   if ( !ebbTree )
+     ebbTree = new ElementBndBoxTree( *_mesh, _elementType );
+   gp_XYZ p = point.XYZ();
+   ElementBndBoxTree* ebbLeaf = ebbTree->getLeafAtPoint( p );
+   const Bnd_B3d* box = ebbLeaf->getBox();
+   double radius = ( box->CornerMax() - box->CornerMin() ).Modulus();
+   vector< const SMDS_MeshElement* > elems;
+   ebbTree->getElementsInSphere( p, radius, elems );
+   while ( elems.empty() )
+   {
+     radius *= 1.5;
+     ebbTree->getElementsInSphere( p, radius, elems );
+   }
+   gp_XYZ proj, bestProj;
+   const SMDS_MeshElement* elem = 0;
+   double minDist = 2 * radius;
+   for ( size_t i = 0; i < elems.size(); ++i )
+   {
+     double d = SMESH_MeshAlgos::GetDistance( elems[i], p, &proj );
+     if ( d < minDist )
+     {
+       bestProj = proj;
+       elem = elems[i];
+       minDist = d;
+     }
+   }
+   if ( closestElem ) *closestElem = elem;
+   return bestProj;
  }
  
  //=======================================================================
@@@ -1388,17 -1540,19 +1540,19 @@@ namespac
  //=======================================================================
  
  double SMESH_MeshAlgos::GetDistance( const SMDS_MeshElement* elem,
-                                      const gp_Pnt&           point )
+                                      const gp_Pnt&           point,
+                                      gp_XYZ*                 closestPnt )
  {
    switch ( elem->GetType() )
    {
    case SMDSAbs_Volume:
-     return GetDistance( dynamic_cast<const SMDS_MeshVolume*>( elem ), point);
+     return GetDistance( dynamic_cast<const SMDS_MeshVolume*>( elem ), point, closestPnt );
    case SMDSAbs_Face:
-     return GetDistance( dynamic_cast<const SMDS_MeshFace*>( elem ), point);
+     return GetDistance( dynamic_cast<const SMDS_MeshFace*>( elem ), point, closestPnt );
    case SMDSAbs_Edge:
-     return GetDistance( dynamic_cast<const SMDS_MeshEdge*>( elem ), point);
+     return GetDistance( dynamic_cast<const SMDS_MeshEdge*>( elem ), point, closestPnt );
    case SMDSAbs_Node:
+     if ( closestPnt ) *closestPnt = SMESH_TNodeXYZ( elem );
      return point.Distance( SMESH_TNodeXYZ( elem ));
    default:;
    }
  //=======================================================================
  
  double SMESH_MeshAlgos::GetDistance( const SMDS_MeshFace* face,
-                                      const gp_Pnt&        point )
+                                      const gp_Pnt&        point,
+                                      gp_XYZ*              closestPnt )
  {
-   double badDistance = -1;
+   const double badDistance = -1;
    if ( !face ) return badDistance;
  
    // coordinates of nodes (medium nodes, if any, ignored)
    trsf.Transforms( tmpPnt );
    gp_XY point2D( tmpPnt.X(), tmpPnt.Z() );
  
-   // loop on segments of the face to analyze point position ralative to the face
+   // loop on edges of the face to analyze point position ralative to the face
    set< PointPos > pntPosSet;
    for ( size_t i = 1; i < xy.size(); ++i )
    {
  
    // compute distance
    PointPos pos = *pntPosSet.begin();
-   // cout << "Face " << face->GetID() << " DIST: ";
    switch ( pos._name )
    {
-   case POS_LEFT: {
-     // point is most close to a segment
-     gp_Vec p0p1( point, xyz[ pos._index ] );
-     gp_Vec p1p2( xyz[ pos._index ], xyz[ pos._index+1 ]); // segment vector
-     p1p2.Normalize();
-     double projDist = p0p1 * p1p2; // distance projected to the segment
-     gp_Vec projVec = p1p2 * projDist;
-     gp_Vec distVec = p0p1 - projVec;
-     // cout << distVec.Magnitude()  << ", SEG " << face->GetNode(pos._index)->GetID()
-     //      << " - " << face->GetNodeWrap(pos._index+1)->GetID() << endl;
-     return distVec.Magnitude();
+   case POS_LEFT:
+   {
+     // point is most close to an edge
+     gp_Vec edge( xyz[ pos._index ], xyz[ pos._index+1 ]);
+     gp_Vec n1p ( xyz[ pos._index ], point  );
+     double u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge
+     // projection of the point on the edge
+     gp_XYZ proj = ( 1. - u ) * xyz[ pos._index ] + u * xyz[ pos._index+1 ];
+     if ( closestPnt ) *closestPnt = proj;
+     return point.Distance( proj );
    }
-   case POS_RIGHT: {
+   case POS_RIGHT:
+   {
      // point is inside the face
-     double distToFacePlane = tmpPnt.Y();
-     // cout << distToFacePlane << ", INSIDE " << endl;
-     return Abs( distToFacePlane );
+     double distToFacePlane = Abs( tmpPnt.Y() );
+     if ( closestPnt )
+     {
+       if ( distToFacePlane < std::numeric_limits<double>::min() ) {
+         *closestPnt = point.XYZ();
+       }
+       else {
+         tmpPnt.SetY( 0 );
+         trsf.Inverted().Transforms( tmpPnt );
+         *closestPnt = tmpPnt;
+       }
+     }
+     return distToFacePlane;
    }
-   case POS_VERTEX: {
+   case POS_VERTEX:
+   {
      // point is most close to a node
      gp_Vec distVec( point, xyz[ pos._index ]);
-     // cout << distVec.Magnitude()  << " VERTEX " << face->GetNode(pos._index)->GetID() << endl;
      return distVec.Magnitude();
    }
    default:;
   */
  //=======================================================================
  
- double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* seg, const gp_Pnt& point )
+ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshEdge* seg,
+                                      const gp_Pnt&        point,
+                                      gp_XYZ*              closestPnt )
  {
    double dist = Precision::Infinite();
    if ( !seg ) return dist;
      double u = ( edge * n1p ) / edge.SquareMagnitude(); // param [0,1] on the edge
      if ( u <= 0. ) {
        dist = Min( dist, n1p.SquareMagnitude() );
+       if ( closestPnt ) *closestPnt = xyz[i-1];
      }
      else if ( u >= 1. ) {
        dist = Min( dist, point.SquareDistance( xyz[i] ));
+       if ( closestPnt ) *closestPnt = xyz[i];
      }
      else {
        gp_XYZ proj = ( 1. - u ) * xyz[i-1] + u * xyz[i]; // projection of the point on the edge
        dist = Min( dist, point.SquareDistance( proj ));
+       if ( closestPnt ) *closestPnt = proj;
      }
    }
    return Sqrt( dist );
   */
  //=======================================================================
  
- double SMESH_MeshAlgos::GetDistance( const SMDS_MeshVolume* volume, const gp_Pnt& point )
+ double SMESH_MeshAlgos::GetDistance( const SMDS_MeshVolume* volume,
+                                      const gp_Pnt&          point,
+                                      gp_XYZ*                closestPnt )
  {
    SMDS_VolumeTool vTool( volume );
    vTool.SetExternalNormal();
  
    double n[3], bc[3];
    double minDist = 1e100, dist;
+   gp_XYZ closeP = point.XYZ();
+   bool isOut = false;
    for ( int iF = 0; iF < vTool.NbFaces(); ++iF )
    {
      // skip a facet with normal not "looking at" the point
      case 3:
      {
        SMDS_FaceOfNodes tmpFace( nodes[0], nodes[ 1*iQ ], nodes[ 2*iQ ] );
-       dist = GetDistance( &tmpFace, point );
+       dist = GetDistance( &tmpFace, point, closestPnt );
        break;
      }
      case 4:
      {
        SMDS_FaceOfNodes tmpFace( nodes[0], nodes[ 1*iQ ], nodes[ 2*iQ ], nodes[ 3*iQ ]);
-       dist = GetDistance( &tmpFace, point );
+       dist = GetDistance( &tmpFace, point, closestPnt );
        break;
      }
      default:
        vector<const SMDS_MeshNode *> nvec( nodes, nodes + vTool.NbFaceNodes( iF ));
        SMDS_PolygonalFaceOfNodes tmpFace( nvec );
-       dist = GetDistance( &tmpFace, point );
+       dist = GetDistance( &tmpFace, point, closestPnt );
+     }
+     if ( dist < minDist )
+     {
+       minDist = dist;
+       isOut = true;
+       if ( closestPnt ) closeP = *closestPnt;
      }
-     minDist = Min( minDist, dist );
    }
-   return minDist;
+   if ( isOut )
+   {
+     if ( closestPnt ) *closestPnt = closeP;
+     return minDist;
+   }
+   return 0; // point is inside the volume
  }
  
  //================================================================================
@@@ -1778,3 -1962,12 +1962,3 @@@ SMESH_ElementSearcher* SMESH_MeshAlgos:
  {
    return new SMESH_ElementSearcherImpl( mesh, tolerance, elemIt );
  }
 -
 -// TMP for ASERIS in V8_2_BR -- to remove when merging to master
 -void SMESH_MeshAlgos::DeMerge(const SMDS_MeshElement*              elem,
 -                              std::vector< const SMDS_MeshNode* >& newNodes,
 -                              std::vector< const SMDS_MeshNode* >& noMergeNodes)
 -{
 -// TMP for ASERIS in V8_2_BR -- to remove when merging to master
 -}
 -// TMP for ASERIS in V8_2_BR -- to remove when merging to master
index 231dd33b5eb7a132013d734008dc5fdcad81441f,f8a61b76644f80cf43f82c62d3b3275818768bb8..e5a7aeeb068b838349bca1e1a913d45b8a99ec4b
@@@ -24,6 -24,7 +24,7 @@@
  //
  #include "libSMESH_Swig.h"
  
+ #include <SVTK_Selector.h>
  
  #include <SMESHGUI.h>
  #include <SMESHGUI_Utils.h>
@@@ -49,6 -50,7 +50,7 @@@
  #include <SalomeApp_Application.h>
  #include <LightApp_SelectionMgr.h>
  #include <SVTK_RenderWindowInteractor.h>
+ #include <VTKViewer_Algorithm.h>
  
  // OCCT includes
  #include <TopAbs.hxx>
  #include CORBA_SERVER_HEADER(SMESH_Gen)
  #include CORBA_SERVER_HEADER(SMESH_Hypothesis)
  
+ // VTK includes
+ #include <vtkActorCollection.h>
+ #include <vtkRenderer.h>
  static CORBA::ORB_var anORB;
  
  namespace
@@@ -421,6 -427,7 +427,6 @@@ SMESH_Swig::~SMESH_Swig(
  //===============================================================
  const char* SMESH_Swig::AddNewMesh(const char* theIOR)
  {
 -  MESSAGE("AddNewMesh");
  
    // VSR: added temporarily - to be removed - objects are published automatically by engine
    SALOMEDS::SObject_var aSObject = myStudy->FindObjectIOR(theIOR);
  //===============================================================
  const char* SMESH_Swig::AddNewHypothesis(const char* theIOR)
  {
 -  MESSAGE("AddNewHypothesis");
 -
    SALOMEDS::SObject_var aSObject = ::AddHypothesis(theIOR,
                                                     mySComponentMesh,
                                                     myStudyBuilder);
  //===============================================================
  const char* SMESH_Swig::AddNewAlgorithms(const char* theIOR)
  {
 -  MESSAGE("AddNewAlgorithms");
 -
    SALOMEDS::SObject_var aSObject = ::AddAlgorithms(theIOR,
                                                     mySComponentMesh,
                                                     myStudyBuilder);
@@@ -610,148 -621,6 +616,148 @@@ const char* SMESH_Swig::AddSubMeshOnSha
    return "";
  }
  
 +/*!
 +  \brief Gets window with specified identifier
 +  \internal
 +  \param id window identifier
 +  \return pointer on the window
 +*/
 +
 +SUIT_ViewWindow* getWnd( const int id )
 +{
 +  SUIT_ViewWindow* resWnd = 0;
 +  SUIT_Session* aSession          = SUIT_Session::session();
 +  SUIT_Application* anApplication = aSession->activeApplication();
 +  SalomeApp_Application* app    = dynamic_cast<SalomeApp_Application*>(anApplication);
 +  if ( app ) {
 +    ViewManagerList vmlist = app->viewManagers();
 +    foreach( SUIT_ViewManager* vm, vmlist ) {
 +      QVector<SUIT_ViewWindow*> vwlist = vm->getViews();
 +      foreach ( SUIT_ViewWindow* vw, vwlist ) {
 +        if ( id == vw->getId() ) {
 +          resWnd = vw;
 +          break;
 +        }
 +      }
 +    }
 +  }
 +  return resWnd;
 +}
 +
 +class TGetActorAspect: public SALOME_Event
 +{
 +public:
 +  typedef actorAspect TResult;
 +  TResult myResult;
 +  const char* _entry;
 +  int _wid;
 +  TGetActorAspect( const char* Mesh_Entry, int viewId )
 +  {
 +    _entry = Mesh_Entry;
 +    _wid = viewId;
 +  }
 +  virtual void Execute()
 +    {
 +      SMESH_Actor* anActor;
 +      if (_wid)
 +        {
 +          SUIT_ViewWindow* w = getWnd(_wid);
 +          anActor = SMESH::FindActorByEntry( w, _entry );
 +        }
 +      else
 +        anActor = SMESH::FindActorByEntry( _entry );
 +      if ( !anActor )
 +        {
 +          MESSAGE("GetActorAspect: no actor corresponding to: " << _entry);
 +          return;
 +        }
 +      anActor->GetSufaceColor(myResult.surfaceColor.r,
 +                              myResult.surfaceColor.g,
 +                              myResult.surfaceColor.b,
 +                              myResult.surfaceColor.delta);
 +      anActor->GetVolumeColor(myResult.volumeColor.r,
 +                              myResult.volumeColor.g,
 +                              myResult.volumeColor.b,
 +                              myResult.volumeColor.delta);
 +      anActor->GetEdgeColor(myResult.edgeColor.r,
 +                            myResult.edgeColor.g,
 +                            myResult.edgeColor.b);
 +      anActor->GetNodeColor(myResult.nodeColor.r,
 +                            myResult.nodeColor.g,
 +                            myResult.nodeColor.b);
 +      myResult.opacity= anActor->GetOpacity();
 +      MESSAGE("opacity: " << myResult.opacity);
 +    }
 +};
 +
 +actorAspect SMESH_Swig::GetActorAspect( const char* Mesh_Entry, int viewId )
 +{
 +  return ProcessEvent(new TGetActorAspect( Mesh_Entry, viewId));
 +}
 +
 +void SMESH_Swig::SetActorAspect( const actorAspect& actorPres, const char* Mesh_Entry, int viewId )
 +{
 +  class TSetActorAspect: public SALOME_Event
 +  {
 +  public:
 +    const char* _entry;
 +    actorAspect _actorPres;
 +    int _wid;
 +    TSetActorAspect(const actorAspect& actorPres, const char* Mesh_Entry, int viewId )
 +    {
 +      _entry = Mesh_Entry;
 +      _actorPres = actorPres;
 +      _wid = viewId;
 +    }
 +    virtual void Execute()
 +    {
 +      SMESH_Actor* anActor;
 +      if (_wid)
 +        {
 +          SUIT_ViewWindow* w = getWnd(_wid);
 +          anActor = SMESH::FindActorByEntry( w, _entry );
 +        }
 +      else
 +        anActor = SMESH::FindActorByEntry( _entry );
 +      if ( !anActor )
 +        {
 +          MESSAGE("SetActorAspect: no actor corresponding to: " << _entry);
 +          return;
 +        }
 +      anActor->SetSufaceColor(_actorPres.surfaceColor.r,
 +                              _actorPres.surfaceColor.g,
 +                              _actorPres.surfaceColor.b,
 +                              _actorPres.surfaceColor.delta);
 +      anActor->SetVolumeColor(_actorPres.volumeColor.r,
 +                              _actorPres.volumeColor.g,
 +                              _actorPres.volumeColor.b,
 +                              _actorPres.volumeColor.delta);
 +      anActor->SetEdgeColor(_actorPres.edgeColor.r,
 +                            _actorPres.edgeColor.g,
 +                            _actorPres.edgeColor.b);
 +      anActor->SetNodeColor(_actorPres.nodeColor.r,
 +                            _actorPres.nodeColor.g,
 +                            _actorPres.nodeColor.b);
 +      anActor->SetOpacity(_actorPres.opacity);
 +      if (_wid)
 +        {
 +          SUIT_ViewWindow* w = getWnd(_wid);
 +          w->repaint();
 +        }
 +      else
 +        {
 +          SUIT_Session* aSession          = SUIT_Session::session();
 +          SUIT_Application* anApplication = aSession->activeApplication();
 +          SalomeApp_Application* anApp    = dynamic_cast<SalomeApp_Application*>(anApplication);
 +          SUIT_ViewManager* vman          = anApp->getViewManager(VTKViewer_Viewer::Type(),true);
 +          vman->getActiveView()->repaint();
 +        }
 +    }
 +  };
 +
 +  ProcessVoidEvent(new TSetActorAspect(actorPres, Mesh_Entry, viewId));
 +}
 +
  void SMESH_Swig::CreateAndDisplayActor( const char* Mesh_Entry )
  {
    //  SMESH_Actor* Mesh = smeshGUI->ReadScript(aM);
@@@ -815,6 -684,25 +821,25 @@@ void SMESH_Swig::EraseActor( const char
    ProcessVoidEvent(new TEvent(Mesh_Entry, allViewers));
  }
  
+ void SMESH_Swig::UpdateActor( const char* Mesh_Entry ) {
+   class TEvent: public SALOME_Event
+   {
+   private:
+     const char* _entry;
+   public:
+     TEvent( const char* Mesh_Entry ) {
+       _entry = Mesh_Entry;
+     }
+     virtual void Execute() {
+       Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject
+         ( _entry, "SMESH", "" );
+       SMESH::Update( anIO, true );
+     }
+   };
+   ProcessVoidEvent( new TEvent(Mesh_Entry) );
+ }
  void SMESH_Swig::SetName(const char* theEntry,
                           const char* theName)
  {
@@@ -892,17 -780,18 +917,18 @@@ public
    {}
    virtual void Execute()
    {
-     SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI();
-     if( !aSMESHGUI ) 
-       return;
      
-     LightApp_SelectionMgr* selMgr = SMESH::GetSelectionMgr( aSMESHGUI );
+     LightApp_SelectionMgr* selMgr = 0;
+     SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
+     if( anApp )
+       selMgr = dynamic_cast<LightApp_SelectionMgr*>( anApp->selectionMgr() );
      if( !selMgr )
        return;
      
      selMgr->clearFilters();
  
-     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aSMESHGUI );
+     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
      if(!aViewWindow)
        return;
  
@@@ -956,30 -845,225 +982,225 @@@ void SMESH_Swig::select( const char* id
    ProcessVoidEvent( new TSelectListEvent( id, ids, append ) );
  }
  
+ /*!
+   \brief Helper class for selection edges of cell event
+ */
+ class TSelectListOfPairEvent: public SALOME_Event
+ {
+   const char*                        myId;
+   std::vector<std::pair<int, int> >  myIdsList;
+   bool                               myIsAppend;
+ public:
+   TSelectListOfPairEvent(const char* id, std::vector<std::pair<int, int> > ids, bool append) :
+     myId(id),
+     myIdsList(ids),
+     myIsAppend(append)
+   {}
+   virtual void Execute()
+   {
+     
+     LightApp_SelectionMgr* selMgr = 0;
+     SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
+     if( anApp )
+       selMgr = dynamic_cast<LightApp_SelectionMgr*>( anApp->selectionMgr() );
+     if( !selMgr )
+       return;
+     
+     selMgr->clearFilters();
+     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
+     if(!aViewWindow)
+       return;
+     SMESH_Actor* anActor = SMESH::FindActorByEntry( myId );
+     
+     if (!anActor || !anActor->hasIO())
+       return;
+     
+     Handle(SALOME_InteractiveObject) anIO = anActor->getIO();
+     SALOME_ListIO aList;
+     aList.Append(anIO);
+     selMgr->setSelectedObjects(aList, false);
+     if ( aViewWindow->SelectionMode() !=  EdgeOfCellSelection ) {
+       return;
+     }
+         
+     SVTK_IndexedMapOfIds aMap;
+     std::vector<std::pair<int, int> >::const_iterator anIter;
+     for (anIter = myIdsList.begin(); anIter != myIdsList.end(); ++anIter) {
+       std::vector<int> aCompositeId;
+       aCompositeId.push_back((*anIter).first);
+       aCompositeId.push_back((*anIter).second);
+       aMap.Add(aCompositeId);
+     }
+     // Set new selection
+     SVTK_Selector* aSelector  = aViewWindow->GetSelector();
+     aSelector->AddOrRemoveCompositeIndex(anIO, aMap, myIsAppend);
+     aViewWindow->highlight( anIO, true, true );
+     aViewWindow->GetInteractor()->onEmitSelectionChanged();
+   }
+ };
+ /*!
+   \brief Select the elements on the mesh, sub-mesh or group.
+   \param id object entry
+   \param ids list of the element ids
+   \param mode selection mode
+ */
+ void SMESH_Swig::select( const char* id, std::vector<std::pair<int,int> > ids, bool append ) {
+   ProcessVoidEvent( new TSelectListOfPairEvent( id, ids, append ) );
+ }
  
  class TGetSelectionModeEvent : public SALOME_Event
  {
  public:
-   typedef int TResult;
+   typedef SelectionMode TResult;
    TResult myResult;
-   TGetSelectionModeEvent() : myResult( -1 ) {}
+   TGetSelectionModeEvent() : myResult( Undefined ) {}
    virtual void Execute()
    {
-     SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI();
-     if( !aSMESHGUI ) 
-       return;
-     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aSMESHGUI );
+     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( );
      if(!aViewWindow)
        return;
      
-     myResult = aViewWindow->SelectionMode();
+     myResult = (SelectionMode) aViewWindow->SelectionMode();
    }
  };
  
  /*!
    \brief Get selection mode of the active VTK View window.
  */
int SMESH_Swig::getSelectionMode() {
SelectionMode SMESH_Swig::getSelectionMode() {
    return ProcessEvent( new TGetSelectionModeEvent() );
  }
+ /*!
+  * Event to set selection mode
+ */
+ class TSetSelectionModeEvent : public SALOME_Event
+ {
+   SelectionMode mySelectionMode;
+ public:
+   TSetSelectionModeEvent(const SelectionMode selectionMode) :
+     mySelectionMode(selectionMode) 
+   {}
+   virtual void Execute()
+   {
+     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
+     if(!aViewWindow)
+       return;
+     Selection_Mode prevMode = aViewWindow->SelectionMode();
+     bool changePointRepresentation = ( prevMode == NodeSelection && mySelectionMode != Node ) ||
+       (prevMode != NodeSelection && mySelectionMode == Node);
+       
+     if( changePointRepresentation ) {
+       vtkRenderer *aRenderer = aViewWindow->getRenderer();
+       VTK::ActorCollectionCopy aCopy(aRenderer->GetActors());
+       vtkActorCollection *aCollection = aCopy.GetActors();
+       aCollection->InitTraversal();
+       while(vtkActor *anAct = aCollection->GetNextActor()){
+       if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
+         if(anActor->GetVisibility()){
+           anActor->SetPointRepresentation(mySelectionMode == Node);
+         }
+       }
+       }
+     }
+     aViewWindow->SetSelectionMode(mySelectionMode);
+   }
+ };
+ void SMESH_Swig::setSelectionMode(SelectionMode selectionMode){
+   ProcessVoidEvent( new TSetSelectionModeEvent( selectionMode ) ); 
+ }
+ class TGetSelectedEvent : public SALOME_Event
+ {
+ public:
+   typedef std::vector<int> TResult;
+   TResult myResult;
+   const char* myId;
+   
+   TGetSelectedEvent( const char* id) : 
+     myResult( std::vector<int>() ),
+     myId(id)
+   {}
+   
+   virtual void Execute()
+   {
+     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
+     if( !aViewWindow )
+       return;
+     SVTK_Selector* aSelector  = aViewWindow->GetSelector();    
+     if( !aSelector )
+       return;
+     SMESH_Actor* anActor = SMESH::FindActorByEntry( myId );
+     
+     if ( !anActor || !anActor->hasIO() )
+       return;
+     TColStd_IndexedMapOfInteger aMapIndex;
+     aSelector->GetIndex(anActor->getIO(),aMapIndex);
+     for( int i = 1; i <= aMapIndex.Extent(); i++ )
+       myResult.push_back( aMapIndex( i ) );
+   }
+ };
+ std::vector<int> SMESH_Swig::getSelected( const char* Mesh_Entry ) {
+   return ProcessEvent( new TGetSelectedEvent(Mesh_Entry) );
+ }
+ class TGetSelectedPairEvent : public SALOME_Event
+ {
+ public:
+   typedef std::vector<std::pair<int, int> > TResult;
+   TResult myResult;
+   const char* myId;
+   
+   TGetSelectedPairEvent( const char* id) : 
+     myResult( std::vector<std::pair<int,int> >() ),
+     myId(id)
+   {}
+   
+   virtual void Execute()
+   {
+     SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow();
+     if( !aViewWindow )
+       return;
+     if(aViewWindow->SelectionMode() != EdgeOfCellSelection )
+       return;
+     SVTK_Selector* aSelector  = aViewWindow->GetSelector();    
+     if( !aSelector )
+       return;
+     SMESH_Actor* anActor = SMESH::FindActorByEntry( myId );
+     
+     if ( !anActor || !anActor->hasIO() )
+       return;
+     SVTK_IndexedMapOfIds aMapIndex;
+     aSelector->GetCompositeIndex(anActor->getIO(),aMapIndex);
+     for( int i = 1; i <= aMapIndex.Extent(); i++ )
+       myResult.push_back( std::make_pair<int,int>( (int)aMapIndex( i )[0], (int)aMapIndex( i )[1]) );
+   }
+ };
+ std::vector<std::pair<int,int> > SMESH_Swig::getSelectedEdgeOfCell( const char* Mesh_Entry ) {
+   return ProcessEvent( new TGetSelectedPairEvent(Mesh_Entry) );
+ }
index 86682ff5b79baa3465050fe6d74d9862fefae85e,654c3e699c200ba8e0fdec51d6d9d1c0f6dafa8b..931614c1ef0082a5216bb505475e78dfafc3e329
  
  //std includes
  #include <vector>
+ #include <utility>
  
  #include <SVTK_Selection.h>
  
  #include <SVTK_Selection.h>
  
- enum
typedef enum
    {
+     Undefined  = -1,
      Node       = NodeSelection,
      Cell       = CellSelection,
      EdgeOfCell = EdgeOfCellSelection,
      Actor      = ActorSelection,
      Elem0D     = Elem0DSelection,
      Ball       = BallSelection
-   };
+   } SelectionMode;
  
 +typedef struct
 +{
 +  double r, g, b;
 +  int delta;
 +} surfaceColorStruct;
 +
 +typedef struct
 +{
 +  double r, g, b;
 +  int delta;
 +} volumeColorStruct;
 +
 +typedef struct
 +{
 +  double r, g, b;
 +} edgeColorStruct;
 +
 +typedef struct
 +{
 +  double r, g, b;
 +} nodeColorStruct;
 +
 +struct actorAspect
 +{
 +  surfaceColorStruct surfaceColor;
 +  volumeColorStruct volumeColor;
 +  edgeColorStruct edgeColor;
 +  nodeColorStruct nodeColor;
 +  double opacity;
 +};
 +
  class SMESH_SWIG_EXPORT SMESH_Swig
  {
  public:
  
    void                       EraseActor( const char*, const bool allViewers = false );
  
+   void                       UpdateActor( const char* Mesh_Entry );
    /*!
     * \brief Set mesh icon according to compute status
      * \param Mesh_Entry - entry of a mesh
     */
    void                       SetMeshIcon( const char*, const bool, const bool );
  
 +  actorAspect                GetActorAspect(const char* Mesh_Entry, int viewId = 0 );
 +  void                       SetActorAspect( const actorAspect& actorPres, const char* Mesh_Entry, int viewId = 0  );
 +
+   void setSelectionMode( SelectionMode selectionMode );
+   std::vector<int> getSelected( const char* Mesh_Entry );
+   std::vector<std::pair<int, int> > getSelectedEdgeOfCell( const char* Mesh_Entry );
    // --------------------- for the test purposes -----------------------
-   int  getSelectionMode();
+   SelectionMode getSelectionMode();
    void select( const char *id, std::vector<int> ids, bool append = false );
    void select( const char *id, int id1, bool append = false );
+   void select( const char *id, std::vector<std::pair<int,int> >, bool apend = false );
  
  private:
    SALOMEDS::Study_var        myStudy;
index ac732d4672e8f64d8626a71b65cd20528cbd8f98,68b0e1ec5618d51a0aac5c44b623d2d879d02917..d00fff057496da611c9107bf70ab65b27461a133
  
  %include "typemaps.i"
  %include "std_vector.i"
+ %include "std_pair.i"
  
  namespace std {
+   
      %template(VectorInt) vector<int>;
+     %template() std::pair<int,int>;
+     %template(PairVector) std::vector<std::pair<int,int> >;
  };
  
  
  /* Selection mode enumeration (corresponds to constants from the SALOME_Selection.h) */
- enum
+ enum SelectionMode
    {
-     Node,
+     Undefined = -1,
+     Node = 0,
      Cell,
      EdgeOfCell,
      Edge,
      Ball
    };
  
 +typedef struct
 +{
 +  double r, g, b;
 +  int delta;
 +} surfaceColorStruct;
 +
 +typedef struct
 +{
 +  double r, g, b;
 +  int delta;
 +} volumeColorStruct;
 +
 +typedef struct
 +{
 +  double r, g, b;
 +} edgeColorStruct;
 +
 +typedef struct
 +{
 +  double r, g, b;
 +} nodeColorStruct;
 +
 +struct actorAspect
 +{
 +  surfaceColorStruct surfaceColor;
 +  volumeColorStruct volumeColor;
 +  edgeColorStruct edgeColor;
 +  nodeColorStruct nodeColor;
 +  double opacity;
 +};
 +
  class SMESH_Swig
  {
   public:
  
    void CreateAndDisplayActor( const char* Mesh_Entry );
    void EraseActor( const char* Mesh_Entry, const bool allViewers = false );
+   void UpdateActor( const char* Mesh_Entry );
+   void setSelectionMode( SelectionMode selectionMode);
+   std::vector<int> getSelected( const char* Mesh_Entry );
+   std::vector<std::pair<int,int> > getSelectedEdgeOfCell( const char* Mesh_Entry );
  
 +  actorAspect GetActorAspect(const char* Mesh_Entry, int viewId = 0 );
 +  void SetActorAspect( const actorAspect& actorPres, const char* Mesh_Entry, int viewId = 0 );
 +
    // --------------------- for the test purposes -----------------------
-   int  getSelectionMode();
+   SelectionMode  getSelectionMode();
    void select( const char *id, std::vector<int> ids, bool append = false );
    void select( const char *id, int id1, bool append = false );
+   void select( const char *id, std::vector<std::pair<int,int> >, bool apend = false );
  
  };