widget.cpp 11.7 KB
Newer Older
O
Ozan Tonkal 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
// Authors:
//  * Ozan Tonkal, ozantonkal@gmail.com
//  * Anatoly Baksheev, Itseez Inc.  myname.mysurname <> mycompany.com
//
//M*/

46 47
#include "precomp.hpp"

O
ozantonkal 已提交
48 49 50
///////////////////////////////////////////////////////////////////////////////////////////////
/// widget implementation

A
Anatoly Baksheev 已提交
51
class cv::viz::Widget::Impl
52 53
{
public:
A
Anatoly Baksheev 已提交
54 55
    vtkSmartPointer<vtkProp> prop;
    Impl() : prop(0) {}
O
ozantonkal 已提交
56
};
57

58
cv::viz::Widget::Widget() : impl_( new Impl() ) { }
59

60
cv::viz::Widget::Widget(const Widget& other) : impl_( new Impl() )
O
Ozan Tonkal 已提交
61
{
A
Anatoly Baksheev 已提交
62 63
    if (other.impl_ && other.impl_->prop)
        impl_->prop = other.impl_->prop;
64 65 66 67
}

cv::viz::Widget& cv::viz::Widget::operator=(const Widget& other)
{
A
Anatoly Baksheev 已提交
68 69 70 71 72
    if (!impl_)
        impl_ = new Impl();

    if (other.impl_)
        impl_->prop = other.impl_->prop;
73 74 75
    return *this;
}

O
Ozan Tonkal 已提交
76 77
cv::viz::Widget::~Widget()
{
78
    if (impl_)
79 80 81 82 83
    {
        delete impl_;
        impl_ = 0;
    }
}
84

85 86
cv::viz::Widget cv::viz::Widget::fromPlyFile(const String &file_name)
{
A
Anatoly Baksheev 已提交
87 88
    CV_Assert(vtkPLYReader::CanReadFile(file_name.c_str()));

89 90
    vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New();
    reader->SetFileName(file_name.c_str());
O
Ozan Tonkal 已提交
91

92
    vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
A
Anatoly Baksheev 已提交
93
    mapper->SetInputConnection( reader->GetOutputPort() );
94
    mapper->ImmediateModeRenderingOff();
95

A
Anatoly Baksheev 已提交
96
    vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
97 98 99
    actor->GetProperty()->SetInterpolationToFlat();
    actor->GetProperty()->BackfaceCullingOn();
    actor->SetMapper(mapper);
O
Ozan Tonkal 已提交
100

101
    Widget widget;
A
Anatoly Baksheev 已提交
102
    WidgetAccessor::setProp(widget, actor);
103 104 105
    return widget;
}

106 107 108
void cv::viz::Widget::setRenderingProperty(int property, double value)
{
    vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this));
109
    CV_Assert("Widget type is not supported." && actor);
O
Ozan Tonkal 已提交
110

111 112
    switch (property)
    {
A
Anatoly Baksheev 已提交
113 114 115 116
        case POINT_SIZE:          actor->GetProperty()->SetPointSize(float(value)); break;
        case OPACITY:             actor->GetProperty()->SetOpacity(value);          break;
        case LINE_WIDTH:          actor->GetProperty()->SetLineWidth(float(value)); break;
        case IMMEDIATE_RENDERING: actor->GetMapper()->SetImmediateModeRendering(int(value)); break;
117 118 119 120
        case FONT_SIZE:
        {
            vtkTextActor* text_actor = vtkTextActor::SafeDownCast(actor);
            CV_Assert("Widget does not have text content." && text_actor);
A
Anatoly Baksheev 已提交
121
            text_actor->GetTextProperty()->SetFontSize(int(value));
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
            break;
        }
        case REPRESENTATION:
        {
            switch (int(value))
            {
                case REPRESENTATION_POINTS:    actor->GetProperty()->SetRepresentationToPoints(); break;
                case REPRESENTATION_WIREFRAME: actor->GetProperty()->SetRepresentationToWireframe(); break;
                case REPRESENTATION_SURFACE:   actor->GetProperty()->SetRepresentationToSurface();  break;
            }
            break;
        }
        case SHADING:
        {
            switch (int(value))
            {
                case SHADING_FLAT: actor->GetProperty()->SetInterpolationToFlat(); break;
                case SHADING_GOURAUD:
                {
                    if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals())
                    {
143
                        vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper());
144 145 146 147
                        CV_Assert("Can't set shading property for such type of widget" && mapper);

                        vtkSmartPointer<vtkPolyData> with_normals = VtkUtils::ComputeNormals(mapper->GetInput());
                        VtkUtils::SetInputData(mapper, with_normals);
148 149 150 151 152 153 154 155
                    }
                    actor->GetProperty()->SetInterpolationToGouraud();
                    break;
                }
                case SHADING_PHONG:
                {
                    if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals())
                    {
156
                        vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper());
157 158 159 160
                        CV_Assert("Can't set shading property for such type of widget" && mapper);

                        vtkSmartPointer<vtkPolyData> with_normals = VtkUtils::ComputeNormals(mapper->GetInput());
                        VtkUtils::SetInputData(mapper, with_normals);
161 162 163 164 165 166 167
                    }
                    actor->GetProperty()->SetInterpolationToPhong();
                    break;
                }
            }
            break;
        }
