1 
2 #include "QtVTKTouchscreenRenderWindows.h"
3 #include "ui_QtVTKTouchscreenRenderWindows.h"
4 
5 // Available interactions:
6 // - Tap: Randomizes background color and moves the sphere actor to the location of the tap point
7 //      = Touchscreen: 1 finger
8 // - Tap and hold: Switches camera between perspective and orthographic view and moves the cylinder
9 // to the location of the tap point
10 //      = Touchscreen and MacOS trackpad: 1 finger
11 // - Swipe: Changes the color of the Square/Sphere/Cylinder based on the swipe angle. Angle -> Hue
12 //      = Touchscreen: 3 fingers
13 // - Pinch : Zoom in and out the view, centered on the location of the pinch
14 //      = Touchscreen and MacOS trackpad: 2 fingers
15 // - Rotate: Rotate the view, centered on the location of the pinch
16 //      = Touchscreen and MacOS trackpad: 2 fingers
17 // - Pan: Translate the view
18 //      = Touchscreen: 2+ fingers
19 //      = MacOS trackpad: Long tap and move
20 
21 #include <vtkActor.h>
22 #include <vtkCamera.h>
23 #include <vtkCollectionIterator.h>
24 #include <vtkCubeSource.h>
25 #include <vtkCylinderSource.h>
26 #include <vtkGenericOpenGLRenderWindow.h>
27 #include <vtkInteractorStyleMultiTouchCamera.h>
28 #include <vtkPlane.h>
29 #include <vtkPolyDataMapper.h>
30 #include <vtkProperty.h>
31 #include <vtkRenderer.h>
32 #include <vtkSphereSource.h>
33 #include <vtkTransform.h>
34 
35 vtkNew<vtkActor> cubeActor;
36 vtkNew<vtkActor> sphereActor;
37 vtkNew<vtkActor> cylinderActor;
38 
39 vtkNew<vtkSphereSource> sphereSource;
40 vtkNew<vtkCubeSource> cubeSource;
41 vtkNew<vtkCylinderSource> cylinderSource;
42 
43 vtkNew<vtkTransform> sphereTransform;
44 vtkNew<vtkTransform> cubeTransform;
45 vtkNew<vtkTransform> cylinderTransform;
46 
47 class vtkInteractorStyleMultiTouchCameraExample : public vtkInteractorStyleMultiTouchCamera
48 {
49 public:
50   static vtkInteractorStyleMultiTouchCameraExample* New();
51   vtkTypeMacro(vtkInteractorStyleMultiTouchCameraExample, vtkInteractorStyleMultiTouchCamera);
52 
GetPickPosition(double pickPosition[4])53   void GetPickPosition(double pickPosition[4])
54   {
55     vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
56     if (!camera)
57     {
58       return;
59     }
60 
61     int pointer = this->Interactor->GetPointerIndex();
62 
63     this->FindPokedRenderer(this->Interactor->GetEventPositions(pointer)[0],
64       this->Interactor->GetEventPositions(pointer)[1]);
65 
66     double* focalPointWorld = camera->GetFocalPoint();
67     double focalPointDisplay[3] = { 0, 0, 0 };
68     vtkInteractorObserver::ComputeWorldToDisplay(this->CurrentRenderer, focalPointWorld[0],
69       focalPointWorld[1], focalPointWorld[2], focalPointDisplay);
70 
71     // New position at the center of the pinch gesture
72     int* touchPositionDisplay = this->Interactor->GetEventPositions(pointer);
73     double pickPoint[4] = { 0, 0, 0, 0 };
74     vtkInteractorObserver::ComputeDisplayToWorld(this->CurrentRenderer, touchPositionDisplay[0],
75       touchPositionDisplay[1], focalPointDisplay[2], pickPosition);
76   }
77 
OnLongTap()78   void OnLongTap() override
79   {
80     if (!this->CurrentRenderer)
81     {
82       return;
83     }
84 
85     vtkCamera* camera = this->CurrentRenderer->GetActiveCamera();
86     if (!camera)
87     {
88       return;
89     }
90 
91     camera->SetParallelProjection(!camera->GetParallelProjection());
92 
93     double pickPoint[4] = { 0, 0, 0, 0 };
94     this->GetPickPosition(pickPoint);
95     cylinderTransform->Identity();
96     cylinderTransform->Translate(pickPoint);
97 
98     this->CurrentRenderer->Render();
99   }
100 
OnTap()101   void OnTap() override
102   {
103     if (!this->CurrentRenderer)
104     {
105       return;
106     }
107 
108     this->CurrentRenderer->SetBackground(
109       (double)rand() / RAND_MAX, (double)rand() / RAND_MAX, (double)rand() / RAND_MAX);
110 
111     double pickPoint[4] = { 0, 0, 0, 0 };
112     this->GetPickPosition(pickPoint);
113     sphereTransform->Identity();
114     sphereTransform->Translate(pickPoint);
115 
116     this->CurrentRenderer->Render();
117   }
118 
119   bool IsSwiping = false;
OnStartSwipe()120   void OnStartSwipe() override
121   {
122     this->IsSwiping = true;
123     this->StartGesture();
124   }
125 
OnEndSwipe()126   void OnEndSwipe() override
127   {
128     this->IsSwiping = false;
129     this->EndGesture();
130   }
131 
OnSwipe()132   void OnSwipe() override
133   {
134     if (!this->CurrentRenderer)
135     {
136       return;
137     }
138 
139     double hsv[3] = { this->Interactor->GetRotation() / 360.0, 1.0, 1.0 };
140     double rgb[3];
141     vtkMath::HSVToRGB(hsv, rgb);
142 
143     cubeActor->GetProperty()->SetColor(rgb);
144     sphereActor->GetProperty()->SetColor(rgb);
145     cylinderActor->GetProperty()->SetColor(rgb);
146 
147     this->CurrentRenderer->Render();
148   }
149 
OnPinch()150   void OnPinch() override
151   {
152     if (this->IsSwiping)
153     {
154       return;
155     }
156     Superclass::OnPinch();
157   }
158 
OnRotate()159   void OnRotate() override
160   {
161     if (this->IsSwiping)
162     {
163       return;
164     }
165     Superclass::OnRotate();
166   }
167 
OnPan()168   void OnPan() override
169   {
170     if (this->IsSwiping)
171     {
172       return;
173     }
174     Superclass::OnPan();
175   }
176 };
177 vtkStandardNewMacro(vtkInteractorStyleMultiTouchCameraExample);
178 
179 //------------------------------------------------------------------------------
QtVTKTouchscreenRenderWindows(int vtkNotUsed (argc),char * argv[])180 QtVTKTouchscreenRenderWindows::QtVTKTouchscreenRenderWindows(int vtkNotUsed(argc), char* argv[])
181 {
182   this->ui = new Ui_QtVTKTouchscreenRenderWindows;
183   this->ui->setupUi(this);
184 
185   vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow =
186     vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();
187   this->ui->view->setRenderWindow(renderWindow);
188 
189   vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
190   this->ui->view->renderWindow()->AddRenderer(renderer);
191 
192   vtkRenderWindowInteractor* interactor = this->ui->view->interactor();
193   vtkSmartPointer<vtkInteractorStyleMultiTouchCameraExample> interactorStyle =
194     vtkSmartPointer<vtkInteractorStyleMultiTouchCameraExample>::New();
195   interactor->SetInteractorStyle(interactorStyle);
196   renderWindow->SetInteractor(interactor);
197 
198   // Create a cube.
199   cubeSource->SetXLength(0.5);
200   cubeSource->SetYLength(0.5);
201   cubeSource->SetZLength(0.5);
202 
203   // Create a mapper and actor.
204   vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
205   mapper->SetInputConnection(cubeSource->GetOutputPort());
206   cubeActor->SetMapper(mapper);
207   renderer->AddActor(cubeActor);
208 
209   // Create a sphere.
210   sphereSource->SetRadius(0.125);
211 
212   // Create a mapper and actor.
213   vtkSmartPointer<vtkPolyDataMapper> sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
214   sphereMapper->SetInputConnection(sphereSource->GetOutputPort());
215   sphereActor->SetMapper(sphereMapper);
216   sphereActor->SetUserTransform(sphereTransform);
217   renderer->AddActor(sphereActor);
218 
219   // Create a cylinder.
220   cylinderSource->SetRadius(0.125);
221   cylinderSource->SetHeight(0.25);
222 
223   // Create a mapper and actor.
224   vtkSmartPointer<vtkPolyDataMapper> cylinderMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
225   cylinderMapper->SetInputConnection(cylinderSource->GetOutputPort());
226   cylinderActor->SetMapper(cylinderMapper);
227   cylinderActor->SetUserTransform(cylinderTransform);
228   renderer->AddActor(cylinderActor);
229 
230   renderer->SetBackground(0.1, 0.2, 0.4);
231 };
232