Back to index

salome-gui  6.5.0
SVTK_Selector.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  SALOME SALOMEGUI : implementation of desktop and GUI kernel
00024 //  File   : SALOME_Selection.cxx
00025 //  Author : Nicolas REJNERI
00026 
00027 #include "SVTK_SelectorDef.h"
00028 
00029 #include <VTKViewer_Filter.h>
00030 
00031 #include "SALOME_Actor.h"
00032 
00033 #include <SUIT_Session.h>
00034 #include <SUIT_ResourceMgr.h>
00035 
00036 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
00037 #include <TColStd_IndexedMapOfInteger.hxx>
00038 
00039 #include <vtkCallbackCommand.h>
00040 #include <vtkActorCollection.h>
00041 #include <vtkCellPicker.h>
00042 
00043 
00047 SVTK_Selector* 
00048 SVTK_Selector
00049 ::New()
00050 {
00051   return new SVTK_SelectorDef();
00052 }
00053 
00057 SVTK_SelectorDef
00058 ::SVTK_SelectorDef():
00059   myPicker(vtkPicker::New()),
00060   myCellPicker(vtkCellPicker::New())
00061 {
00062   mySelectionMode = ActorSelection;
00063   myDynamicPreselection = true;
00064 
00065   myPicker->Delete();
00066   myCellPicker->Delete();
00067 }
00068 
00072 SVTK_SelectorDef
00073 ::~SVTK_SelectorDef()
00074 {
00075 }
00076 
00080 void 
00081 SVTK_SelectorDef
00082 ::StartPickCallback()
00083 {
00084   this->InvokeEvent(vtkCommand::StartPickEvent,NULL);
00085 }
00086 
00090 void 
00091 SVTK_SelectorDef
00092 ::EndPickCallback()
00093 {
00094   this->InvokeEvent(vtkCommand::EndPickEvent,NULL);
00095 }
00096 
00100 void 
00101 SVTK_SelectorDef
00102 ::SetSelectionMode(Selection_Mode theMode)
00103 {
00104   if(mySelectionMode != theMode){
00105     mySelectionMode = theMode;
00106     myMapIOSubIndex.clear();
00107     this->EndPickCallback();
00108   }
00109 }
00110 
00114 void 
00115 SVTK_SelectorDef
00116 ::ClearIObjects() 
00117 {
00118   myIO2Actors.clear();
00119   myIObjects.clear();
00120   myMapIOSubIndex.clear();
00121 }
00122 
00126 bool
00127 SVTK_SelectorDef
00128 ::IsSelected(const Handle(SALOME_InteractiveObject)& theIO) const
00129 {
00130   return !theIO.IsNull() && (myIObjects.find(theIO) != myIObjects.end());
00131 }
00132 
00136 bool
00137 SVTK_SelectorDef
00138 ::IsSelected(SALOME_Actor* theActor) const
00139 {
00140   const Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
00141   return IsSelected(anIO) && myIO2Actors.find(anIO) != myIO2Actors.end();
00142 }
00143 
00148 SALOME_Actor*
00149 SVTK_SelectorDef
00150 ::GetActor(const Handle(SALOME_InteractiveObject)& theIO) const
00151 {
00152   TIO2Actors::const_iterator anIter = myIO2Actors.find(theIO);
00153   if(anIter != myIO2Actors.end())
00154     return anIter->second.GetPointer();
00155   return NULL;
00156 }
00157 
00162 bool 
00163 SVTK_SelectorDef
00164 ::AddIObject(const Handle(SALOME_InteractiveObject)& theIO) 
00165 {
00166   if(!IsSelected(theIO)){
00167     myIObjects.insert(theIO);
00168     return true;
00169   }
00170   return false;
00171 }
00172 
00177 bool 
00178 SVTK_SelectorDef
00179 ::AddIObject(SALOME_Actor* theActor) 
00180 {
00181   const Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
00182 
00183   bool anIsIOBound = IsSelected(anIO);
00184   if(!anIsIOBound)
00185     myIObjects.insert(anIO);
00186 
00187   bool anIsActorBound = myIO2Actors.find(anIO) != myIO2Actors.end();
00188   if(!anIsActorBound)
00189     myIO2Actors[anIO] = theActor;
00190   
00191   return !anIsIOBound || !anIsActorBound;
00192 }
00193 
00198 bool 
00199 SVTK_SelectorDef
00200 ::RemoveIObject(const Handle(SALOME_InteractiveObject)& theIO) 
00201 {
00202   bool anIsIOBound = myIObjects.find(theIO) != myIObjects.end();
00203 
00204   myIObjects.erase(theIO);
00205   myIO2Actors.erase(theIO);
00206   myMapIOSubIndex.erase(theIO);
00207 
00208   return anIsIOBound;
00209 }
00210 
00215 bool 
00216 SVTK_SelectorDef
00217 ::RemoveIObject(SALOME_Actor* theActor) 
00218 {
00219   const Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
00220 
00221   bool anIsActorBound = myIO2Actors.find(anIO) != myIO2Actors.end();
00222   if(anIsActorBound)
00223     myIO2Actors.erase(anIO);
00224 
00225   return RemoveIObject(anIO) || anIsActorBound;
00226 }
00227 
00231 const SALOME_ListIO& 
00232 SVTK_SelectorDef
00233 ::StoredIObjects() const
00234 {
00235   myIObjectList.Clear();
00236   TIObjects::const_iterator anIter = myIObjects.begin();
00237   TIObjects::const_iterator anIterEnd = myIObjects.end();
00238   for(; anIter != anIterEnd; anIter++)
00239     myIObjectList.Append(*anIter);
00240 
00241   return myIObjectList;
00242 }
00243 
00247 int
00248 SVTK_SelectorDef
00249 ::IObjectCount() const
00250 {
00251   return myIObjects.size();
00252 }
00253 
00258 bool 
00259 SVTK_SelectorDef
00260 ::HasIndex( const Handle(SALOME_InteractiveObject)& theIO) const
00261 {
00262   return myMapIOSubIndex.find(theIO) != myMapIOSubIndex.end();
00263 }
00264 
00269 void 
00270 SVTK_SelectorDef
00271 ::GetIndex( const Handle(SALOME_InteractiveObject)& theIO, 
00272             TColStd_IndexedMapOfInteger& theIndex)
00273 {
00274   TMapIOSubIndex::const_iterator anIter = myMapIOSubIndex.find(theIO);
00275   if(anIter != myMapIOSubIndex.end())
00276     theIndex = anIter->second.myMap;
00277   else
00278     theIndex.Clear();
00279 }
00280 
00286 bool
00287 SVTK_SelectorDef
00288 ::IsIndexSelected(const Handle(SALOME_InteractiveObject)& theIO, 
00289                   int theIndex) const
00290 {
00291   TMapIOSubIndex::const_iterator anIter = myMapIOSubIndex.find(theIO);
00292   if(anIter != myMapIOSubIndex.end()){
00293     const TColStd_IndexedMapOfInteger& aMapIndex = anIter->second.myMap;
00294     return aMapIndex.Contains( theIndex ) == Standard_True;
00295   }
00296 
00297   return false;
00298 }
00299 
00300 static bool removeIndex(TColStd_IndexedMapOfInteger& theMapIndex, const int theIndex)
00301 {
00302   int anId = theMapIndex.FindIndex(theIndex); // i==0 if Index is not in the MapIndex
00303   if(anId){
00304     // only the last key can be removed
00305     int aLastId = theMapIndex.FindKey(theMapIndex.Extent());
00306     if(aLastId == anId)
00307       theMapIndex.RemoveLast();
00308     else{
00309       TColStd_IndexedMapOfInteger aNewMap;
00310       aNewMap.ReSize(theMapIndex.Extent()-1);
00311       for(int j = 1; j <= theMapIndex.Extent(); j++){
00312         int anIndex = theMapIndex(j);
00313         if ( anIndex != theIndex )
00314           aNewMap.Add( anIndex );
00315       }
00316       theMapIndex = aNewMap;
00317     }
00318   }
00319   return anId != 0;
00320 }
00321 
00328 bool
00329 SVTK_SelectorDef
00330 ::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& theIO, 
00331                     const TColStd_IndexedMapOfInteger& theIndices, 
00332                     bool theIsModeShift)
00333 {
00334   TMapIOSubIndex::iterator aMapIter = myMapIOSubIndex.find(theIO);
00335   if(aMapIter == myMapIOSubIndex.end()){
00336     TIndexedMapOfInteger anEmpty;
00337     aMapIter = myMapIOSubIndex.
00338       insert(TMapIOSubIndex::value_type(theIO,anEmpty)).first;
00339   }
00340   TColStd_IndexedMapOfInteger& aMapIndex = aMapIter->second.myMap;
00341 
00342   if(!theIsModeShift)
00343     aMapIndex.Clear();
00344   
00345   for(int i = 1, iEnd = theIndices.Extent(); i <= iEnd; i++)
00346     aMapIndex.Add(theIndices(i));
00347   
00348   if(aMapIndex.IsEmpty()) {
00349     myMapIOSubIndex.erase(theIO);
00350     return false;
00351   }
00352 
00353   return true;
00354 }
00355 
00356 
00363 bool
00364 SVTK_SelectorDef
00365 ::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& theIO, 
00366                     const TColStd_MapOfInteger& theIndices, 
00367                     bool theIsModeShift)
00368 {
00369   TMapIOSubIndex::iterator aMapIter = myMapIOSubIndex.find(theIO);
00370   if(aMapIter == myMapIOSubIndex.end()){
00371     TIndexedMapOfInteger anEmpty;
00372     aMapIter = myMapIOSubIndex.
00373       insert(TMapIOSubIndex::value_type(theIO,anEmpty)).first;
00374   }
00375   TColStd_IndexedMapOfInteger& aMapIndex = aMapIter->second.myMap;
00376 
00377   if(!theIsModeShift)
00378     aMapIndex.Clear();
00379   
00380   TColStd_MapIteratorOfMapOfInteger anIter(theIndices);
00381   for(; anIter.More(); anIter.Next())
00382     aMapIndex.Add(anIter.Key());
00383   
00384   if(aMapIndex.IsEmpty()) {
00385     myMapIOSubIndex.erase(theIO);
00386     return false;
00387   }
00388 
00389   return true;
00390 }
00391 
00392 
00399 bool 
00400 SVTK_SelectorDef
00401 ::AddOrRemoveIndex( const Handle(SALOME_InteractiveObject)& theIO, 
00402                     int theIndex, 
00403                     bool theIsModeShift)
00404 {
00405   TMapIOSubIndex::iterator anIter = myMapIOSubIndex.find(theIO);
00406   if(anIter == myMapIOSubIndex.end()){
00407     TIndexedMapOfInteger anEmpty;
00408     anIter = myMapIOSubIndex.
00409       insert(TMapIOSubIndex::value_type(theIO,anEmpty)).first;
00410   }
00411   TColStd_IndexedMapOfInteger& aMapIndex = anIter->second.myMap;
00412 
00413   bool anIsConatains = aMapIndex.Contains( theIndex ) == Standard_True;
00414   if ( anIsConatains )
00415     removeIndex( aMapIndex, theIndex );
00416   
00417   if ( !theIsModeShift )
00418     aMapIndex.Clear();
00419   
00420   if ( !anIsConatains )
00421     aMapIndex.Add( theIndex );
00422 
00423   if ( aMapIndex.IsEmpty() )
00424     myMapIOSubIndex.erase( theIO );
00425 
00426   return false;
00427 }
00428 
00429 
00435 void
00436 SVTK_SelectorDef
00437 ::RemoveIndex( const Handle(SALOME_InteractiveObject)& theIO, 
00438                int theIndex)
00439 {
00440   if(IsIndexSelected(theIO,theIndex)){
00441     TMapIOSubIndex::iterator anIter = myMapIOSubIndex.find(theIO);
00442     TColStd_IndexedMapOfInteger& aMapIndex = anIter->second.myMap;
00443     removeIndex(aMapIndex,theIndex);
00444   }
00445 }
00446 
00450 void 
00451 SVTK_SelectorDef
00452 ::ClearIndex()
00453 {
00454   myMapIOSubIndex.clear();  
00455 }
00456 
00461 void
00462 SVTK_SelectorDef
00463 ::SetFilter(const Handle(VTKViewer_Filter)& theFilter)
00464 {
00465   myFilters.insert(TFilters::value_type(theFilter->GetId(),theFilter));
00466 }
00467 
00472 bool
00473 SVTK_SelectorDef
00474 ::IsFilterPresent(const TFilterID theId) const
00475 {
00476   return myFilters.find(theId) != myFilters.end();
00477 }
00478 
00483 void  
00484 SVTK_SelectorDef
00485 ::RemoveFilter(const TFilterID theId)
00486 {
00487   if(IsFilterPresent(theId))
00488     myFilters.erase(theId);
00489 }
00490 
00497 bool
00498 SVTK_SelectorDef
00499 ::IsValid(SALOME_Actor* theActor,
00500           const TFilterID theId,
00501           const bool theIsNode) const
00502 {
00503   TFilters::const_iterator anIter = myFilters.begin();
00504   for(; anIter != myFilters.end(); ++anIter){
00505     const Handle(VTKViewer_Filter)& aFilter = anIter->second;
00506     if(theIsNode == aFilter->IsNodeFilter() &&
00507        !aFilter->IsValid(theActor,theId))
00508       return false;
00509   }
00510   return true;
00511 }
00512 
00517 Handle(VTKViewer_Filter) 
00518 SVTK_SelectorDef
00519 ::GetFilter(const TFilterID theId) const
00520 {
00521   TFilters::const_iterator anIter = myFilters.find(theId);
00522   if(anIter != myFilters.end()){
00523     const Handle(VTKViewer_Filter)& aFilter = anIter->second;
00524     return aFilter;
00525   }
00526   return Handle(VTKViewer_Filter)();
00527 }
00528 
00529 vtkActorCollection*
00530 SVTK_SelectorDef
00531 ::Pick(const SVTK_SelectionEvent* theEvent, vtkRenderer* theRenderer) const
00532 {
00533   vtkActorCollection* aListActors = NULL;
00534 
00535   if ( GetDynamicPreSelection() ) {
00536     myCellPicker->Pick(theEvent->myX,
00537                        theEvent->myY, 
00538                        0.0,
00539                        theRenderer);
00540   
00541     aListActors = myCellPicker->GetActors();
00542   }
00543 
00544   if ( !aListActors || !aListActors->GetNumberOfItems() ) {
00545     myPicker->Pick(theEvent->myX,
00546                    theEvent->myY, 
00547                    0.0,
00548                    theRenderer);
00549     aListActors = myPicker->GetActors();
00550   }
00551   
00552   return aListActors;
00553 }
00554 
00555 void
00556 SVTK_SelectorDef
00557 ::SetTolerance(const double& theTolerance) 
00558 {
00559   myPicker->SetTolerance(theTolerance);         
00560   myCellPicker->SetTolerance(theTolerance);
00561 }
00562 
00563 void
00564 SVTK_SelectorDef
00565 ::SetDynamicPreSelection( bool theIsDynPreselect )
00566 {
00567   myDynamicPreselection = theIsDynPreselect;
00568 }
00569 
00570 bool
00571 SVTK_SelectorDef
00572 ::GetDynamicPreSelection() const
00573 {
00574   return myDynamicPreselection;
00575 }