1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkInteractorStyleRubberBand3D.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 /*-------------------------------------------------------------------------
16 Copyright 2008 Sandia Corporation.
17 Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
18 the U.S. Government retains certain rights in this software.
19 -------------------------------------------------------------------------*/
20
21 #include "vtkInteractorStyleRubberBand3D.h"
22
23 #include "vtkActor.h"
24 #include "vtkCamera.h"
25 #include "vtkCommand.h"
26 #include "vtkObjectFactory.h"
27 #include "vtkRenderer.h"
28 #include "vtkRenderWindow.h"
29 #include "vtkRenderWindowInteractor.h"
30 #include "vtkUnsignedCharArray.h"
31
32 vtkStandardNewMacro(vtkInteractorStyleRubberBand3D);
33
34 //--------------------------------------------------------------------------
vtkInteractorStyleRubberBand3D()35 vtkInteractorStyleRubberBand3D::vtkInteractorStyleRubberBand3D()
36 {
37 this->PixelArray = vtkUnsignedCharArray::New();
38 this->Interaction = NONE;
39 this->RenderOnMouseMove = false;
40 this->StartPosition[0] = 0;
41 this->StartPosition[1] = 0;
42 this->EndPosition[0] = 0;
43 this->EndPosition[1] = 0;
44 }
45
46 //--------------------------------------------------------------------------
~vtkInteractorStyleRubberBand3D()47 vtkInteractorStyleRubberBand3D::~vtkInteractorStyleRubberBand3D()
48 {
49 this->PixelArray->Delete();
50 }
51
52 //--------------------------------------------------------------------------
OnLeftButtonDown()53 void vtkInteractorStyleRubberBand3D::OnLeftButtonDown()
54 {
55 if(this->Interaction == NONE)
56 {
57 this->Interaction = SELECTING;
58 vtkRenderWindow *renWin = this->Interactor->GetRenderWindow();
59
60 this->StartPosition[0] = this->Interactor->GetEventPosition()[0];
61 this->StartPosition[1] = this->Interactor->GetEventPosition()[1];
62 this->EndPosition[0] = this->StartPosition[0];
63 this->EndPosition[1] = this->StartPosition[1];
64
65 this->PixelArray->Initialize();
66 this->PixelArray->SetNumberOfComponents(4);
67 int *size = renWin->GetSize();
68 this->PixelArray->SetNumberOfTuples(size[0]*size[1]);
69
70 renWin->GetRGBACharPixelData(0, 0, size[0]-1, size[1]-1, 1, this->PixelArray);
71 this->FindPokedRenderer(this->StartPosition[0], this->StartPosition[1]);
72 this->InvokeEvent(vtkCommand::StartInteractionEvent);
73 }
74 }
75
76 //--------------------------------------------------------------------------
OnLeftButtonUp()77 void vtkInteractorStyleRubberBand3D::OnLeftButtonUp()
78 {
79 if(this->Interaction == SELECTING)
80 {
81 // Clear the rubber band
82 int* size = this->Interactor->GetRenderWindow()->GetSize();
83 unsigned char* pixels = this->PixelArray->GetPointer(0);
84 this->Interactor->GetRenderWindow()->SetRGBACharPixelData(0, 0, size[0]-1, size[1]-1, pixels, 0);
85 this->Interactor->GetRenderWindow()->Frame();
86
87 unsigned int rect[5];
88 rect[0] = this->StartPosition[0];
89 rect[1] = this->StartPosition[1];
90 rect[2] = this->EndPosition[0];
91 rect[3] = this->EndPosition[1];
92 if (this->Interactor->GetShiftKey())
93 {
94 rect[4] = SELECT_UNION;
95 }
96 else
97 {
98 rect[4] = SELECT_NORMAL;
99 }
100 this->InvokeEvent(vtkCommand::SelectionChangedEvent, reinterpret_cast<void*>(rect));
101 this->InvokeEvent(vtkCommand::EndInteractionEvent);
102 this->Interaction = NONE;
103 }
104 }
105
106 //--------------------------------------------------------------------------
OnMiddleButtonDown()107 void vtkInteractorStyleRubberBand3D::OnMiddleButtonDown()
108 {
109 if(this->Interaction == NONE)
110 {
111 this->Interaction = PANNING;
112 this->FindPokedRenderer(
113 this->Interactor->GetEventPosition()[0],
114 this->Interactor->GetEventPosition()[1]);
115 this->InvokeEvent(vtkCommand::StartInteractionEvent);
116 }
117 }
118
119 //--------------------------------------------------------------------------
OnMiddleButtonUp()120 void vtkInteractorStyleRubberBand3D::OnMiddleButtonUp()
121 {
122 if(this->Interaction == PANNING)
123 {
124 this->InvokeEvent(vtkCommand::EndInteractionEvent);
125 this->Interaction = NONE;
126 }
127 }
128
129 //--------------------------------------------------------------------------
OnRightButtonDown()130 void vtkInteractorStyleRubberBand3D::OnRightButtonDown()
131 {
132 if(this->Interaction == NONE)
133 {
134 if (this->Interactor->GetShiftKey())
135 {
136 this->Interaction = ZOOMING;
137 }
138 else
139 {
140 this->Interaction = ROTATING;
141 }
142 this->FindPokedRenderer(
143 this->Interactor->GetEventPosition()[0],
144 this->Interactor->GetEventPosition()[1]);
145 this->InvokeEvent(vtkCommand::StartInteractionEvent);
146 }
147 }
148
149 //--------------------------------------------------------------------------
OnRightButtonUp()150 void vtkInteractorStyleRubberBand3D::OnRightButtonUp()
151 {
152 if(this->Interaction == ZOOMING || this->Interaction == ROTATING)
153 {
154 this->InvokeEvent(vtkCommand::EndInteractionEvent);
155 this->Interaction = NONE;
156 }
157 }
158
159 //--------------------------------------------------------------------------
OnMouseMove()160 void vtkInteractorStyleRubberBand3D::OnMouseMove()
161 {
162 if (this->Interaction == PANNING)
163 {
164 this->Superclass::Pan();
165 }
166 else if (this->Interaction == ZOOMING)
167 {
168 this->Superclass::Dolly();
169 }
170 else if (this->Interaction == ROTATING)
171 {
172 this->Superclass::Rotate();
173 }
174 else if (this->Interaction == SELECTING)
175 {
176 this->EndPosition[0] = this->Interactor->GetEventPosition()[0];
177 this->EndPosition[1] = this->Interactor->GetEventPosition()[1];
178 int *size = this->Interactor->GetRenderWindow()->GetSize();
179 if (this->EndPosition[0] > (size[0]-1))
180 {
181 this->EndPosition[0] = size[0]-1;
182 }
183 if (this->EndPosition[0] < 0)
184 {
185 this->EndPosition[0] = 0;
186 }
187 if (this->EndPosition[1] > (size[1]-1))
188 {
189 this->EndPosition[1] = size[1]-1;
190 }
191 if (this->EndPosition[1] < 0)
192 {
193 this->EndPosition[1] = 0;
194 }
195 this->InvokeEvent(vtkCommand::InteractionEvent);
196 this->RedrawRubberBand();
197 }
198 else if (this->RenderOnMouseMove)
199 {
200 this->GetInteractor()->Render();
201 }
202 }
203
204 //--------------------------------------------------------------------------
OnMouseWheelForward()205 void vtkInteractorStyleRubberBand3D::OnMouseWheelForward()
206 {
207 this->FindPokedRenderer(
208 this->Interactor->GetEventPosition()[0],
209 this->Interactor->GetEventPosition()[1]);
210 vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
211 if (!camera)
212 {
213 return;
214 }
215 this->Interaction = ZOOMING;
216 this->Superclass::OnMouseWheelForward();
217 this->Interaction = NONE;
218 }
219
220 //--------------------------------------------------------------------------
OnMouseWheelBackward()221 void vtkInteractorStyleRubberBand3D::OnMouseWheelBackward()
222 {
223 this->FindPokedRenderer(
224 this->Interactor->GetEventPosition()[0],
225 this->Interactor->GetEventPosition()[1]);
226 vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
227 if (!camera)
228 {
229 return;
230 }
231 this->Interaction = ZOOMING;
232 this->Superclass::OnMouseWheelBackward();
233 this->Interaction = NONE;
234 }
235
236 //--------------------------------------------------------------------------
RedrawRubberBand()237 void vtkInteractorStyleRubberBand3D::RedrawRubberBand()
238 {
239 // Update the rubber band on the screen
240 int *size = this->Interactor->GetRenderWindow()->GetSize();
241
242 vtkUnsignedCharArray *tmpPixelArray = vtkUnsignedCharArray::New();
243 tmpPixelArray->DeepCopy(this->PixelArray);
244 unsigned char *pixels = tmpPixelArray->GetPointer(0);
245
246 int min[2], max[2];
247
248 min[0] = this->StartPosition[0] <= this->EndPosition[0] ?
249 this->StartPosition[0] : this->EndPosition[0];
250 if (min[0] < 0) { min[0] = 0; }
251 if (min[0] >= size[0]) { min[0] = size[0] - 1; }
252
253 min[1] = this->StartPosition[1] <= this->EndPosition[1] ?
254 this->StartPosition[1] : this->EndPosition[1];
255 if (min[1] < 0) { min[1] = 0; }
256 if (min[1] >= size[1]) { min[1] = size[1] - 1; }
257
258 max[0] = this->EndPosition[0] > this->StartPosition[0] ?
259 this->EndPosition[0] : this->StartPosition[0];
260 if (max[0] < 0) { max[0] = 0; }
261 if (max[0] >= size[0]) { max[0] = size[0] - 1; }
262
263 max[1] = this->EndPosition[1] > this->StartPosition[1] ?
264 this->EndPosition[1] : this->StartPosition[1];
265 if (max[1] < 0) { max[1] = 0; }
266 if (max[1] >= size[1]) { max[1] = size[1] - 1; }
267
268 int i;
269 for (i = min[0]; i <= max[0]; i++)
270 {
271 pixels[4*(min[1]*size[0]+i)] = 255 ^ pixels[4*(min[1]*size[0]+i)];
272 pixels[4*(min[1]*size[0]+i)+1] = 255 ^ pixels[4*(min[1]*size[0]+i)+1];
273 pixels[4*(min[1]*size[0]+i)+2] = 255 ^ pixels[4*(min[1]*size[0]+i)+2];
274 pixels[4*(max[1]*size[0]+i)] = 255 ^ pixels[4*(max[1]*size[0]+i)];
275 pixels[4*(max[1]*size[0]+i)+1] = 255 ^ pixels[4*(max[1]*size[0]+i)+1];
276 pixels[4*(max[1]*size[0]+i)+2] = 255 ^ pixels[4*(max[1]*size[0]+i)+2];
277 }
278 for (i = min[1]+1; i < max[1]; i++)
279 {
280 pixels[4*(i*size[0]+min[0])] = 255 ^ pixels[4*(i*size[0]+min[0])];
281 pixels[4*(i*size[0]+min[0])+1] = 255 ^ pixels[4*(i*size[0]+min[0])+1];
282 pixels[4*(i*size[0]+min[0])+2] = 255 ^ pixels[4*(i*size[0]+min[0])+2];
283 pixels[4*(i*size[0]+max[0])] = 255 ^ pixels[4*(i*size[0]+max[0])];
284 pixels[4*(i*size[0]+max[0])+1] = 255 ^ pixels[4*(i*size[0]+max[0])+1];
285 pixels[4*(i*size[0]+max[0])+2] = 255 ^ pixels[4*(i*size[0]+max[0])+2];
286 }
287
288 this->Interactor->GetRenderWindow()->SetRGBACharPixelData(0, 0, size[0]-1, size[1]-1, pixels, 0);
289 this->Interactor->GetRenderWindow()->Frame();
290
291 tmpPixelArray->Delete();
292 }
293
294 //--------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)295 void vtkInteractorStyleRubberBand3D::PrintSelf(ostream& os, vtkIndent indent)
296 {
297 this->Superclass::PrintSelf(os, indent);
298 os << indent << "Interaction: " << this->Interaction << endl;
299 os << indent << "RenderOnMouseMove: " << this->RenderOnMouseMove << endl;
300 os << indent << "StartPosition: " << this->StartPosition[0] << "," << this->StartPosition[1] << endl;
301 os << indent << "EndPosition: " << this->EndPosition[0] << "," << this->EndPosition[1] << endl;
302 }
303