168 169 170
        default:
            CV_Assert("setPointCloudRenderingProperties: Unknown property");
    }
A
Anatoly Baksheev 已提交
171
    actor->Modified();
172 173 174 175 176
}

double cv::viz::Widget::getRenderingProperty(int property) const
{
    vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this));
177
    CV_Assert("Widget type is not supported." && actor);
O
Ozan Tonkal 已提交
178

179 180 181
    double value = 0.0;
    switch (property)
    {
A
Anatoly Baksheev 已提交
182 183 184 185 186
        case POINT_SIZE: value = actor->GetProperty()->GetPointSize(); break;
        case OPACITY:    value = actor->GetProperty()->GetOpacity();   break;
        case LINE_WIDTH: value = actor->GetProperty()->GetLineWidth(); break;
        case IMMEDIATE_RENDERING:  value = actor->GetMapper()->GetImmediateModeRendering();  break;

187
        case FONT_SIZE:
188
        {
189 190
            vtkTextActor* text_actor = vtkTextActor::SafeDownCast(actor);
            CV_Assert("Widget does not have text content." && text_actor);
A
Anatoly Baksheev 已提交
191
            value = text_actor->GetTextProperty()->GetFontSize();;
192 193 194 195 196
            break;
        }
        case REPRESENTATION:
        {
            switch (actor->GetProperty()->GetRepresentation())
197
            {
198 199 200
                case VTK_POINTS:    value = REPRESENTATION_POINTS; break;
                case VTK_WIREFRAME: value = REPRESENTATION_WIREFRAME; break;
                case VTK_SURFACE:   value = REPRESENTATION_SURFACE; break;
201 202 203
            }
            break;
        }
204
        case SHADING:
205
        {
206
            switch (actor->GetProperty()->GetInterpolation())
207
            {
208 209 210
                case VTK_FLAT:      value = SHADING_FLAT; break;
                case VTK_GOURAUD:   value = SHADING_GOURAUD; break;
                case VTK_PHONG:     value = SHADING_PHONG; break;
211 212 213 214 215 216 217 218 219
            }
            break;
        }
        default:
            CV_Assert("getPointCloudRenderingProperties: Unknown property");
    }
    return value;
}

220
///////////////////////////////////////////////////////////////////////////////////////////////
O
ozantonkal 已提交
221
/// widget accessor implementaion
222

A
Anatoly Baksheev 已提交
223
vtkSmartPointer<vtkProp> cv::viz::WidgetAccessor::getProp(const Widget& widget)
224
{
A
Anatoly Baksheev 已提交
225
    return widget.impl_->prop;
226 227
}

A
Anatoly Baksheev 已提交
228
void cv::viz::WidgetAccessor::setProp(Widget& widget, vtkSmartPointer<vtkProp> prop)
O
ozantonkal 已提交
229
{
A
Anatoly Baksheev 已提交
230
    widget.impl_->prop = prop;
O
ozantonkal 已提交
231 232
}

233
///////////////////////////////////////////////////////////////////////////////////////////////
O
ozantonkal 已提交
234
/// widget3D implementation
235

