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@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;
Impl()55 Impl() : prop(0) {}
56 };
57
Widget()58 cv::viz::Widget::Widget() : impl_( new Impl() ) { }
59
Widget(const Widget & other)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
operator =(const Widget & other)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
~Widget()76 cv::viz::Widget::~Widget()
77 {
78 if (impl_)
79 {
80 delete impl_;
81 impl_ = 0;
82 }
83 }
84
fromPlyFile(const String & file_name)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
setRenderingProperty(int property,double value)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
getRenderingProperty(int property) const174 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
getProp(const Widget & widget)223 vtkSmartPointer<vtkProp> cv::viz::WidgetAccessor::getProp(const Widget& widget)
224 {
225 return widget.impl_->prop;
226 }
227
setProp(Widget & widget,vtkSmartPointer<vtkProp> prop)228 void cv::viz::WidgetAccessor::setProp(Widget& widget, vtkSmartPointer<vtkProp> prop)
229 {
230 widget.impl_->prop = prop;
231 }
232
233 ///////////////////////////////////////////////////////////////////////////////////////////////
234 /// widget3D implementation
235
setPose(const Affine3d & pose)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
updatePose(const Affine3d & pose)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
getPose() const265 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
applyTransform(const Affine3d & transform)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
setColor(const Color & color)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
cast()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
setColor(const Color & color)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
cast()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