X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSVTK%2FSVTK_Selector.cxx;h=fe5a930470c1bbf2c9585722dacbe98c23e1624a;hb=f830c97c748d8f8a6a7eccc8e3a58e19066a1181;hp=63a28eab0ded281e8413c86f9bba7237c799a8c4;hpb=57886dd1cb61045824b0e76e5f83cb6479aaca4c;p=modules%2Fgui.git diff --git a/src/SVTK/SVTK_Selector.cxx b/src/SVTK/SVTK_Selector.cxx index 63a28eab0..fe5a93047 100644 --- a/src/SVTK/SVTK_Selector.cxx +++ b/src/SVTK/SVTK_Selector.cxx @@ -17,7 +17,7 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // // @@ -27,198 +27,292 @@ // $Header$ +#include "SVTK_SelectorDef.h" + +#include "SALOME_Actor.h" + #include #include +#include +#include +#include -#include "SALOME_Actor.h" -#include "SVTK_ViewModel.h" -#include "SVTK_ViewWindow.h" -#include "SALOME_ListIteratorOfListIO.hxx" -#include "SVTK_Selector.h" -#include "utilities.h" +/*! + Find first SALOME_Actor from the end of actors collection +*/ +inline +SALOME_Actor* +GetLastSALOMEActor(vtkActorCollection* theCollection) +{ + if (theCollection) { + for (int i = theCollection->GetNumberOfItems() - 1; i >= 0; i--) { + if (SALOME_Actor* anActor = dynamic_cast(theCollection->GetItemAsObject(i))) + if (anActor->hasIO()) + return anActor; + } + } + return NULL; +} + +/*! + \return new SVTK_Selector +*/ +SVTK_Selector* SVTK_Selector -::SVTK_Selector() +::New() { + return new SVTK_SelectorDef(); } -SVTK_Selector -::~SVTK_Selector() +/*! + Default constructor +*/ +SVTK_SelectorDef +::SVTK_SelectorDef(): + myPicker(vtkPicker::New()), + myCellPicker(vtkCellPicker::New()) +{ + mySelectionMode = ActorSelection; + + myPicker->Delete(); + myCellPicker->Delete(); +} + +/*! + Destructor +*/ +SVTK_SelectorDef +::~SVTK_SelectorDef() { } +/*! + To invoke selectionChanged signals +*/ void -SVTK_Selector +SVTK_SelectorDef +::StartPickCallback() +{ + this->InvokeEvent(vtkCommand::StartPickEvent,NULL); +} + +/*! + To invoke selectionChanged signals +*/ +void +SVTK_SelectorDef +::EndPickCallback() +{ + this->InvokeEvent(vtkCommand::EndPickEvent,NULL); +} + +/*! + To change current Selection_Mode (as outside effect, it invokes selectionChange signal) +*/ +void +SVTK_SelectorDef ::SetSelectionMode(Selection_Mode theMode) { - mySelectionMode = theMode; + if(mySelectionMode != theMode){ + mySelectionMode = theMode; + myMapIOSubIndex.clear(); + this->EndPickCallback(); + } } +/*! + Clear selection +*/ void -SVTK_Selector +SVTK_SelectorDef ::ClearIObjects() { - myIO2Actors.Clear(); - myIObjects.Clear(); - myMapIOSubIndex.Clear(); + myIO2Actors.clear(); + myIObjects.clear(); + myMapIOSubIndex.clear(); } -//---------------------------------------------------------------------------- +/*! + \return true if the SALOME_InteractiveObject presents into selection +*/ bool -SVTK_Selector -::IsSelected(const Handle(SALOME_InteractiveObject)& theObject) const +SVTK_SelectorDef +::IsSelected(const Handle(SALOME_InteractiveObject)& theIO) const { - SALOME_ListIteratorOfListIO anIter(myIObjects); - for(; anIter.More(); anIter.Next()){ - if(theObject->isSame(anIter.Value())){ - return true; - } - } - return false; + return !theIO.IsNull() && (myIObjects.find(theIO) != myIObjects.end()); } +/*! + \return true if the SALOME_Actor presents into selection +*/ bool -SVTK_Selector +SVTK_SelectorDef ::IsSelected(SALOME_Actor* theActor) const { const Handle(SALOME_InteractiveObject) anIO = theActor->getIO(); - return IsSelected(anIO) && myIO2Actors.IsBound(anIO); + return IsSelected(anIO) && myIO2Actors.find(anIO) != myIO2Actors.end(); } +/*! + \return corresponding SALOME_Actor for SALOME_InteractiveObject + \param theIO - SALOME_InteractiveObject +*/ SALOME_Actor* -SVTK_Selector +SVTK_SelectorDef ::GetActor(const Handle(SALOME_InteractiveObject)& theIO) const { - if(myIO2Actors.IsBound(theIO)) - return myIO2Actors.Find(theIO).GetPointer(); + TIO2Actors::const_iterator anIter = myIO2Actors.find(theIO); + if(anIter != myIO2Actors.end()) + return anIter->second.GetPointer(); return NULL; } -//---------------------------------------------------------------------------- +/*! + Adds SALOME_InteractiveObject into selection + \param theIO - SALOME_InteractiveObject +*/ bool -SVTK_Selector +SVTK_SelectorDef ::AddIObject(const Handle(SALOME_InteractiveObject)& theIO) { if(!IsSelected(theIO)){ - myIObjects.Append(theIO); + myIObjects.insert(theIO); return true; } return false; } +/*! + Adds SALOME_Actor into selection + \param theActor - SALOME_Actor +*/ bool -SVTK_Selector +SVTK_SelectorDef ::AddIObject(SALOME_Actor* theActor) { const Handle(SALOME_InteractiveObject) anIO = theActor->getIO(); bool anIsIOBound = IsSelected(anIO); if(!anIsIOBound) - myIObjects.Append(anIO); + myIObjects.insert(anIO); - bool anIsActorBound = myIO2Actors.IsBound(anIO); + bool anIsActorBound = myIO2Actors.find(anIO) != myIO2Actors.end(); if(!anIsActorBound) - myIO2Actors.Bind(anIO,theActor); + myIO2Actors[anIO] = theActor; return !anIsIOBound || !anIsActorBound; } -//---------------------------------------------------------------------------- +/*! + Removes SALOME_InteractiveObject from selection + \param theIO - SALOME_InteractiveObject +*/ bool -SVTK_Selector +SVTK_SelectorDef ::RemoveIObject(const Handle(SALOME_InteractiveObject)& theIO) { - bool anIsIOBound = false; - for(SALOME_ListIteratorOfListIO anIter(myIObjects); anIter.More(); anIter.Next()){ - if(theIO->isSame(anIter.Value())){ - if(myMapIOSubIndex.IsBound(theIO)) - myMapIOSubIndex.UnBind(theIO); - myIObjects.Remove(anIter); - anIsIOBound = true; - } - } + bool anIsIOBound = myIObjects.find(theIO) != myIObjects.end(); - bool anIsActorBound = myIO2Actors.IsBound(theIO); - if(anIsActorBound) - myIO2Actors.UnBind(theIO); + myIObjects.erase(theIO); + myIO2Actors.erase(theIO); + myMapIOSubIndex.erase(theIO); - return anIsIOBound || anIsActorBound; + return anIsIOBound; } +/*! + Removes SALOME_Actor from selection + \param theActor - SALOME_Actor +*/ bool -SVTK_Selector +SVTK_SelectorDef ::RemoveIObject(SALOME_Actor* theActor) { const Handle(SALOME_InteractiveObject) anIO = theActor->getIO(); - bool anIsActorBound = myIO2Actors.IsBound(anIO); + bool anIsActorBound = myIO2Actors.find(anIO) != myIO2Actors.end(); if(anIsActorBound) - myIO2Actors.UnBind(anIO); - - bool anIsIOBound = false; - for(SALOME_ListIteratorOfListIO anIter(myIObjects); anIter.More(); anIter.Next()){ - if(anIO->isSame(anIter.Value())){ - if(myMapIOSubIndex.IsBound(anIO)) - myMapIOSubIndex.UnBind(anIO); - myIObjects.Remove(anIter); - anIsIOBound = true; - } - } + myIO2Actors.erase(anIO); - return anIsIOBound || anIsActorBound; + return RemoveIObject(anIO) || anIsActorBound; } -//---------------------------------------------------------------------------- +/*! + \return list of all SALOME_InteractiveObject presenting in selection +*/ const SALOME_ListIO& -SVTK_Selector +SVTK_SelectorDef ::StoredIObjects() const { - return myIObjects; + myIObjectList.Clear(); + TIObjects::const_iterator anIter = myIObjects.begin(); + TIObjects::const_iterator anIterEnd = myIObjects.end(); + for(; anIter != anIterEnd; anIter++) + myIObjectList.Append(*anIter); + + return myIObjectList; } +/*! + \return number of selected objects +*/ int -SVTK_Selector +SVTK_SelectorDef ::IObjectCount() const { - return myIObjects.Extent(); + return myIObjects.size(); } +/*! + \return true if the SALOME_InteractiveObject has a subselection + \param theIO - SALOME_InteractiveObject +*/ bool -SVTK_Selector +SVTK_SelectorDef ::HasIndex( const Handle(SALOME_InteractiveObject)& theIO) const { - return myMapIOSubIndex.IsBound(theIO); + return myMapIOSubIndex.find(theIO) != myMapIOSubIndex.end(); } +/*! + Gets indices of subselection for SALOME_InteractiveObject + \param theIO - SALOME_InteractiveObject +*/ void -SVTK_Selector +SVTK_SelectorDef ::GetIndex( const Handle(SALOME_InteractiveObject)& theIO, TColStd_IndexedMapOfInteger& theIndex) { - if(myMapIOSubIndex.IsBound(theIO)) - theIndex = myMapIOSubIndex.Find(theIO); + TMapIOSubIndex::const_iterator anIter = myMapIOSubIndex.find(theIO); + if(anIter != myMapIOSubIndex.end()) + theIndex = anIter->second.myMap; else theIndex.Clear(); } +/*! + \return true if the index presents in subselection + \param theIO - SALOME_InteractiveObject + \param theIndex - index +*/ bool -SVTK_Selector +SVTK_SelectorDef ::IsIndexSelected(const Handle(SALOME_InteractiveObject)& theIO, int theIndex) const { - if( !myMapIOSubIndex.IsBound(theIO)) - return false; + TMapIOSubIndex::const_iterator anIter = myMapIOSubIndex.find(theIO); + if(anIter != myMapIOSubIndex.end()){ + const TColStd_IndexedMapOfInteger& aMapIndex = anIter->second.myMap; + return aMapIndex.Contains( theIndex ) == Standard_True; + } - const TColStd_IndexedMapOfInteger& aMapIndex = myMapIOSubIndex.Find(theIO); - return aMapIndex.Contains(theIndex); + return false; } -static -bool -removeIndex(TColStd_IndexedMapOfInteger& theMapIndex, - const int theIndex) +static bool removeIndex(TColStd_IndexedMapOfInteger& theMapIndex, const int theIndex) { int anId = theMapIndex.FindIndex(theIndex); // i==0 if Index is not in the MapIndex if(anId){ @@ -237,108 +331,244 @@ removeIndex(TColStd_IndexedMapOfInteger& theMapIndex, theMapIndex = aNewMap; } } - return anId; + return anId != 0; } - +/*! + Changes indices of subselection for SALOME_InteractiveObject + \param theIO - SALOME_InteractiveObject + \param theIndices - indices + \param theIsModeShift - if it is false, then map will be cleared before indices are added +*/ bool -SVTK_Selector +SVTK_SelectorDef ::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& theIO, const TColStd_IndexedMapOfInteger& theIndices, bool theIsModeShift) { - TColStd_IndexedMapOfInteger empty; - if(!myMapIOSubIndex.IsBound(theIO)) - myMapIOSubIndex.Bind(theIO, empty); - - TColStd_IndexedMapOfInteger& aMapIndex = myMapIOSubIndex.ChangeFind(theIO); - aMapIndex = theIndices; + TMapIOSubIndex::iterator aMapIter = myMapIOSubIndex.find(theIO); + if(aMapIter == myMapIOSubIndex.end()){ + TIndexedMapOfInteger anEmpty; + aMapIter = myMapIOSubIndex. + insert(TMapIOSubIndex::value_type(theIO,anEmpty)).first; + } + TColStd_IndexedMapOfInteger& aMapIndex = aMapIter->second.myMap; if(!theIsModeShift) aMapIndex.Clear(); - if(aMapIndex.IsEmpty()){ - myMapIOSubIndex.UnBind(theIO); - RemoveIObject(theIO); + for(int i = 1, iEnd = theIndices.Extent(); i <= iEnd; i++) + aMapIndex.Add(theIndices(i)); + + if(aMapIndex.IsEmpty()) { + myMapIOSubIndex.erase(theIO); + return false; } - return !aMapIndex.IsEmpty(); + return true; } +/*! + Changes indices of subselection for SALOME_InteractiveObject + \param theIO - SALOME_InteractiveObject + \param theIndices - indices + \param theIsModeShift - if it is false, then map will be cleared before indices are added +*/ bool -SVTK_Selector +SVTK_SelectorDef ::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& theIO, const TColStd_MapOfInteger& theIndices, bool theIsModeShift) { - TColStd_IndexedMapOfInteger empty; - if(!myMapIOSubIndex.IsBound(theIO)) - myMapIOSubIndex.Bind(theIO, empty); - - TColStd_IndexedMapOfInteger& aMapIndex = myMapIOSubIndex.ChangeFind(theIO); + TMapIOSubIndex::iterator aMapIter = myMapIOSubIndex.find(theIO); + if(aMapIter == myMapIOSubIndex.end()){ + TIndexedMapOfInteger anEmpty; + aMapIter = myMapIOSubIndex. + insert(TMapIOSubIndex::value_type(theIO,anEmpty)).first; + } + TColStd_IndexedMapOfInteger& aMapIndex = aMapIter->second.myMap; if(!theIsModeShift) aMapIndex.Clear(); - for(TColStd_MapIteratorOfMapOfInteger anIter(theIndices); anIter.More(); anIter.Next()) + TColStd_MapIteratorOfMapOfInteger anIter(theIndices); + for(; anIter.More(); anIter.Next()) aMapIndex.Add(anIter.Key()); - if(aMapIndex.IsEmpty()){ - myMapIOSubIndex.UnBind(theIO); - RemoveIObject(theIO); + if(aMapIndex.IsEmpty()) { + myMapIOSubIndex.erase(theIO); + return false; } - return !aMapIndex.IsEmpty(); + return true; } +/*! + Changes indices of subselection for SALOME_InteractiveObject + \param theIO - SALOME_InteractiveObject + \param theIndex - index + \param theIsModeShift - if it is false, then map will be cleared before indices are added +*/ bool -SVTK_Selector +SVTK_SelectorDef ::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& theIO, int theIndex, bool theIsModeShift) { - TColStd_IndexedMapOfInteger empty; - if(!myMapIOSubIndex.IsBound(theIO)) - myMapIOSubIndex.Bind(theIO, empty); - - TColStd_IndexedMapOfInteger& aMapIndex = myMapIOSubIndex.ChangeFind(theIO); - - bool anIsConatains = aMapIndex.Contains( theIndex ); + TMapIOSubIndex::iterator anIter = myMapIOSubIndex.find(theIO); + if(anIter == myMapIOSubIndex.end()){ + TIndexedMapOfInteger anEmpty; + anIter = myMapIOSubIndex. + insert(TMapIOSubIndex::value_type(theIO,anEmpty)).first; + } + TColStd_IndexedMapOfInteger& aMapIndex = anIter->second.myMap; - if (anIsConatains) + bool anIsConatains = aMapIndex.Contains( theIndex ) == Standard_True; + if ( anIsConatains ) removeIndex( aMapIndex, theIndex ); - if (!theIsModeShift) + if ( !theIsModeShift ) aMapIndex.Clear(); - if(!anIsConatains) + if ( !anIsConatains ) aMapIndex.Add( theIndex ); - if ( aMapIndex.IsEmpty() ) { - myMapIOSubIndex.UnBind(theIO); - RemoveIObject(theIO); - } + if ( aMapIndex.IsEmpty() ) + myMapIOSubIndex.erase( theIO ); return false; } +/*! + Removes index of subselection for SALOME_InteractiveObject + \param theIO - SALOME_InteractiveObject + \param theIndex - index +*/ void -SVTK_Selector +SVTK_SelectorDef ::RemoveIndex( const Handle(SALOME_InteractiveObject)& theIO, int theIndex) { - if ( myMapIOSubIndex.IsBound( theIO ) ) { - TColStd_IndexedMapOfInteger& aMapIndex = myMapIOSubIndex.ChangeFind( theIO ); - removeIndex( aMapIndex, theIndex ); + if(IsIndexSelected(theIO,theIndex)){ + TMapIOSubIndex::iterator anIter = myMapIOSubIndex.find(theIO); + TColStd_IndexedMapOfInteger& aMapIndex = anIter->second.myMap; + removeIndex(aMapIndex,theIndex); } } +/*! + Clears all indices of subselection +*/ void -SVTK_Selector +SVTK_SelectorDef ::ClearIndex() { - myMapIOSubIndex.Clear(); + myMapIOSubIndex.clear(); +} + +/*! + To apply a filter on the selection + \param theFilter - new filter +*/ +void +SVTK_SelectorDef +::SetFilter(const Handle(VTKViewer_Filter)& theFilter) +{ + myFilters.insert(TFilters::value_type(theFilter->GetId(),theFilter)); +} + +/*! + \return true if filter with given number is applyed + \param theId - filter id +*/ +bool +SVTK_SelectorDef +::IsFilterPresent(const TFilterID theId) const +{ + return myFilters.find(theId) != myFilters.end(); +} + +/*! + To remove a filter from the selection + \param theId - filter id +*/ +void +SVTK_SelectorDef +::RemoveFilter(const TFilterID theId) +{ + if(IsFilterPresent(theId)) + myFilters.erase(theId); +} + +/*! + \return true if the index satisfy installed filters + \param theActor - actor + \param theId - filter id + \param theIsNode - whether it is node +*/ +bool +SVTK_SelectorDef +::IsValid(SALOME_Actor* theActor, + const TFilterID theId, + const bool theIsNode) const +{ + TFilters::const_iterator anIter = myFilters.begin(); + for(; anIter != myFilters.end(); ++anIter){ + const Handle(VTKViewer_Filter)& aFilter = anIter->second; + if(theIsNode == aFilter->IsNodeFilter() && + !aFilter->IsValid(theActor,theId)) + return false; + } + return true; +} + +/*! + \return filter by it's id + \param theId - filter id +*/ +Handle(VTKViewer_Filter) +SVTK_SelectorDef +::GetFilter(const TFilterID theId) const +{ + TFilters::const_iterator anIter = myFilters.find(theId); + if(anIter != myFilters.end()){ + const Handle(VTKViewer_Filter)& aFilter = anIter->second; + return aFilter; + } + return Handle(VTKViewer_Filter)(); +} + +SALOME_Actor* +SVTK_SelectorDef +::Pick(const SVTK_SelectionEvent* theEvent, vtkRenderer* theRenderer) const +{ + myCellPicker->Pick(theEvent->myX, + theEvent->myY, + 0.0, + theRenderer); + + vtkActorCollection* aListActors = myCellPicker->GetActors(); + SALOME_Actor* anActor = GetLastSALOMEActor(aListActors); + + if (! anActor) { + myPicker->Pick(theEvent->myX, + theEvent->myY, + 0.0, + theRenderer); + aListActors = myPicker->GetActors(); + anActor = GetLastSALOMEActor(aListActors); + } + + return anActor; +} + +void +SVTK_SelectorDef +::SetTolerance(const double& theTolerance) +{ + myPicker->SetTolerance(theTolerance); + myCellPicker->SetTolerance(theTolerance); }