widget.cpp 12 KB
Newer Older
Ozan Tonkal's avatar
Ozan Tonkal committed
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"

ozantonkal's avatar
ozantonkal committed
48 49 50
///////////////////////////////////////////////////////////////////////////////////////////////
/// widget implementation

Anatoly Baksheev's avatar
Anatoly Baksheev committed
51
class cv::viz::Widget::Impl
52 53
{
public:
Anatoly Baksheev's avatar
Anatoly Baksheev committed
54 55
    vtkSmartPointer<vtkProp> prop;
    Impl() : prop(0) {}
ozantonkal's avatar
ozantonkal committed
56
};
57

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

60
cv::viz::Widget::Widget(const Widget& other) : impl_( new Impl() )
Ozan Tonkal's avatar
Ozan Tonkal committed
61
{
Anatoly Baksheev's avatar
Anatoly Baksheev committed
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)
{
Anatoly Baksheev's avatar
Anatoly Baksheev committed
68 69 70 71 72
    if (!impl_)
        impl_ = new Impl();

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

Ozan Tonkal's avatar
Ozan Tonkal committed
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)
{
Anatoly Baksheev's avatar
Anatoly Baksheev committed
87 88
    CV_Assert(vtkPLYReader::CanReadFile(file_name.c_str()));

89 90
    vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New();
    reader->SetFileName(file_name.c_str());
Ozan Tonkal's avatar
Ozan Tonkal committed
91

92
    vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
Anatoly Baksheev's avatar
Anatoly Baksheev committed
93
    mapper->SetInputConnection( reader->GetOutputPort() );
94
    mapper->ImmediateModeRenderingOff();
95

Anatoly Baksheev's avatar
Anatoly Baksheev committed
96
    vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
97 98 99
    actor->GetProperty()->SetInterpolationToFlat();
    actor->GetProperty()->BackfaceCullingOn();
    actor->SetMapper(mapper);
Ozan Tonkal's avatar
Ozan Tonkal committed
100

101
    Widget widget;
Anatoly Baksheev's avatar
Anatoly Baksheev committed
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);
Ozan Tonkal's avatar
Ozan Tonkal committed
110

111 112
    switch (property)
    {
Anatoly Baksheev's avatar
Anatoly Baksheev committed
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
        case AMBIENT:             actor->GetProperty()->SetAmbient(float(value)); break;
118 119 120 121 122 123 124 125
        case LIGHTING:
        {
            if (value == 0)
                actor->GetProperty()->LightingOff();
            else
                actor->GetProperty()->LightingOn();
            break;
        }
126 127 128 129
        case FONT_SIZE:
        {
            vtkTextActor* text_actor = vtkTextActor::SafeDownCast(actor);
            CV_Assert("Widget does not have text content." && text_actor);
Anatoly Baksheev's avatar
Anatoly Baksheev committed
130
            text_actor->GetTextProperty()->SetFontSize(int(value));
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
            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())
                    {
152
                        vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper());
153 154 155 156
                        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);
157 158 159 160 161 162 163 164
                    }
                    actor->GetProperty()->SetInterpolationToGouraud();
                    break;
                }
                case SHADING_PHONG:
                {
                    if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals())
                    {
165
                        vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper());
166 167 168 169
                        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);
170 171 172 173 174 175 176
                    }
                    actor->GetProperty()->SetInterpolationToPhong();
                    break;
                }
            }
            break;
        }
177 178 179
        default:
            CV_Assert("setPointCloudRenderingProperties: Unknown property");
    }
Anatoly Baksheev's avatar
Anatoly Baksheev committed
180
    actor->Modified();
181 182 183 184 185
}

double cv::viz::Widget::getRenderingProperty(int property) const
{
    vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this));
186
    CV_Assert("Widget type is not supported." && actor);
Ozan Tonkal's avatar
Ozan Tonkal committed
187

188 189 190
    double value = 0.0;
    switch (property)
    {
Anatoly Baksheev's avatar
Anatoly Baksheev committed
191 192 193 194 195
        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;

196
        case FONT_SIZE:
197
        {
198 199
            vtkTextActor* text_actor = vtkTextActor::SafeDownCast(actor);
            CV_Assert("Widget does not have text content." && text_actor);
Anatoly Baksheev's avatar
Anatoly Baksheev committed
200
            value = text_actor->GetTextProperty()->GetFontSize();;
201 202 203 204 205
            break;
        }
        case REPRESENTATION:
        {
            switch (actor->GetProperty()->GetRepresentation())
206
            {
207 208 209
                case VTK_POINTS:    value = REPRESENTATION_POINTS; break;
                case VTK_WIREFRAME: value = REPRESENTATION_WIREFRAME; break;
                case VTK_SURFACE:   value = REPRESENTATION_SURFACE; break;
210 211 212
            }
            break;
        }
213
        case SHADING:
214
        {
215
            switch (actor->GetProperty()->GetInterpolation())
216
            {
217 218 219
                case VTK_FLAT:      value = SHADING_FLAT; break;
                case VTK_GOURAUD:   value = SHADING_GOURAUD; break;
                case VTK_PHONG:     value = SHADING_PHONG; break;
220 221 222 223 224 225 226 227 228
            }
            break;
        }
        default:
            CV_Assert("getPointCloudRenderingProperties: Unknown property");
    }
    return value;
}

