ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
vtkwidget.cpp
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #include "vtkwidget.h"
9 
11 #include <VtkUtils/utils.h>
12 #include <VtkUtils/vtkutils.h>
13 #include <vtkActor.h>
14 #include <vtkAxesActor.h>
15 #include <vtkDataObject.h>
16 #include <vtkDataSetMapper.h>
17 #include <vtkLODActor.h>
18 #include <vtkOrientationMarkerWidget.h>
19 #include <vtkPolyData.h>
20 #include <vtkProperty.h>
21 #include <vtkRenderWindow.h>
22 #include <vtkRenderer.h>
23 #include <vtkRendererCollection.h>
24 
25 // CV_DB_LIB
26 #include <ecvColorTypes.h>
27 
28 #include <QDebug>
29 
30 namespace VtkUtils {
31 
32 class VtkWidgetPrivate {
33 public:
34  VtkWidgetPrivate(VtkWidget* q);
35  ~VtkWidgetPrivate();
36 
37  void init();
38  void configRenderer(vtkRenderer* renderer, bool gradient = true);
39  void layoutRenderers();
40 
41  VtkWidget* q_ptr;
42  QColor backgroundColor1 = Qt::black;
43  QColor backgroundColor2 = QColor(134.895, 205.989, 235.00035);
44  bool multiViewports = false;
45  vtkRenderer* defaultRenderer = nullptr;
46  vtkOrientationMarkerWidget* orientationMarkerWidget = nullptr;
47 
48  QList<vtkRenderer*> renderers;
49  QList<vtkProp*> actors;
50  QList<vtkProp*> props;
51 
52  double bounds[6];
53 };
54 
55 VtkWidgetPrivate::VtkWidgetPrivate(VtkWidget* q) : q_ptr(q) { init(); }
56 
57 VtkWidgetPrivate::~VtkWidgetPrivate() {}
58 
59 void VtkWidgetPrivate::configRenderer(vtkRenderer* renderer, bool gradient) {
60  if (!renderer) return;
61 
62  double bgclr1[3];
63  double bgclr2[3];
64  Utils::vtkColor(backgroundColor1, bgclr1);
65  Utils::vtkColor(backgroundColor2, bgclr2);
66 
67  renderer->SetBackground2(bgclr2);
68  renderer->SetBackground(bgclr1);
69  renderer->SetGradientBackground(gradient);
70 }
71 
72 static int columnCount(int count) {
73  int cols = 1;
74  while (true) {
75  if ((cols * cols) >= count) return cols;
76  ++cols;
77  }
78  return cols;
79 }
80 
82  switch (renderers.size()) {
83  case 1:
85  break;
86 
87  case 2:
89  break;
90 
91  case 3:
93  break;
94 
95  case 4:
97  break;
98 
99  case 5:
100  VtkUtils::layoutRenderers<5>(renderers);
101  break;
102 
103  case 6:
104  VtkUtils::layoutRenderers<6>(renderers);
105  break;
106 
107  case 7:
108  VtkUtils::layoutRenderers<7>(renderers);
109  break;
110 
111  case 8:
112  VtkUtils::layoutRenderers<8>(renderers);
113  break;
114 
115  case 9:
116  VtkUtils::layoutRenderers<9>(renderers);
117  break;
118 
119  case 10:
121  break;
122 
123  default:
124  VtkUtils::layoutRenderers<-1>(renderers);
125  }
126 }
127 
128 void VtkWidgetPrivate::init() { layoutRenderers(); }
129 
130 VtkWidget::VtkWidget(QWidget* parent) : QVTKOpenGLNativeWidget(parent) {
131  vtkObject::GlobalWarningDisplayOff();
132  d_ptr = new VtkWidgetPrivate(this);
133  d_ptr->configRenderer(this->defaultRenderer(), true);
134 }
135 
136 VtkWidget::~VtkWidget() { delete d_ptr; }
137 
139  if (d_ptr->multiViewports != multi) {
140  d_ptr->multiViewports = multi;
141  }
142 }
143 
144 bool VtkWidget::multiViewports() const { return d_ptr->multiViewports; }
145 
146 // Helper function called by createActorFromVTKDataSet () methods.
147 // This function determines the default setting of
148 // vtkMapper::InterpolateScalarsBeforeMapping. Return 0, interpolation off, if
149 // data is a vtkPolyData that contains only vertices. Return 1, interpolation
150 // on, for anything else.
152  vtkPolyData* polyData = vtkPolyData::SafeDownCast(
153  data); // Check that polyData != NULL in case of segfault
154  return (polyData &&
155  polyData->GetNumberOfCells() != polyData->GetNumberOfVerts());
156 }
157 
161  bool use_scalars) {
162  // If actor is not initialized, initialize it here
163  if (!actor) actor = vtkSmartPointer<vtkLODActor>::New();
164 
165  {
168 #if VTK_MAJOR_VERSION < 6
169  mapper->SetInput(data);
170 #else
171  mapper->SetInputData(data);
172 #endif
173 
174  if (use_scalars) {
176  data->GetPointData()->GetScalars();
177  double minmax[2];
178  if (scalars) {
179  scalars->GetRange(minmax);
180  mapper->SetScalarRange(minmax);
181 
182  mapper->SetScalarModeToUsePointData();
183  mapper->SetInterpolateScalarsBeforeMapping(
185  mapper->ScalarVisibilityOn();
186  }
187  }
188  // mapper->ImmediateModeRenderingOff();
189 
190  actor->SetNumberOfCloudPoints(
191  int(std::max<vtkIdType>(1, data->GetNumberOfPoints() / 10)));
192  actor->GetProperty()->SetInterpolationToFlat();
193 
198  // actor->GetProperty ()->BackfaceCullingOn ();
199 
200  actor->SetMapper(mapper);
201  }
202 }
203 
204 void VtkWidget::addActor(vtkProp* actor, const QColor& clr) {
205  if (!actor || d_ptr->actors.contains(actor)) return;
206 
207  double vtkClr[3];
208  Utils::vtkColor(clr, vtkClr);
209 
210  d_ptr->actors.append(actor);
211 
212  if (!d_ptr->multiViewports) {
213  if (d_ptr->renderers.isEmpty()) {
214  vtkRenderer* renderer = vtkRenderer::New();
215  renderer->SetBackground(vtkClr);
216  d_ptr->configRenderer(renderer);
217  renderer->AddActor(actor);
218  GetRenderWindow()->AddRenderer(renderer);
219  d_ptr->renderers.append(renderer);
220  renderer->ResetCamera();
221  } else {
222  // defaultRenderer()->SetBackground(vtkClr);
223  d_ptr->configRenderer(defaultRenderer());
224  defaultRenderer()->AddActor(actor);
225  }
226  } else {
227  if (!defaultRendererTaken()) {
228  // defaultRenderer()->SetBackground(vtkClr);
229  d_ptr->configRenderer(defaultRenderer());
230  defaultRenderer()->AddActor(actor);
231  } else {
232  vtkRenderer* renderer = vtkRenderer::New();
233  renderer->SetBackground(vtkClr);
234  d_ptr->configRenderer(renderer);
235  renderer->AddActor(actor);
236  GetRenderWindow()->AddRenderer(renderer);
237  d_ptr->renderers.append(renderer);
238  d_ptr->layoutRenderers();
239  renderer->ResetCamera();
240  }
241  }
242 }
243 
244 void VtkWidget::addViewProp(vtkProp* prop) {
245  if (!prop || d_ptr->props.contains(prop)) return;
246 
247  d_ptr->props.append(prop);
248 
249  if (!d_ptr->multiViewports) {
250  if (d_ptr->renderers.isEmpty()) {
251  vtkRenderer* renderer = vtkRenderer::New();
252  d_ptr->configRenderer(renderer);
253  renderer->AddViewProp(prop);
254  GetRenderWindow()->AddRenderer(renderer);
255  d_ptr->renderers.append(renderer);
256  renderer->ResetCamera();
257  } else {
258  defaultRenderer()->AddViewProp(prop);
259  // GetRenderWindow()->GetRenderers()->GetFirstRenderer()->AddViewProp(prop);
260  }
261  } else {
262  if (!defaultRendererTaken()) {
263  defaultRenderer()->AddViewProp(prop);
264  } else {
265  vtkRenderer* renderer = vtkRenderer::New();
266  d_ptr->configRenderer(renderer);
267  renderer->AddViewProp(prop);
268  GetRenderWindow()->AddRenderer(renderer);
269  d_ptr->renderers.append(renderer);
270  d_ptr->layoutRenderers();
271  renderer->ResetCamera();
272  }
273  }
274 }
275 
276 QList<vtkProp*> VtkWidget::actors() const { return d_ptr->actors; }
277 
278 void VtkWidget::setActorsVisible(bool visible) {
279  foreach (auto actor, d_ptr->actors) actor->SetVisibility(visible);
280 }
281 
282 void VtkWidget::setActorVisible(vtkProp* actor, bool visible) {
283  actor->SetVisibility(visible);
284 }
285 
286 bool VtkWidget::actorVisible(vtkProp* actor) { return actor->GetVisibility(); }
287 
289  foreach (vtkRenderer* renderer, d_ptr->renderers)
290  d_ptr->configRenderer(renderer);
291 }
292 
293 void VtkWidget::setBackgroundColor(const QColor& clr) {
294  if (d_ptr->backgroundColor1 != clr) {
295  d_ptr->backgroundColor1 = clr;
296 
297  foreach (vtkRenderer* renderer, d_ptr->renderers)
298  d_ptr->configRenderer(renderer);
299 
300 #if 0
301  vtkRendererCollection* renderers = GetRenderWindow()->GetRenderers();
302  vtkRenderer* renderer = renderers->GetFirstRenderer();
303  while (renderer) {
304  renderer = renderers->GetNextItem();
305  }
306 #endif
307  update();
308  }
309 }
310 
311 QColor VtkWidget::backgroundColor() const { return d_ptr->backgroundColor1; }
312 
314  VtkUtils::vtkInitOnce(&d_ptr->defaultRenderer);
315  GetRenderWindow()->AddRenderer(d_ptr->defaultRenderer);
316  if (!d_ptr->renderers.contains(d_ptr->defaultRenderer))
317  d_ptr->renderers.append(d_ptr->defaultRenderer);
318  return d_ptr->defaultRenderer;
319 }
320 
322  if (!d_ptr->defaultRenderer) return false;
323  return d_ptr->defaultRenderer->GetActors()->GetNumberOfItems() != 0;
324 }
325 
327  if (!d_ptr->orientationMarkerWidget) {
328  VTK_CREATE(vtkAxesActor, axes);
329  axes->SetShaftTypeToCylinder();
330 
331  d_ptr->orientationMarkerWidget = vtkOrientationMarkerWidget::New();
332  d_ptr->orientationMarkerWidget->SetOutlineColor(0.9300, 0.5700, 0.1300);
333  d_ptr->orientationMarkerWidget->SetOrientationMarker(axes);
334  d_ptr->orientationMarkerWidget->SetInteractor(GetInteractor());
335  d_ptr->orientationMarkerWidget->SetViewport(0.0, 0.0, 0.23, 0.23);
336  d_ptr->orientationMarkerWidget->SetEnabled(1);
337  d_ptr->orientationMarkerWidget->InteractiveOff();
338  }
339 
340  d_ptr->orientationMarkerWidget->SetEnabled(show);
341  update();
342 }
343 
344 void VtkWidget::setBounds(double* bounds) {
346  aa(bounds, d_ptr->bounds);
347 }
348 
349 double VtkWidget::xMin() const { return d_ptr->bounds[0]; }
350 
351 double VtkWidget::xMax() const { return d_ptr->bounds[1]; }
352 
353 double VtkWidget::yMin() const { return d_ptr->bounds[2]; }
354 
355 double VtkWidget::yMax() const { return d_ptr->bounds[3]; }
356 
357 double VtkWidget::zMin() const { return d_ptr->bounds[4]; }
358 
359 double VtkWidget::zMax() const { return d_ptr->bounds[5]; }
360 
361 } // namespace VtkUtils
int count
static int columnCount(int count)
bool multiViewports() const
Definition: vtkwidget.cpp:144
double xMax() const
Definition: vtkwidget.cpp:351
void addViewProp(vtkProp *prop)
Definition: vtkwidget.cpp:244
virtual ~VtkWidget()
Definition: vtkwidget.cpp:136
void createActorFromVTKDataSet(const vtkSmartPointer< vtkDataSet > &data, vtkSmartPointer< vtkLODActor > &actor, bool use_scalars=true)
Definition: vtkwidget.cpp:158
QColor backgroundColor() const
Definition: vtkwidget.cpp:311
vtkRenderer * defaultRenderer()
Definition: vtkwidget.cpp:313
void showOrientationMarker(bool show=true)
Definition: vtkwidget.cpp:326
void setActorsVisible(bool visible)
Definition: vtkwidget.cpp:278
bool actorVisible(vtkProp *actor)
Definition: vtkwidget.cpp:286
vtkRenderWindow * GetRenderWindow()
Definition: vtkwidget.h:67
void setActorVisible(vtkProp *actor, bool visible)
Definition: vtkwidget.cpp:282
double zMin() const
Definition: vtkwidget.cpp:357
bool defaultRendererTaken() const
Definition: vtkwidget.cpp:321
QList< vtkProp * > actors() const
Definition: vtkwidget.cpp:276
QVTKInteractor * GetInteractor()
Definition: vtkwidget.h:68
double yMin() const
Definition: vtkwidget.cpp:353
void addActor(vtkProp *actor, const QColor &clr=Qt::black)
Definition: vtkwidget.cpp:204
void setBounds(double *bounds)
Definition: vtkwidget.cpp:344
double yMax() const
Definition: vtkwidget.cpp:355
double xMin() const
Definition: vtkwidget.cpp:349
void setMultiViewports(bool multi=true)
Definition: vtkwidget.cpp:138
double zMax() const
Definition: vtkwidget.cpp:359
GraphType data
Definition: graph_cut.cc:138
void vtkColor(const QColor &clr, double *vtkClr)
Definition: utils.cpp:60
void layoutRenderers< 7 >(const QList< vtkRenderer * > &renderers)
void layoutRenderers< 5 >(const QList< vtkRenderer * > &renderers)
void layoutRenderers(const QList< vtkRenderer * > &renderers)
void layoutRenderers< 8 >(const QList< vtkRenderer * > &renderers)
void vtkInitOnce(T **obj)
Definition: vtkutils.h:44
void layoutRenderers< 10 >(const QList< vtkRenderer * > &renderers)
void layoutRenderers< 1 >(const QList< vtkRenderer * > &renderers)
void layoutRenderers< 4 >(const QList< vtkRenderer * > &renderers)
void layoutRenderers< 3 >(const QList< vtkRenderer * > &renderers)
int getDefaultScalarInterpolationForDataSet(vtkDataSet *data)
Definition: vtkwidget.cpp:151
void layoutRenderers< 9 >(const QList< vtkRenderer * > &renderers)
void layoutRenderers< 2 >(const QList< vtkRenderer * > &renderers)
void layoutRenderers< 6 >(const QList< vtkRenderer * > &renderers)
constexpr Rgb black(0, 0, 0)
#define VTK_CREATE(type, name)