Home | History | Annotate | Download | only in src
      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, ozantonkal (at) gmail.com
     42 //  * Anatoly Baksheev, Itseez Inc.  myname.mysurname <> mycompany.com
     43 //
     44 //M*/
     45 
     46 #include "precomp.hpp"
     47 
     48 ///////////////////////////////////////////////////////////////////////////////////////////////
     49 /// widget implementation
     50 
     51 class cv::viz::Widget::Impl
     52 {
     53 public:
     54     vtkSmartPointer<vtkProp> prop;
     55     Impl() : prop(0) {}
     56 };
     57 
     58 cv::viz::Widget::Widget() : impl_( new Impl() ) { }
     59 
     60 cv::viz::Widget::Widget(const Widget& other) : impl_( new Impl() )
     61 {
     62     if (other.impl_ && other.impl_->prop)
     63         impl_->prop = other.impl_->prop;
     64 }
     65 
     66 cv::viz::Widget& cv::viz::Widget::operator=(const Widget& other)
     67 {
     68     if (!impl_)
     69         impl_ = new Impl();
     70 
     71     if (other.impl_)
     72         impl_->prop = other.impl_->prop;
     73     return *this;
     74 }
     75 
     76 cv::viz::Widget::~Widget()
     77 {
     78     if (impl_)
     79     {
     80         delete impl_;
     81         impl_ = 0;
     82     }
     83 }
     84 
     85 cv::viz::Widget cv::viz::Widget::fromPlyFile(const String &file_name)
     86 {
     87     CV_Assert(vtkPLYReader::CanReadFile(file_name.c_str()));
     88 
     89     vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New();
     90     reader->SetFileName(file_name.c_str());
     91 
     92     vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
     93     mapper->SetInputConnection( reader->GetOutputPort() );
     94     mapper->ImmediateModeRenderingOff();
     95 
     96     vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
     97     actor->GetProperty()->SetInterpolationToFlat();
     98     actor->GetProperty()->BackfaceCullingOn();
     99     actor->SetMapper(mapper);
    100 
    101     Widget widget;
    102     WidgetAccessor::setProp(widget, actor);
    103     return widget;
    104 }
    105 
    106 void cv::viz::Widget::setRenderingProperty(int property, double value)
    107 {
    108     vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this));
    109     CV_Assert("Widget type is not supported." && actor);
    110 
    111     switch (property)
    112     {
    113         case POINT_SIZE:          actor->GetProperty()->SetPointSize(float(value)); break;
    114         case OPACITY:             actor->GetProperty()->SetOpacity(value);          break;
    115         case LINE_WIDTH:          actor->GetProperty()->SetLineWidth(float(value)); break;
    116         case IMMEDIATE_RENDERING: actor->GetMapper()->SetImmediateModeRendering(int(value)); break;
    117         case FONT_SIZE:
    118         {
    119             vtkTextActor* text_actor = vtkTextActor::SafeDownCast(actor);
    120             CV_Assert("Widget does not have text content." && text_actor);
    121             text_actor->GetTextProperty()->SetFontSize(int(value));
    122             break;
    123         }
    124         case REPRESENTATION:
    125         {
    126             switch (int(value))
    127             {
    128                 case REPRESENTATION_POINTS:    actor->GetProperty()->SetRepresentationToPoints(); break;
    129                 case REPRESENTATION_WIREFRAME: actor->GetProperty()->SetRepresentationToWireframe(); break;
    130                 case REPRESENTATION_SURFACE:   actor->GetProperty()->SetRepresentationToSurface();  break;
    131             }
    132             break;
    133         }
    134         case SHADING:
    135         {
    136             switch (int(value))
    137             {
    138                 case SHADING_FLAT: actor->GetProperty()->SetInterpolationToFlat(); break;
    139                 case SHADING_GOURAUD:
    140                 {
    141                     if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals())
    142                     {
    143                         vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper());
    144                         CV_Assert("Can't set shading property for such type of widget" && mapper);
    145 
    146                         vtkSmartPointer<vtkPolyData> with_normals = VtkUtils::ComputeNormals(mapper->GetInput());
    147                         VtkUtils::SetInputData(mapper, with_normals);
    148                     }
    149                     actor->GetProperty()->SetInterpolationToGouraud();
    150                     break;
    151                 }
    152                 case SHADING_PHONG:
    153                 {
    154                     if (!actor->GetMapper()->GetInput()->GetPointData()->GetNormals())
    155                     {
    156                         vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper());
    157                         CV_Assert("Can't set shading property for such type of widget" && mapper);
    158 
    159                         vtkSmartPointer<vtkPolyData> with_normals = VtkUtils::ComputeNormals(mapper->GetInput());
    160                         VtkUtils::SetInputData(mapper, with_normals);
    161                     }
    162                     actor->GetProperty()->SetInterpolationToPhong();
    163                     break;
    164                 }
    165             }
    166             break;
    167         }
    168         default:
    169             CV_Assert("setPointCloudRenderingProperties: Unknown property");
    170     }
    171     actor->Modified();
    172 }
    173 
    174 double cv::viz::Widget::getRenderingProperty(int property) const
    175 {
    176     vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this));
    177     CV_Assert("Widget type is not supported." && actor);
    178 
    179     double value = 0.0;
    180     switch (property)
    181     {
    182         case POINT_SIZE: value = actor->GetProperty()->GetPointSize(); break;
    183         case OPACITY:    value = actor->GetProperty()->GetOpacity();   break;
    184         case LINE_WIDTH: value = actor->GetProperty()->GetLineWidth(); break;
    185         case IMMEDIATE_RENDERING:  value = actor->GetMapper()->GetImmediateModeRendering();  break;
    186 
    187         case FONT_SIZE:
    188         {
    189             vtkTextActor* text_actor = vtkTextActor::SafeDownCast(actor);
    190             CV_Assert("Widget does not have text content." && text_actor);
    191             value = text_actor->GetTextProperty()->GetFontSize();;
    192             break;
    193         }
    194         case REPRESENTATION:
    195         {
    196             switch (actor->GetProperty()->GetRepresentation())
    197             {
    198                 case VTK_POINTS:    value = REPRESENTATION_POINTS; break;
    199                 case VTK_WIREFRAME: value = REPRESENTATION_WIREFRAME; break;
    200                 case VTK_SURFACE:   value = REPRESENTATION_SURFACE; break;
    201             }
    202             break;
    203         }
    204         case SHADING:
    205         {
    206             switch (actor->GetProperty()->GetInterpolation())
    207             {
    208                 case VTK_FLAT:      value = SHADING_FLAT; break;
    209                 case VTK_GOURAUD:   value = SHADING_GOURAUD; break;
    210                 case VTK_PHONG:     value = SHADING_PHONG; break;
    211             }
    212             break;
    213         }
    214         default:
    215             CV_Assert("getPointCloudRenderingProperties: Unknown property");
    216     }
    217     return value;
    218 }
    219 
    220 ///////////////////////////////////////////////////////////////////////////////////////////////
    221 /// widget accessor implementaion
    222 
    223 vtkSmartPointer<vtkProp> cv::viz::WidgetAccessor::getProp(const Widget& widget)
    224 {
    225     return widget.impl_->prop;
    226 }
    227 
    228 void cv::viz::WidgetAccessor::setProp(Widget& widget, vtkSmartPointer<vtkProp> prop)
    229 {
    230     widget.impl_->prop = prop;
    231 }
    232 
    233 ///////////////////////////////////////////////////////////////////////////////////////////////
    234 /// widget3D implementation
    235 
    236 void cv::viz::Widget3D::setPose(const Affine3d &pose)
    237 {
    238     vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
    239     CV_Assert("Widget is not 3D." && actor);
    240 
    241     vtkSmartPointer<vtkMatrix4x4> matrix = vtkmatrix(pose.matrix);
    242     actor->SetUserMatrix(matrix);
    243     actor->Modified();
    244 }
    245 
    246 void cv::viz::Widget3D::updatePose(const Affine3d &pose)
    247 {
    248     vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
    249     CV_Assert("Widget is not 3D." && actor);
    250 
    251     vtkSmartPointer<vtkMatrix4x4> matrix = actor->GetUserMatrix();
    252     if (!matrix)
    253     {
    254         setPose(pose);
    255         return;
    256     }
    257 
    258     Affine3d updated_pose = pose * Affine3d(*matrix->Element);
    259     matrix = vtkmatrix(updated_pose.matrix);
    260 
    261     actor->SetUserMatrix(matrix);
    262     actor->Modified();
    263 }
    264 
    265 cv::Affine3d cv::viz::Widget3D::getPose() const
    266 {
    267     vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(*this));
    268     CV_Assert("Widget is not 3D." && actor);
    269     return Affine3d(*actor->GetUserMatrix()->Element);
    270 }
    271 
    272 void cv::viz::Widget3D::applyTransform(const Affine3d &transform)
    273 {
    274     vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this));
    275     CV_Assert("Widget is not 3D actor." && actor);
    276 
    277     vtkSmartPointer<vtkPolyDataMapper> mapper = vtkPolyDataMapper::SafeDownCast(actor->GetMapper());
    278     CV_Assert("Widget doesn't have a polydata mapper" && mapper);
    279     mapper->Update();
    280 
    281     VtkUtils::SetInputData(mapper, VtkUtils::TransformPolydata(mapper->GetInput(), transform));
    282 }
    283 
    284 void cv::viz::Widget3D::setColor(const Color &color)
    285 {
    286     // Cast to actor instead of prop3d since prop3d doesn't provide getproperty
    287     vtkActor *actor = vtkActor::SafeDownCast(WidgetAccessor::getProp(*this));
    288     CV_Assert("Widget type is not supported." && actor);
    289 
    290     Color c = vtkcolor(color);
    291     actor->GetMapper()->ScalarVisibilityOff();
    292     actor->GetProperty()->SetColor(c.val);
    293     actor->GetProperty()->SetEdgeColor(c.val);
    294     actor->Modified();
    295 }
    296 
    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     Widget3D widget;
    303     WidgetAccessor::setProp(widget, actor);
    304     return widget;
    305 }
    306 
    307 ///////////////////////////////////////////////////////////////////////////////////////////////
    308 /// widget2D implementation
    309 
    310 void cv::viz::Widget2D::setColor(const Color &color)
    311 {
    312     vtkActor2D *actor = vtkActor2D::SafeDownCast(WidgetAccessor::getProp(*this));
    313     CV_Assert("Widget type is not supported." && actor);
    314     Color c = vtkcolor(color);
    315     actor->GetProperty()->SetColor(c.val);
    316     actor->Modified();
    317 }
    318 
    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     Widget2D widget;
    325     WidgetAccessor::setProp(widget, actor);
    326     return widget;
    327 }
    328