Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/viz/src/clouds.cpp
16354 views
1
/*M///////////////////////////////////////////////////////////////////////////////////////
2
//
3
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4
//
5
// By downloading, copying, installing or using the software you agree to this license.
6
// If you do not agree to this license, do not download, install,
7
// copy or use the software.
8
//
9
//
10
// License Agreement
11
// For Open Source Computer Vision Library
12
//
13
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
14
// Third party copyrights are property of their respective owners.
15
//
16
// Redistribution and use in source and binary forms, with or without modification,
17
// are permitted provided that the following conditions are met:
18
//
19
// * Redistribution's of source code must retain the above copyright notice,
20
// this list of conditions and the following disclaimer.
21
//
22
// * Redistribution's in binary form must reproduce the above copyright notice,
23
// this list of conditions and the following disclaimer in the documentation
24
// and/or other materials provided with the distribution.
25
//
26
// * The name of the copyright holders may not be used to endorse or promote products
27
// derived from this software without specific prior written permission.
28
//
29
// This software is provided by the copyright holders and contributors "as is" and
30
// any express or implied warranties, including, but not limited to, the implied
31
// warranties of merchantability and fitness for a particular purpose are disclaimed.
32
// In no event shall the Intel Corporation or contributors be liable for any direct,
33
// indirect, incidental, special, exemplary, or consequential damages
34
// (including, but not limited to, procurement of substitute goods or services;
35
// loss of use, data, or profits; or business interruption) however caused
36
// and on any theory of liability, whether in contract, strict liability,
37
// or tort (including negligence or otherwise) arising in any way out of
38
// the use of this software, even if advised of the possibility of such damage.
39
//
40
// Authors:
41
// * Ozan Tonkal, [email protected]
42
// * Anatoly Baksheev, Itseez Inc. myname.mysurname <> mycompany.com
43
//
44
//M*/
45
46
#include "precomp.hpp"
47
48
///////////////////////////////////////////////////////////////////////////////////////////////
49
/// Point Cloud Widget implementation
50
51
cv::viz::WCloud::WCloud(InputArray cloud, InputArray colors)
52
{
53
WCloud cloud_widget(cloud, colors, cv::noArray());
54
*this = cloud_widget;
55
}
56
57
cv::viz::WCloud::WCloud(InputArray cloud, const Color &color)
58
{
59
WCloud cloud_widget(cloud, Mat(cloud.size(), CV_8UC3, color));
60
*this = cloud_widget;
61
}
62
63
cv::viz::WCloud::WCloud(InputArray cloud, const Color &color, InputArray normals)
64
{
65
WCloud cloud_widget(cloud, Mat(cloud.size(), CV_8UC3, color), normals);
66
*this = cloud_widget;
67
}
68
69
cv::viz::WCloud::WCloud(cv::InputArray cloud, cv::InputArray colors, cv::InputArray normals)
70
{
71
CV_Assert(!cloud.empty() && !colors.empty());
72
73
vtkSmartPointer<vtkCloudMatSource> cloud_source = vtkSmartPointer<vtkCloudMatSource>::New();
74
cloud_source->SetColorCloudNormals(cloud, colors, normals);
75
cloud_source->Update();
76
77
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
78
VtkUtils::SetInputData(mapper, cloud_source->GetOutput());
79
mapper->SetScalarModeToUsePointData();
80
#if VTK_MAJOR_VERSION < 8
81
mapper->ImmediateModeRenderingOff();
82
#endif
83
mapper->SetScalarRange(0, 255);
84
mapper->ScalarVisibilityOn();
85
86
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
87
actor->GetProperty()->SetInterpolationToFlat();
88
actor->GetProperty()->BackfaceCullingOn();
89
actor->SetMapper(mapper);
90
91
WidgetAccessor::setProp(*this, actor);
92
}
93
94
template<> cv::viz::WCloud cv::viz::Widget::cast<cv::viz::WCloud>()
95
{
96
Widget3D widget = this->cast<Widget3D>();
97
return static_cast<WCloud&>(widget);
98
}
99
100
///////////////////////////////////////////////////////////////////////////////////////////////
101
/// Painted Cloud Widget implementation
102
103
cv::viz::WPaintedCloud::WPaintedCloud(InputArray cloud)
104
{
105
vtkSmartPointer<vtkCloudMatSource> cloud_source = vtkSmartPointer<vtkCloudMatSource>::New();
106
cloud_source->SetCloud(cloud);
107
cloud_source->Update();
108
109
Vec6d bounds(cloud_source->GetOutput()->GetPoints()->GetBounds());
110
111
vtkSmartPointer<vtkElevationFilter> elevation = vtkSmartPointer<vtkElevationFilter>::New();
112
elevation->SetInputConnection(cloud_source->GetOutputPort());
113
elevation->SetLowPoint(bounds[0], bounds[2], bounds[4]);
114
elevation->SetHighPoint(bounds[1], bounds[3], bounds[5]);
115
elevation->SetScalarRange(0.0, 1.0);
116
elevation->Update();
117
118
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
119
VtkUtils::SetInputData(mapper, vtkPolyData::SafeDownCast(elevation->GetOutput()));
120
#if VTK_MAJOR_VERSION < 8
121
mapper->ImmediateModeRenderingOff();
122
#endif
123
mapper->ScalarVisibilityOn();
124
mapper->SetColorModeToMapScalars();
125
126
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
127
actor->GetProperty()->SetInterpolationToFlat();
128
actor->GetProperty()->BackfaceCullingOn();
129
actor->SetMapper(mapper);
130
131
WidgetAccessor::setProp(*this, actor);
132
}
133
134
cv::viz::WPaintedCloud::WPaintedCloud(InputArray cloud, const Point3d& p1, const Point3d& p2)
135
{
136
vtkSmartPointer<vtkCloudMatSource> cloud_source = vtkSmartPointer<vtkCloudMatSource>::New();
137
cloud_source->SetCloud(cloud);
138
139
vtkSmartPointer<vtkElevationFilter> elevation = vtkSmartPointer<vtkElevationFilter>::New();
140
elevation->SetInputConnection(cloud_source->GetOutputPort());
141
elevation->SetLowPoint(p1.x, p1.y, p1.z);
142
elevation->SetHighPoint(p2.x, p2.y, p2.z);
143
elevation->SetScalarRange(0.0, 1.0);
144
elevation->Update();
145
146
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
147
VtkUtils::SetInputData(mapper, vtkPolyData::SafeDownCast(elevation->GetOutput()));
148
#if VTK_MAJOR_VERSION < 8
149
mapper->ImmediateModeRenderingOff();
150
#endif
151
mapper->ScalarVisibilityOn();
152
mapper->SetColorModeToMapScalars();
153
154
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
155
actor->GetProperty()->SetInterpolationToFlat();
156
actor->GetProperty()->BackfaceCullingOn();
157
actor->SetMapper(mapper);
158
159
WidgetAccessor::setProp(*this, actor);
160
}
161
162
cv::viz::WPaintedCloud::WPaintedCloud(InputArray cloud, const Point3d& p1, const Point3d& p2, const Color& c1, const Color c2)
163
{
164
vtkSmartPointer<vtkCloudMatSource> cloud_source = vtkSmartPointer<vtkCloudMatSource>::New();
165
cloud_source->SetCloud(cloud);
166
167
vtkSmartPointer<vtkElevationFilter> elevation = vtkSmartPointer<vtkElevationFilter>::New();
168
elevation->SetInputConnection(cloud_source->GetOutputPort());
169
elevation->SetLowPoint(p1.x, p1.y, p1.z);
170
elevation->SetHighPoint(p2.x, p2.y, p2.z);
171
elevation->SetScalarRange(0.0, 1.0);
172
elevation->Update();
173
174
Color vc1 = vtkcolor(c1), vc2 = vtkcolor(c2);
175
vtkSmartPointer<vtkColorTransferFunction> color_transfer = vtkSmartPointer<vtkColorTransferFunction>::New();
176
color_transfer->SetColorSpaceToRGB();
177
color_transfer->AddRGBPoint(0.0, vc1[0], vc1[1], vc1[2]);
178
color_transfer->AddRGBPoint(1.0, vc2[0], vc2[1], vc2[2]);
179
color_transfer->SetScaleToLinear();
180
color_transfer->Build();
181
182
//if in future some need to replace color table with real scalars, then this can be done usine next calls:
183
//vtkDataArray *float_scalars = vtkPolyData::SafeDownCast(elevation->GetOutput())->GetPointData()->GetArray("Elevation");
184
//vtkSmartPointer<vtkPolyData> polydata = cloud_source->GetOutput();
185
//polydata->GetPointData()->SetScalars(color_transfer->MapScalars(float_scalars, VTK_COLOR_MODE_DEFAULT, 0));
186
187
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
188
VtkUtils::SetInputData(mapper, vtkPolyData::SafeDownCast(elevation->GetOutput()));
189
#if VTK_MAJOR_VERSION < 8
190
mapper->ImmediateModeRenderingOff();
191
#endif
192
mapper->ScalarVisibilityOn();
193
mapper->SetColorModeToMapScalars();
194
mapper->SetLookupTable(color_transfer);
195
196
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
197
actor->GetProperty()->SetInterpolationToFlat();
198
actor->GetProperty()->BackfaceCullingOn();
199
actor->SetMapper(mapper);
200
201
WidgetAccessor::setProp(*this, actor);
202
}
203
204
template<> cv::viz::WPaintedCloud cv::viz::Widget::cast<cv::viz::WPaintedCloud>()
205
{
206
Widget3D widget = this->cast<Widget3D>();
207
return static_cast<WPaintedCloud&>(widget);
208
}
209
210
///////////////////////////////////////////////////////////////////////////////////////////////
211
/// Cloud Collection Widget implementation
212
213
cv::viz::WCloudCollection::WCloudCollection()
214
{
215
vtkSmartPointer<vtkAppendPolyData> append_filter = vtkSmartPointer<vtkAppendPolyData>::New();
216
217
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
218
mapper->SetInputConnection(append_filter->GetOutputPort());
219
mapper->SetScalarModeToUsePointData();
220
#if VTK_MAJOR_VERSION < 8
221
mapper->ImmediateModeRenderingOff();
222
#endif
223
mapper->SetScalarRange(0, 255);
224
mapper->ScalarVisibilityOn();
225
226
vtkSmartPointer<vtkLODActor> actor = vtkSmartPointer<vtkLODActor>::New();
227
actor->SetNumberOfCloudPoints(1);
228
actor->GetProperty()->SetInterpolationToFlat();
229
actor->GetProperty()->BackfaceCullingOn();
230
actor->SetMapper(mapper);
231
232
WidgetAccessor::setProp(*this, actor);
233
}
234
235
void cv::viz::WCloudCollection::addCloud(InputArray cloud, InputArray colors, const Affine3d &pose)
236
{
237
vtkSmartPointer<vtkCloudMatSource> source = vtkSmartPointer<vtkCloudMatSource>::New();
238
source->SetColorCloud(cloud, colors);
239
240
vtkSmartPointer<vtkPolyData> polydata = VtkUtils::TransformPolydata(source->GetOutputPort(), pose);
241
242
vtkSmartPointer<vtkLODActor> actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this));
243
CV_Assert("Correctness check." && actor);
244
245
vtkSmartPointer<vtkAlgorithm> producer = actor->GetMapper()->GetInputConnection(0, 0)->GetProducer();
246
vtkSmartPointer<vtkAppendPolyData> append_filter = vtkAppendPolyData::SafeDownCast(producer);
247
VtkUtils::AddInputData(append_filter, polydata);
248
249
actor->SetNumberOfCloudPoints(std::max<vtkIdType>(1, actor->GetNumberOfCloudPoints() + polydata->GetNumberOfPoints()/10));
250
}
251
252
void cv::viz::WCloudCollection::addCloud(InputArray cloud, const Color &color, const Affine3d &pose)
253
{
254
addCloud(cloud, Mat(cloud.size(), CV_8UC3, color), pose);
255
}
256
257
void cv::viz::WCloudCollection::finalize()
258
{
259
vtkSmartPointer<vtkLODActor> actor = vtkLODActor::SafeDownCast(WidgetAccessor::getProp(*this));
260
CV_Assert("Incompatible widget type." && actor);
261
262
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper());
263
CV_Assert("Need to add at least one cloud." && mapper);
264
265
vtkSmartPointer<vtkAlgorithm> producer = mapper->GetInputConnection(0, 0)->GetProducer();
266
vtkSmartPointer<vtkAppendPolyData> append_filter = vtkAppendPolyData::SafeDownCast(producer);
267
append_filter->Update();
268
269
vtkSmartPointer<vtkPolyData> polydata = append_filter->GetOutput();
270
mapper->RemoveInputConnection(0, 0);
271
VtkUtils::SetInputData(mapper, polydata);
272
}
273
274
template<> cv::viz::WCloudCollection cv::viz::Widget::cast<cv::viz::WCloudCollection>()
275
{
276
Widget3D widget = this->cast<Widget3D>();
277
return static_cast<WCloudCollection&>(widget);
278
}
279
280
///////////////////////////////////////////////////////////////////////////////////////////////
281
/// Cloud Normals Widget implementation
282
283
cv::viz::WCloudNormals::WCloudNormals(InputArray _cloud, InputArray _normals, int level, double scale, const Color &color)
284
{
285
Mat cloud = _cloud.getMat();
286
Mat normals = _normals.getMat();
287
288
CV_Assert(cloud.type() == CV_32FC3 || cloud.type() == CV_64FC3 || cloud.type() == CV_32FC4 || cloud.type() == CV_64FC4);
289
CV_Assert(cloud.size() == normals.size() && cloud.type() == normals.type());
290
291
int sqlevel = (int)std::sqrt((double)level);
292
int ystep = (cloud.cols > 1 && cloud.rows > 1) ? sqlevel : 1;
293
int xstep = (cloud.cols > 1 && cloud.rows > 1) ? sqlevel : level;
294
295
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
296
points->SetDataType(cloud.depth() == CV_32F ? VTK_FLOAT : VTK_DOUBLE);
297
298
vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New();
299
300
int s_chs = cloud.channels();
301
int n_chs = normals.channels();
302
int total = 0;
303
304
for(int y = 0; y < cloud.rows; y += ystep)
305
{
306
if (cloud.depth() == CV_32F)
307
{
308
const float *srow = cloud.ptr<float>(y);
309
const float *send = srow + cloud.cols * s_chs;
310
const float *nrow = normals.ptr<float>(y);
311
312
for (; srow < send; srow += xstep * s_chs, nrow += xstep * n_chs)
313
if (!isNan(srow) && !isNan(nrow))
314
{
315
Vec3f endp = Vec3f(srow) + Vec3f(nrow) * (float)scale;
316
317
points->InsertNextPoint(srow);
318
points->InsertNextPoint(endp.val);
319
320
lines->InsertNextCell(2);
321
lines->InsertCellPoint(total++);
322
lines->InsertCellPoint(total++);
323
}
324
}
325
else
326
{
327
const double *srow = cloud.ptr<double>(y);
328
const double *send = srow + cloud.cols * s_chs;
329
const double *nrow = normals.ptr<double>(y);
330
331
for (; srow < send; srow += xstep * s_chs, nrow += xstep * n_chs)
332
if (!isNan(srow) && !isNan(nrow))
333
{
334
Vec3d endp = Vec3d(srow) + Vec3d(nrow) * (double)scale;
335
336
points->InsertNextPoint(srow);
337
points->InsertNextPoint(endp.val);
338
339
lines->InsertNextCell(2);
340
lines->InsertCellPoint(total++);
341
lines->InsertCellPoint(total++);
342
}
343
}
344
}
345
346
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
347
polydata->SetPoints(points);
348
polydata->SetLines(lines);
349
VtkUtils::FillScalars(polydata, color);
350
351
vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
352
VtkUtils::SetInputData(mapper, polydata);
353
354
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
355
actor->SetMapper(mapper);
356
357
WidgetAccessor::setProp(*this, actor);
358
}
359
360
template<> cv::viz::WCloudNormals cv::viz::Widget::cast<cv::viz::WCloudNormals>()
361
{
362
Widget3D widget = this->cast<Widget3D>();
363
return static_cast<WCloudNormals&>(widget);
364
}
365
366
///////////////////////////////////////////////////////////////////////////////////////////////
367
/// Mesh Widget implementation
368
369
cv::viz::WMesh::WMesh(const Mesh &mesh)
370
{
371
CV_Assert(mesh.cloud.rows == 1 && mesh.polygons.type() == CV_32SC1);
372
373
vtkSmartPointer<vtkCloudMatSource> source = vtkSmartPointer<vtkCloudMatSource>::New();
374
source->SetColorCloudNormalsTCoords(mesh.cloud, mesh.colors, mesh.normals, mesh.tcoords);
375
source->Update();
376
377
Mat lookup_buffer(1, (int)mesh.cloud.total(), CV_32SC1);
378
int *lookup = lookup_buffer.ptr<int>();
379
for(int y = 0, index = 0; y < mesh.cloud.rows; ++y)
380
{
381
int s_chs = mesh.cloud.channels();
382
383
if (mesh.cloud.depth() == CV_32F)
384
{
385
const float* srow = mesh.cloud.ptr<float>(y);
386
const float* send = srow + mesh.cloud.cols * s_chs;
387
388
for (; srow != send; srow += s_chs, ++lookup)
389
if (!isNan(srow[0]) && !isNan(srow[1]) && !isNan(srow[2]))
390
*lookup = index++;
391
}
392
393
if (mesh.cloud.depth() == CV_64F)
394
{
395
const double* srow = mesh.cloud.ptr<double>(y);
396
const double* send = srow + mesh.cloud.cols * s_chs;
397
398
for (; srow != send; srow += s_chs, ++lookup)
399
if (!isNan(srow[0]) && !isNan(srow[1]) && !isNan(srow[2]))
400
*lookup = index++;
401
}
402
}
403
lookup = lookup_buffer.ptr<int>();
404
405
vtkSmartPointer<vtkPolyData> polydata = source->GetOutput();
406
polydata->SetVerts(0);
407
408
const int * polygons = mesh.polygons.ptr<int>();
409
vtkSmartPointer<vtkCellArray> cell_array = vtkSmartPointer<vtkCellArray>::New();
410
411
int idx = 0;
412
size_t polygons_size = mesh.polygons.total();
413
for (size_t i = 0; i < polygons_size; ++idx)
414
{
415
int n_points = polygons[i++];
416
417
cell_array->InsertNextCell(n_points);
418
for (int j = 0; j < n_points; ++j, ++idx)
419
cell_array->InsertCellPoint(lookup[polygons[i++]]);
420
}
421
cell_array->GetData()->SetNumberOfValues(idx);
422
cell_array->Squeeze();
423
polydata->SetStrips(cell_array);
424
425
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
426
mapper->SetScalarModeToUsePointData();
427
#if VTK_MAJOR_VERSION < 8
428
mapper->ImmediateModeRenderingOff();
429
#endif
430
VtkUtils::SetInputData(mapper, polydata);
431
432
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
433
//actor->SetNumberOfCloudPoints(std::max(1, polydata->GetNumberOfPoints() / 10));
434
actor->GetProperty()->SetRepresentationToSurface();
435
actor->GetProperty()->BackfaceCullingOff(); // Backface culling is off for higher efficiency
436
actor->GetProperty()->SetInterpolationToFlat();
437
actor->GetProperty()->EdgeVisibilityOff();
438
actor->GetProperty()->ShadingOff();
439
actor->SetMapper(mapper);
440
441
if (!mesh.texture.empty())
442
{
443
vtkSmartPointer<vtkImageMatSource> image_source = vtkSmartPointer<vtkImageMatSource>::New();
444
image_source->SetImage(mesh.texture);
445
446
vtkSmartPointer<vtkTexture> texture = vtkSmartPointer<vtkTexture>::New();
447
texture->SetInputConnection(image_source->GetOutputPort());
448
actor->SetTexture(texture);
449
}
450
451
WidgetAccessor::setProp(*this, actor);
452
}
453
454
cv::viz::WMesh::WMesh(InputArray cloud, InputArray polygons, InputArray colors, InputArray normals)
455
{
456
Mesh mesh;
457
mesh.cloud = cloud.getMat();
458
mesh.colors = colors.getMat();
459
mesh.normals = normals.getMat();
460
mesh.polygons = polygons.getMat();
461
*this = WMesh(mesh);
462
}
463
464
template<> CV_EXPORTS cv::viz::WMesh cv::viz::Widget::cast<cv::viz::WMesh>()
465
{
466
Widget3D widget = this->cast<Widget3D>();
467
return static_cast<WMesh&>(widget);
468
}
469
470
471
///////////////////////////////////////////////////////////////////////////////////////////////
472
/// Widget Merger implementation
473
474
cv::viz::WWidgetMerger::WWidgetMerger()
475
{
476
vtkSmartPointer<vtkAppendPolyData> append_filter = vtkSmartPointer<vtkAppendPolyData>::New();
477
478
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
479
mapper->SetInputConnection(append_filter->GetOutputPort());
480
mapper->SetScalarModeToUsePointData();
481
#if VTK_MAJOR_VERSION < 8
482
mapper->ImmediateModeRenderingOff();
483
#endif
484
mapper->SetScalarRange(0, 255);
485
mapper->ScalarVisibilityOn();
486
487
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
488
actor->GetProperty()->SetInterpolationToFlat();
489
actor->GetProperty()->BackfaceCullingOn();
490
actor->SetMapper(mapper);
491
492
WidgetAccessor::setProp(*this, actor);
493
}
494
495
void cv::viz::WWidgetMerger::addWidget(const Widget3D& widget, const Affine3d &pose)
496
{
497
vtkActor *widget_actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(widget));
498
CV_Assert("Widget is not 3D actor." && widget_actor);
499
500
vtkSmartPointer<vtkPolyDataMapper> widget_mapper = vtkPolyDataMapper::SafeDownCast(widget_actor->GetMapper());
501
CV_Assert("Widget doesn't have a polydata mapper" && widget_mapper);
502
widget_mapper->Update();
503
504
vtkSmartPointer<vtkActor> actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this));
505
vtkSmartPointer<vtkAlgorithm> producer = actor->GetMapper()->GetInputConnection(0, 0)->GetProducer();
506
vtkSmartPointer<vtkAppendPolyData> append_filter = vtkAppendPolyData::SafeDownCast(producer);
507
CV_Assert("Correctness check" && append_filter);
508
509
VtkUtils::AddInputData(append_filter, VtkUtils::TransformPolydata(widget_mapper->GetInput(), pose));
510
}
511
512
void cv::viz::WWidgetMerger::finalize()
513
{
514
vtkSmartPointer<vtkActor> actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this));
515
vtkSmartPointer<vtkAlgorithm> producer = actor->GetMapper()->GetInputConnection(0, 0)->GetProducer();
516
vtkSmartPointer<vtkAppendPolyData> append_filter = vtkAppendPolyData::SafeDownCast(producer);
517
CV_Assert("Correctness check" && append_filter);
518
append_filter->Update();
519
520
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper());
521
mapper->RemoveInputConnection(0, 0);
522
VtkUtils::SetInputData(mapper, append_filter->GetOutput());
523
mapper->Modified();
524
}
525
526
template<> CV_EXPORTS cv::viz::WWidgetMerger cv::viz::Widget::cast<cv::viz::WWidgetMerger>()
527
{
528
Widget3D widget = this->cast<Widget3D>();
529
return static_cast<WWidgetMerger&>(widget);
530
}
531
532