236
void cv::viz::Widget3D::setPose(const Affine3d &pose)
237
{
O
ozantonkal 已提交
238
    vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
239
    CV_Assert("Widget is not 3D." && actor);
O
Ozan Tonkal 已提交
240

A
Anatoly Baksheev 已提交
241
    vtkSmartPointer<vtkMatrix4x4> matrix = vtkmatrix(pose.matrix);
242 243
    actor->SetUserMatrix(matrix);
    actor->Modified();
244 245
}

246
void cv::viz::Widget3D::updatePose(const Affine3d &pose)
247
{
O
ozantonkal 已提交
248
    vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
249
    CV_Assert("Widget is not 3D." && actor);
O
Ozan Tonkal 已提交
250

O
ozantonkal 已提交
251 252
    vtkSmartPointer<vtkMatrix4x4> matrix = actor->GetUserMatrix();
    if (!matrix)
O
ozantonkal 已提交
253
    {
O
ozantonkal 已提交
254
        setPose(pose);
A
Anatoly Baksheev 已提交
255
        return;
O
ozantonkal 已提交
256
    }
257

A
Anatoly Baksheev 已提交
258 259
    Affine3d updated_pose = pose * Affine3d(*matrix->Element);
    matrix = vtkmatrix(updated_pose.matrix);
O
ozantonkal 已提交
260

261 262
    actor->SetUserMatrix(matrix);
    actor->Modified();
263 264
}

265
cv::Affine3d cv::viz::Widget3D::getPose() const
O
ozantonkal 已提交
266
{
O
ozantonkal 已提交
267
    vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
268
    CV_Assert("Widget is not 3D." && actor);
A
Anatoly Baksheev 已提交
269
    return Affine3d(*actor->GetUserMatrix()->Element);
O
ozantonkal 已提交
270
}
271

A
Anatoly Baksheev 已提交
272 273 274 275 276 277 278
void cv::viz::Widget3D::applyTransform(const Affine3d &transform)
{
    vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this));
    CV_Assert("Widget is not 3D actor." && actor);

    vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper());
    CV_Assert("Widget doesn't have a polydata mapper" && mapper);
279
    mapper->Update();
A
Anatoly Baksheev 已提交
280 281 282 283

    VtkUtils::SetInputData(mapper, VtkUtils::TransformPolydata(mapper->GetInput(), transform));
}

A
Anatoly Baksheev 已提交
284
void cv::viz::Widget3D::setColor(const Color &color)
O
ozantonkal 已提交
285
{
O
ozantonkal 已提交
286
    // Cast to actor instead of prop3d since prop3d doesn't provide getproperty
O
ozantonkal 已提交
287
    vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this));
288
    CV_Assert("Widget type is not supported." && actor);
O
Ozan Tonkal 已提交
289

O
ozantonkal 已提交
290
    Color c = vtkcolor(color);
291 292 293 294
    actor->GetMapper()->ScalarVisibilityOff();
    actor->GetProperty()->SetColor(c.val);
    actor->GetProperty()->SetEdgeColor(c.val);
    actor->Modified();
O
ozantonkal 已提交
295
}
296

A
Anatoly Baksheev 已提交
297
template<> cv::viz::Widget3D cv::viz::Widget::cast<cv::viz::Widget3D>()
298 299
{
    vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
300
    CV_Assert("Widget cannot be cast." && actor);
301 302 303 304 305 306

    Widget3D widget;
    WidgetAccessor::setProp(widget, actor);
    return widget;
}

307 308 309
///////////////////////////////////////////////////////////////////////////////////////////////
/// widget2D implementation

A
Anatoly Baksheev 已提交
310
void cv::viz::Widget2D::setColor(const Color &color)
O
ozantonkal 已提交
311
{
O
ozantonkal 已提交
312
    vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this));
313
    CV_Assert("Widget type is not supported." && actor);
O
ozantonkal 已提交
314
    Color c = vtkcolor(color);
315 316
    actor->GetProperty()->SetColor(c.val);
    actor->Modified();
A
Anatoly Baksheev 已提交
317
}
318

A
Anatoly Baksheev 已提交
319
template<> cv::viz::Widget2D cv::viz::Widget::cast<cv::viz::Widget2D>()
320 321
{
    vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this));
322
    CV_Assert("Widget cannot be cast." && actor);
323 324 325 326 327

    Widget2D widget;
    WidgetAccessor::setProp(widget, actor);
    return widget;
}