VTK
|
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