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