1 /*=========================================================================
2
3 Program: Visualization Toolkit
4
5 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
6 All rights reserved.
7 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
8
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the above copyright notice for more information.
12
13 =========================================================================*/
14
15
16 // This tests vtkVisibleCellSelector, vtkExtractSelectedFrustum,
17 // vtkRenderedAreaPicker, and vtkInteractorStyleRubberBandPick.
18 //
19 // The command line arguments are:
20 // -I => run in interactive mode; unless this is used, the program will
21 // not allow interaction and exit
22
23 #include "vtkTestUtilities.h"
24 #include "vtkRegressionTestImage.h"
25
26 #include "vtkRenderer.h"
27 #include "vtkRenderWindow.h"
28 #include "vtkRenderWindowInteractor.h"
29 #include "vtkSphereSource.h"
30 #include "vtkActor.h"
31 #include "vtkInteractorStyleRubberBandPick.h"
32 #include "vtkCommand.h"
33 #include "vtkHardwareSelector.h"
34 #include "vtkSelection.h"
35 #include "vtkIdTypeArray.h"
36 #include "vtkRenderedAreaPicker.h"
37 #include "vtkCamera.h"
38 #include "vtkImageActor.h"
39 #include "vtkPointData.h"
40 #include "vtkPlaneSource.h"
41 #include "vtkElevationFilter.h"
42 #include "vtkBitArray.h"
43 #include "vtkGlyph3DMapper.h"
44 #include "vtkSelection.h"
45 #include "vtkSelectionNode.h"
46 #include <cassert>
47
48 static vtkRenderer *renderer = nullptr;
49
50 class MyEndPickCommand : public vtkCommand
51 {
52 public:
MyEndPickCommand()53 MyEndPickCommand()
54 {
55 this->Renderer=nullptr; // no reference counting
56 this->Mask=nullptr; // no reference counting
57 this->DataSet=nullptr;
58 }
59
~MyEndPickCommand()60 ~MyEndPickCommand() override
61 {
62 // empty
63 }
64
Execute(vtkObject * vtkNotUsed (caller),unsigned long vtkNotUsed (eventId),void * vtkNotUsed (callData))65 void Execute(vtkObject *vtkNotUsed(caller),
66 unsigned long vtkNotUsed(eventId),
67 void *vtkNotUsed(callData)) override
68 {
69 assert("pre: renderer_exists" && this->Renderer!=nullptr);
70
71 vtkHardwareSelector *sel = vtkHardwareSelector::New();
72 sel->SetFieldAssociation(vtkDataObject::FIELD_ASSOCIATION_CELLS);
73 sel->SetRenderer(renderer);
74
75 double x0 = renderer->GetPickX1();
76 double y0 = renderer->GetPickY1();
77 double x1 = renderer->GetPickX2();
78 double y1 = renderer->GetPickY2();
79 sel->SetArea(static_cast<unsigned int>(x0),
80 static_cast<unsigned int>(y0),
81 static_cast<unsigned int>(x1),
82 static_cast<unsigned int>(y1));
83
84 vtkSelection *res = sel->Select();
85
86 #if 1
87 cerr << "x0 " << x0 << " y0 " << y0 << "\t";
88 cerr << "x1 " << x1 << " y1 " << y1 << endl;
89 res->Print(cout);
90 #endif
91
92 // Reset the mask to false.
93 vtkIdType numPoints = this->Mask->GetNumberOfTuples();
94 for (vtkIdType i=0; i < numPoints; i++)
95 {
96 this->Mask->SetValue(i,false);
97 }
98
99 vtkSelectionNode *glyphids = res->GetNode(0);
100 if (glyphids!=nullptr)
101 {
102 vtkAbstractArray *abs=glyphids->GetSelectionList();
103 if(abs==nullptr)
104 {
105 cout<<"abs is null"<<endl;
106 }
107 vtkIdTypeArray *ids=vtkArrayDownCast<vtkIdTypeArray>(abs);
108 if(ids==nullptr)
109 {
110 cout<<"ids is null"<<endl;
111 }
112 else
113 {
114 // modify mask array with selection.
115 vtkIdType numSelPoints = ids->GetNumberOfTuples();
116 for (vtkIdType i =0; i < numSelPoints; i++)
117 {
118 vtkIdType value = ids->GetValue(i);
119 if (value >=0 && value < numPoints)
120 {
121 cout << "Turn On: " << value << endl;
122 this->Mask->SetValue(value,true);
123 }
124 else
125 {
126 cout << "Ignoring: " << value << endl;
127 }
128 }
129 }
130 }
131 this->DataSet->Modified();
132
133 sel->Delete();
134 res->Delete();
135 }
136
SetRenderer(vtkRenderer * r)137 void SetRenderer(vtkRenderer *r)
138 {
139 this->Renderer=r;
140 }
141
GetRenderer() const142 vtkRenderer *GetRenderer() const
143 {
144 return this->Renderer;
145 }
146
SetMask(vtkBitArray * m)147 void SetMask(vtkBitArray *m)
148 {
149 this->Mask=m;
150 }
SetDataSet(vtkDataSet * ds)151 void SetDataSet(vtkDataSet* ds)
152 {
153 this->DataSet = ds;
154 }
155
156 protected:
157 vtkRenderer *Renderer;
158 vtkBitArray *Mask;
159 vtkDataSet *DataSet;
160 };
161
TestGlyph3DMapperCellPicking(int argc,char * argv[])162 int TestGlyph3DMapperCellPicking(int argc, char* argv[])
163 {
164 int res=1;
165 vtkPlaneSource *plane=vtkPlaneSource::New();
166 plane->SetResolution(res,res);
167 vtkElevationFilter *colors=vtkElevationFilter::New();
168 colors->SetInputConnection(plane->GetOutputPort());
169 plane->Delete();
170 colors->SetLowPoint(-1,-1,-1);
171 colors->SetHighPoint(0.5,0.5,0.5);
172
173 vtkSphereSource *squad=vtkSphereSource::New();
174 squad->SetPhiResolution(4);
175 squad->SetThetaResolution(6);
176
177 vtkGlyph3DMapper *glypher=vtkGlyph3DMapper::New();
178 glypher->SetInputConnection(colors->GetOutputPort());
179 colors->Delete();
180 glypher->SetScaleFactor(1.5);
181 glypher->SetSourceConnection(squad->GetOutputPort());
182 squad->Delete();
183
184 // selection is performed on actor1
185 vtkActor *glyphActor1=vtkActor::New();
186 glyphActor1->SetMapper(glypher);
187 glypher->Delete();
188 glyphActor1->PickableOn();
189
190 // result of selection is on actor2
191 vtkActor *glyphActor2=vtkActor::New();
192 glyphActor2->PickableOff();
193 colors->Update(); // make sure output is valid.
194 vtkDataSet *selection=colors->GetOutput()->NewInstance();
195 selection->ShallowCopy(colors->GetOutput());
196
197 vtkBitArray *selectionMask=vtkBitArray::New();
198 selectionMask->SetName("mask");
199 selectionMask->SetNumberOfComponents(1);
200 selectionMask->SetNumberOfTuples(selection->GetNumberOfPoints());
201 // Initially, everything is selected
202 vtkIdType i=0;
203 vtkIdType c=selectionMask->GetNumberOfTuples();
204 while(i<c)
205 {
206 selectionMask->SetValue(i,true);
207 ++i;
208 }
209 selection->GetPointData()->AddArray(selectionMask);
210 selectionMask->Delete();
211
212 vtkGlyph3DMapper *glypher2=vtkGlyph3DMapper::New();
213 // glypher->SetNestedDisplayLists(0);
214 glypher2->SetMasking(1);
215 glypher2->SetMaskArray("mask");
216
217 glypher2->SetInputData(selection);
218 glypher2->SetScaleFactor(1.5);
219 glypher2->SetSourceConnection(squad->GetOutputPort());
220 glyphActor2->SetMapper(glypher2);
221 glypher2->Delete();
222
223 // Standard rendering classes
224 renderer = vtkRenderer::New();
225 vtkRenderWindow *renWin = vtkRenderWindow::New();
226 renWin->AddRenderer(renderer);
227 renWin->SetMultiSamples(0);
228 vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
229 iren->SetRenderWindow(renWin);
230
231 //set up the view
232 renderer->SetBackground(0.2,0.2,0.2);
233 renWin->SetSize(600,300);
234
235 //use the rubber band pick interactor style
236 vtkRenderWindowInteractor* rwi = renWin->GetInteractor();
237 vtkInteractorStyleRubberBandPick *rbp =
238 vtkInteractorStyleRubberBandPick::New();
239 rwi->SetInteractorStyle(rbp);
240
241 vtkRenderedAreaPicker *areaPicker = vtkRenderedAreaPicker::New();
242 rwi->SetPicker(areaPicker);
243
244 renderer->AddActor(glyphActor1);
245 renderer->AddActor(glyphActor2);
246 glyphActor2->SetPosition(2,0,0);
247 glyphActor1->Delete();
248 glyphActor2->Delete();
249
250 //pass pick events to the VisibleGlyphSelector
251 MyEndPickCommand *cbc=new MyEndPickCommand;
252 cbc->SetRenderer(renderer);
253 cbc->SetMask(selectionMask);
254 cbc->SetDataSet(selection);
255 rwi->AddObserver(vtkCommand::EndPickEvent,cbc);
256 cbc->Delete();
257
258 ////////////////////////////////////////////////////////////
259
260 //run the test
261
262 renderer->ResetCamera();
263 renderer->GetActiveCamera()->Zoom(2.0);
264
265 renWin->Render();
266 // areaPicker->AreaPick(0, 0, 241, 160, renderer);
267 areaPicker->AreaPick(233, 120, 241, 160, renderer);
268 cbc->Execute(nullptr, 0, nullptr);
269 renWin->Render();
270
271 int retVal = vtkRegressionTestImage( renWin );
272 if ( retVal == vtkRegressionTester::DO_INTERACTOR)
273 {
274 iren->Start();
275 }
276
277 // Cleanup
278 renderer->Delete();
279 renWin->Delete();
280 iren->Delete();
281 rbp->Delete();
282 areaPicker->Delete();
283 selection->Delete();
284 return !retVal;
285 }
286