OGS
VtkCustomInteractorStyle.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4// ** INCLUDES **
6
7#include <vtkActor.h>
8#include <vtkAlgorithmOutput.h>
9#include <vtkCamera.h>
10#include <vtkCellData.h>
11#include <vtkCellPicker.h>
12#include <vtkDataSetMapper.h>
13#include <vtkExtractSelection.h>
14#include <vtkIdTypeArray.h>
15#include <vtkObjectFactory.h>
16#include <vtkProp.h>
17#include <vtkProperty.h>
18#include <vtkRenderWindow.h>
19#include <vtkRenderWindowInteractor.h>
20#include <vtkRendererCollection.h>
21#include <vtkSelection.h>
22#include <vtkSelectionNode.h>
23#include <vtkSmartPointer.h>
24#include <vtkUnstructuredGrid.h>
25#include <vtkUnstructuredGridAlgorithm.h>
26
27#include <string>
28
29#include "BaseLib/Logging.h"
31
33
35{
36 _selectedMapper = vtkDataSetMapper::New();
37 _selectedActor = vtkActor::New();
39 _selectedActor->GetProperty()->EdgeVisibilityOn();
40 _selectedActor->GetProperty()->SetEdgeColor(1, 0, 0);
41 _selectedActor->GetProperty()->SetLineWidth(3);
42}
43
49
51{
52 switch (Interactor->GetKeyCode())
53 {
54 case '3':
55 INFO("The 3 key was pressed.");
56 break;
57 case 'a':
58 break;
59 default:
60 vtkInteractorStyleTrackballCamera::OnChar();
61 }
62}
63
65{
66 switch (Interactor->GetKeyCode())
67 {
68 case 32: // Space
70 emit cursorChanged(Qt::CrossCursor);
71 break;
72 default:
73 vtkInteractorStyleTrackballCamera::OnKeyDown();
74 }
75}
76
78{
79 switch (Interactor->GetKeyCode())
80 {
81 case 32: // Space
83 emit cursorChanged(Qt::ArrowCursor);
84 break;
85 default:
86 vtkInteractorStyleTrackballCamera::OnKeyUp();
87 }
88}
89
91{
93 {
94 HighlightProp((vtkProp*)actor);
95 }
96}
97
99{
100 this->Interactor->GetRenderWindow()
101 ->GetRenderers()
102 ->GetFirstRenderer()
103 ->RemoveActor(_selectedActor);
104}
105
107{
108 _highlightActor = on;
109 if (!on)
110 {
111 HighlightProp((vtkProp*)nullptr);
112 }
113}
114
116{
117 _data = object;
118 if (!object)
119 {
120 this->Interactor->GetRenderWindow()
121 ->GetRenderers()
122 ->GetFirstRenderer()
123 ->RemoveActor(_selectedActor);
124 _selectedMapper->SetInputConnection(nullptr);
125 }
126}
127
128// From https://kitware.github.io/vtk-examples/site/Cxx/Picking/CellPicking/
130{
131 if (!_data)
132 {
133 return vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
134 }
135
137 {
138 // Get the location of the click (in window coordinates)
139 int* pos = this->GetInteractor()->GetEventPosition();
140
141 vtkSmartPointer<vtkCellPicker> picker =
142 vtkSmartPointer<vtkCellPicker>::New();
143 picker->SetTolerance(0.0005);
144
145 // Pick from this location.
146 picker->Pick(pos[0], pos[1], 0, this->GetDefaultRenderer());
147
148 double* worldPosition = picker->GetPickPosition();
149 INFO("Cell id is: {:d}", picker->GetCellId());
150
151 if (picker->GetCellId() != -1)
152 {
153 INFO("Pick position is: {:f} {:f} {:f}", worldPosition[0],
154 worldPosition[1], worldPosition[2]);
155
156 vtkSmartPointer<vtkIdTypeArray> ids =
157 vtkSmartPointer<vtkIdTypeArray>::New();
158 ids->SetNumberOfValues(1);
159 ids->SetValue(0, picker->GetCellId());
160
161 vtkSmartPointer<vtkSelectionNode> selectionNode =
162 vtkSmartPointer<vtkSelectionNode>::New();
163 selectionNode->SetFieldType(vtkSelectionNode::CELL);
164 selectionNode->SetContentType(vtkSelectionNode::INDICES);
165 selectionNode->SetSelectionList(ids);
166
167 vtkSmartPointer<vtkSelection> selection =
168 vtkSmartPointer<vtkSelection>::New();
169 selection->AddNode(selectionNode);
170
171 vtkSmartPointer<vtkExtractSelection> extractSelection =
172 vtkSmartPointer<vtkExtractSelection>::New();
173 extractSelection->SetInputData(0, _data);
174 extractSelection->SetInputData(1, selection);
175 extractSelection->Update();
176
177 // In selection
178 vtkSmartPointer<vtkUnstructuredGrid> selected =
179 vtkSmartPointer<vtkUnstructuredGrid>::New();
180 selected->ShallowCopy(extractSelection->GetOutput());
181
182 INFO("There are {:d} points in the selection.",
183 selected->GetNumberOfPoints());
184 INFO("There are {:d} cells in the selection.",
185 selected->GetNumberOfCells());
186
187 // check if the underlying object is a mesh and if so, send a signal
188 // to the element model for display of information about the picked
189 // element.
190 vtkAlgorithm* data_set = picker->GetActor()
191 ->GetMapper()
192 ->GetInputConnection(0, 0)
193 ->GetProducer()
194 ->GetInputConnection(0, 0)
195 ->GetProducer();
196 auto* source =
197 dynamic_cast<vtkUnstructuredGridAlgorithm*>(data_set);
198 if (source)
199 {
200 emit elementPicked(source,
201 static_cast<unsigned>(picker->GetCellId()));
202 }
203 else
204 {
205 emit clearElementView();
206 }
207 _selectedMapper->SetInputData(selected);
208
209 this->Interactor->GetRenderWindow()
210 ->GetRenderers()
211 ->GetFirstRenderer()
212 ->AddActor(_selectedActor);
213 //_highlightActor = true;
214 }
215 else
216 {
217 this->Interactor->GetRenderWindow()
218 ->GetRenderers()
219 ->GetFirstRenderer()
220 ->RemoveActor(_selectedActor);
221 }
222 emit requestViewUpdate();
223 }
224 else
225 {
226 // Forward events
227 vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
228 }
229}
230
232{
233 if (!_data)
234 {
235 return vtkInteractorStyleTrackballCamera::OnRightButtonDown();
236 }
237
239 {
240 // Get the location of the click (in window coordinates)
241 int* pos = this->GetInteractor()->GetEventPosition();
242
243 vtkSmartPointer<vtkCellPicker> picker =
244 vtkSmartPointer<vtkCellPicker>::New();
245 picker->SetTolerance(0.0005);
246
247 // Pick from this location.
248 picker->Pick(pos[0], pos[1], 0, this->GetDefaultRenderer());
249
250 double* worldPosition = picker->GetPickPosition();
251 INFO("Cell id is: {:d}", picker->GetCellId());
252
253 if (picker->GetCellId() != -1)
254 {
255 vtkRenderer* renderer = this->Interactor->GetRenderWindow()
256 ->GetRenderers()
257 ->GetFirstRenderer();
258 vtkCamera* cam = renderer->GetActiveCamera();
259 cam->SetFocalPoint(worldPosition);
260 emit requestViewUpdate();
261 }
262 }
263 else
264 {
265 // Forward events
266 vtkInteractorStyleTrackballCamera::OnRightButtonDown();
267 }
268}
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:28
vtkStandardNewMacro(VtkCustomInteractorStyle)
vtkDataSetMapper * _selectedMapper
The mapper for highlighting the selected cell.
void OnChar() override
Handles key press events.
void OnKeyDown() override
Handles key down events.
void elementPicked(vtkUnstructuredGridAlgorithm const *const, unsigned)
Emitted when a mesh element has been picked.
void cursorChanged(Qt::CursorShape)
Emitted when the cursor shape was changed due to alternate mouse action mode.
void clearElementView()
Emitted when the current object type cannot be handled by the element model.
void pickableDataObject(vtkDataObject *object)
Sets the highlightable vtk object.
vtkDataObject * _data
The vtk object to pick.
void removeHighlightActor()
Removes the highlight actor from the visible scene.
vtkActor * _selectedActor
The actor for highlighting the selected cell.
void highlightActor(vtkProp3D *actor)
void requestViewUpdate()
Emitted when something was picked.
void OnLeftButtonDown() override
Handles left mouse button events (picking).
void OnKeyUp() override
Handles key up events.
void OnRightButtonDown() override
Handles middle mouse button events (rotation point picking).