VTK
dox/Charts/Core/vtkChartSelectionHelper.h
Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Visualization Toolkit
00004   Module:    vtkVector.h
00005 
00006   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
00007   All rights reserved.
00008   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
00009 
00010      This software is distributed WITHOUT ANY WARRANTY; without even
00011      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00012      PURPOSE.  See the above copyright notice for more information.
00013 
00014 =========================================================================*/
00015 
00026 #ifndef __vtkChartSelectionHelper_h
00027 #define __vtkChartSelectionHelper_h
00028 
00029 #include "vtkNew.h"
00030 #include "vtkSmartPointer.h"
00031 #include "vtkAnnotationLink.h"
00032 #include "vtkSelection.h"
00033 #include "vtkSelectionNode.h"
00034 #include "vtkIdTypeArray.h"
00035 #include "vtkContextScene.h"
00036 #include "vtkContextMouseEvent.h"
00037 #include "vtkInformation.h"
00038 #include "vtkPlot.h"
00039 #include "vtkTable.h"
00040 
00041 #include <vector>
00042 #include <algorithm>
00043 
00044 namespace vtkChartSelectionHelper
00045 {
00046 
00048 
00051 static void MakeSelection(vtkAnnotationLink *link, vtkIdTypeArray *selectionIds,
00052                           vtkPlot *plot)
00053 {
00054   assert(link != NULL && selectionIds != NULL);
00056 
00057   if (plot)
00058     {
00059     // We are building up plot-based selections, using multiple nodes.
00060     vtkSelection *selection = link->GetCurrentSelection();
00061     vtkSmartPointer<vtkSelectionNode> node;
00062     for (unsigned int i = 0; i < selection->GetNumberOfNodes(); ++i)
00063       {
00064       vtkSelectionNode *tmp = selection->GetNode(i);
00065       vtkPlot *selectionPlot =
00066           vtkPlot::SafeDownCast(tmp->GetProperties()->Get(vtkSelectionNode::PROP()));
00067       if (selectionPlot == plot)
00068         {
00069         node = tmp;
00070         break;
00071         }
00072       }
00073     if (!node)
00074       {
00075       node = vtkSmartPointer<vtkSelectionNode>::New();
00076       selection->AddNode(node.GetPointer());
00077       node->SetContentType(vtkSelectionNode::INDICES);
00078       node->SetFieldType(vtkSelectionNode::POINT);
00079       node->GetProperties()->Set(vtkSelectionNode::PROP(), plot);
00080       node->GetProperties()->Set(vtkSelectionNode::SOURCE(), plot->GetInput());
00081       }
00082     node->SetSelectionList(selectionIds);
00083     }
00084   else
00085     {
00086     // Use a simple single selection node layout, remove previous selections.
00087     vtkNew<vtkSelection> selection;
00088     vtkNew<vtkSelectionNode> node;
00089     selection->AddNode(node.GetPointer());
00090     node->SetContentType(vtkSelectionNode::INDICES);
00091     node->SetFieldType(vtkSelectionNode::POINT);
00092     node->SetSelectionList(selectionIds);
00093     link->SetCurrentSelection(selection.GetPointer());
00094     }
00095 }
00096 
00098 
00099 static void MinusSelection(vtkIdTypeArray *selection, vtkIdTypeArray *oldSelection)
00100 {
00101   // We rely on the selection id arrays being sorted.
00102   std::vector<vtkIdType> output;
00103   vtkIdType *ptrSelection =
00104       static_cast<vtkIdType *>(selection->GetVoidPointer(0));
00105   vtkIdType *ptrOldSelection =
00106       static_cast<vtkIdType *>(oldSelection->GetVoidPointer(0));
00107   vtkIdType oldSize = oldSelection->GetNumberOfTuples();
00108   vtkIdType size = selection->GetNumberOfTuples();
00109   vtkIdType i = 0;
00110   vtkIdType iOld = 0;
00112 
00113   while (i < size && iOld < oldSize)
00114     {
00115     if (ptrSelection[i] > ptrOldSelection[iOld]) // Skip the value.
00116       {
00117       output.push_back(ptrOldSelection[iOld++]);
00118       }
00119     else if (ptrSelection[i] == ptrOldSelection[iOld]) // Match - remove.
00120       {
00121       ++i;
00122       ++iOld;
00123       }
00124     else if (ptrSelection[i] < ptrOldSelection[iOld]) // Add the new value.
00125       {
00126       ++i;
00127       }
00128     }
00129   while (iOld < oldSize)
00130     {
00131     output.push_back(ptrOldSelection[iOld++]);
00132     }
00133   selection->SetNumberOfTuples(output.size());
00134   ptrSelection = static_cast<vtkIdType *>(selection->GetVoidPointer(0));
00135   for (std::vector<vtkIdType>::iterator it = output.begin();
00136        it != output.end(); ++it, ++ptrSelection)
00137     {
00138     *ptrSelection = *it;
00139     }
00140 }
00141 
00143 
00144 static void AddSelection(vtkIdTypeArray *selection, vtkIdTypeArray *oldSelection)
00145 {
00146   // Add all unique array indices to create a new combined array.
00147   vtkIdType *ptrSelection =
00148       static_cast<vtkIdType *>(selection->GetVoidPointer(0));
00149   vtkIdType *ptrOldSelection =
00150       static_cast<vtkIdType *>(oldSelection->GetVoidPointer(0));
00151   std::vector<vtkIdType> output(selection->GetNumberOfTuples()
00152                                 + oldSelection->GetNumberOfTuples());
00153   std::vector<vtkIdType>::iterator it;
00154   it = std::set_union(ptrSelection,
00155                       ptrSelection + selection->GetNumberOfTuples(),
00156                       ptrOldSelection,
00157                       ptrOldSelection + oldSelection->GetNumberOfTuples(),
00158                       output.begin());
00159   int newSize = int(it - output.begin());
00160   selection->SetNumberOfTuples(newSize);
00161   ptrSelection = static_cast<vtkIdType *>(selection->GetVoidPointer(0));
00162   for (std::vector<vtkIdType>::iterator i = output.begin(); i != it;
00163        ++i, ++ptrSelection)
00164     {
00165     *ptrSelection = *i;
00166     }
00167 }
00169 
00171 
00172 static void ToggleSelection(vtkIdTypeArray *selection, vtkIdTypeArray *oldSelection)
00173 {
00174   // We rely on the selection id arrays being sorted.
00175   std::vector<vtkIdType> output;
00176   vtkIdType *ptrSelection =
00177       static_cast<vtkIdType *>(selection->GetVoidPointer(0));
00178   vtkIdType *ptrOldSelection =
00179       static_cast<vtkIdType *>(oldSelection->GetVoidPointer(0));
00180   vtkIdType oldSize = oldSelection->GetNumberOfTuples();
00181   vtkIdType size = selection->GetNumberOfTuples();
00182   vtkIdType i = 0;
00183   vtkIdType iOld = 0;
00184   while (i < size && iOld < oldSize)
00185     {
00186     if (ptrSelection[i] > ptrOldSelection[iOld]) // Retain the value.
00187       {
00188       output.push_back(ptrOldSelection[iOld++]);
00189       }
00190     else if (ptrSelection[i] == ptrOldSelection[iOld]) // Match - toggle.
00191       {
00192       ++i;
00193       ++iOld;
00194       }
00195     else if (ptrSelection[i] < ptrOldSelection[iOld]) // Add the new value.
00196       {
00197       output.push_back(ptrSelection[i++]);
00198       }
00199     }
00200   while (i < size)
00201     {
00202     output.push_back(ptrSelection[i++]);
00203     }
00204   while (iOld < oldSize)
00205     {
00206     output.push_back(ptrOldSelection[iOld++]);
00207     }
00208   selection->SetNumberOfTuples(output.size());
00209   ptrSelection = static_cast<vtkIdType *>(selection->GetVoidPointer(0));
00210   for (std::vector<vtkIdType>::iterator it = output.begin();
00211        it != output.end(); ++it, ++ptrSelection)
00212     {
00213     *ptrSelection = *it;
00214     }
00215 }
00217 
00219 
00222 static void BuildSelection(vtkAnnotationLink *link, int selectionMode,
00223                            vtkIdTypeArray *plotSelection, vtkIdTypeArray *oldSelection,
00224                            vtkPlot *plot)
00225 {
00226   if (!plotSelection || !oldSelection)
00227     {
00228     return;
00229     }
00231 
00232   // Build a selection and set it on the annotation link if not null.
00233   switch(selectionMode)
00234     {
00235     case vtkContextScene::SELECTION_ADDITION:
00236       AddSelection(plotSelection, oldSelection);
00237       break;
00238     case vtkContextScene::SELECTION_SUBTRACTION:
00239       MinusSelection(plotSelection, oldSelection);
00240       break;
00241     case vtkContextScene::SELECTION_TOGGLE:
00242       ToggleSelection(plotSelection, oldSelection);
00243       break;
00244     case vtkContextScene::SELECTION_DEFAULT:
00245     default:
00246       // Nothing necessary - overwrite the old selection.
00247       break;
00248     }
00249 
00250   if (link)
00251     {
00252     MakeSelection(link, plotSelection, plot);
00253     }
00254 }
00255 
00257 
00259 static int GetMouseSelectionMode(const vtkContextMouseEvent &mouse, int selectionMode)
00260 {
00261   // Mouse modifiers override the current selection mode.
00262   if (mouse.GetModifiers() & vtkContextMouseEvent::SHIFT_MODIFIER &&
00263       mouse.GetModifiers() & vtkContextMouseEvent::CONTROL_MODIFIER)
00264     {
00265     return vtkContextScene::SELECTION_TOGGLE;
00266     }
00267   else if (mouse.GetModifiers() & vtkContextMouseEvent::CONTROL_MODIFIER)
00268     {
00269     return vtkContextScene::SELECTION_ADDITION;
00270     }
00271   else if (mouse.GetModifiers() & vtkContextMouseEvent::SHIFT_MODIFIER)
00272     {
00273     return vtkContextScene::SELECTION_SUBTRACTION;
00274     }
00275   return selectionMode;
00276 }
00278 
00279 } // End vtkChartSelectionHelper namespace
00280 
00281 #endif // __vtkChartSelectionHelper_h
00282 // VTK-HeaderTest-Exclude: vtkChartSelectionHelper.h