229
///////////////////////////////////////////////////////////////////////////////////////////////
ozantonkal's avatar
ozantonkal committed
230
/// widget accessor implementaion
231

Anatoly Baksheev's avatar
Anatoly Baksheev committed
232
vtkSmartPointer<vtkProp> cv::viz::WidgetAccessor::getProp(const Widget& widget)
233
{
Anatoly Baksheev's avatar
Anatoly Baksheev committed
234
    return widget.impl_->prop;
235 236
}

Anatoly Baksheev's avatar
Anatoly Baksheev committed
237
void cv::viz::WidgetAccessor::setProp(Widget& widget, vtkSmartPointer<vtkProp> prop)
ozantonkal's avatar
ozantonkal committed
238
{
Anatoly Baksheev's avatar
Anatoly Baksheev committed
239
    widget.impl_->prop = prop;
ozantonkal's avatar
ozantonkal committed
240 241
}

242
///////////////////////////////////////////////////////////////////////////////////////////////
ozantonkal's avatar
ozantonkal committed
243
/// widget3D implementation
244

245
void cv::viz::Widget3D::setPose(const Affine3d &pose)
246
{
247
    vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
248
    CV_Assert("Widget is not 3D." && actor);
Ozan Tonkal's avatar
Ozan Tonkal committed
249

250
    vtkSmartPointer<vtkMatrix4x4> matrix = vtkmatrix(pose.matrix);
251 252
    actor->SetUserMatrix(matrix);
    actor->Modified();
253 254
}

255
void cv::viz::Widget3D::updatePose(const Affine3d &pose)
256
{
257
    vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
258
    CV_Assert("Widget is not 3D." && actor);
Ozan Tonkal's avatar
Ozan Tonkal committed
259

ozantonkal's avatar
ozantonkal committed
260 261
    vtkSmartPointer<vtkMatrix4x4> matrix = actor->GetUserMatrix();
    if (!matrix)
262
    {
ozantonkal's avatar
ozantonkal committed
263
        setPose(pose);
Anatoly Baksheev's avatar
Anatoly Baksheev committed
264
        return;
265
    }
266

267 268
    Affine3d updated_pose = pose * Affine3d(*matrix->Element);
    matrix = vtkmatrix(updated_pose.matrix);
269

270 271
    actor->SetUserMatrix(matrix);
    actor->Modified();
272 273
}

274
cv::Affine3d cv::viz::Widget3D::getPose() const
275
{
276
    vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
277
    CV_Assert("Widget is not 3D." && actor);
278
    return Affine3d(*actor->GetUserMatrix()->Element);
279
}
280

Anatoly Baksheev's avatar
Anatoly Baksheev committed
281 282 283 284 285 286 287
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);
288
    mapper->Update();
Anatoly Baksheev's avatar
Anatoly Baksheev committed
289 290 291 292

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

Anatoly Baksheev's avatar
Anatoly Baksheev committed
293
void cv::viz::Widget3D::setColor(const Color &color)
294
{
ozantonkal's avatar
ozantonkal committed
295
    // Cast to actor instead of prop3d since prop3d doesn't provide getproperty
296
    vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this));
297
    CV_Assert("Widget type is not supported." && actor);
Ozan Tonkal's avatar
Ozan Tonkal committed
298

ozantonkal's avatar
ozantonkal committed
299
    Color c = vtkcolor(color);
300 301 302 303
    actor->GetMapper()->ScalarVisibilityOff();
    actor->GetProperty()->SetColor(c.val);
    actor->GetProperty()->SetEdgeColor(c.val);
    actor->Modified();
304
}
305

Anatoly Baksheev's avatar
Anatoly Baksheev committed
306
template<> cv::viz::Widget3D cv::viz::Widget::cast<cv::viz::Widget3D>()
307 308
{
    vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
309
    CV_Assert("Widget cannot be cast." && actor);
310 311 312 313 314 315

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

316 317 318
///////////////////////////////////////////////////////////////////////////////////////////////
/// widget2D implementation

Anatoly Baksheev's avatar
Anatoly Baksheev committed
319
void cv::viz::Widget2D::setColor(const Color &color)
320
{
321
    vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this));
322
    CV_Assert("Widget type is not supported." && actor);
323
    Color c = vtkcolor(color);
324 325
    actor->GetProperty()->SetColor(c.val);
    actor->Modified();
Anatoly Baksheev's avatar
Anatoly Baksheev committed
326
}
327

Anatoly Baksheev's avatar
Anatoly Baksheev committed
328
template<> cv::viz::Widget2D cv::viz::Widget::cast<cv::viz::Widget2D>()
329 330
{
    vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this));
331
    CV_Assert("Widget cannot be cast." && actor);
332 333 334 335 336

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