--- /dev/null
- typedef std::string String;
-
+/*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
+//
+// OpenCV Viz module is complete rewrite of
+// PCL visualization module (www.pointclouds.org)
+//
+//M*/
+
+#ifndef __OPENCV_VIZ_TYPES_HPP__
+#define __OPENCV_VIZ_TYPES_HPP__
+
+#include <string>
+#include <opencv2/core.hpp>
+#include <opencv2/core/affine.hpp>
+
+namespace cv
+{
- KeyboardEvent(bool action, const std::string& key_sym, unsigned char key, bool alt, bool ctrl, bool shift);
+ namespace viz
+ {
+ class CV_EXPORTS Color : public Scalar
+ {
+ public:
+ Color();
+ Color(double gray);
+ Color(double blue, double green, double red);
+
+ Color(const Scalar& color);
+
+ static Color black();
+ static Color blue();
+ static Color green();
+ static Color cyan();
+
+ static Color red();
+ static Color magenta();
+ static Color yellow();
+ static Color white();
+
+ static Color gray();
+ };
+
+ class CV_EXPORTS Mesh3d
+ {
+ public:
+
+ Mat cloud, colors;
+ Mat polygons;
+
+ //! Loads mesh from a given ply file
+ static cv::viz::Mesh3d loadMesh(const String& file);
+
+ private:
+ struct loadMeshImpl;
+ };
+
+ class CV_EXPORTS KeyboardEvent
+ {
+ public:
+ static const unsigned int Alt = 1;
+ static const unsigned int Ctrl = 2;
+ static const unsigned int Shift = 4;
+
+ //! Create a keyboard event
+ //! - Note that action is true if key is pressed, false if released
++ KeyboardEvent(bool action, const String& key_sym, unsigned char key, bool alt, bool ctrl, bool shift);
+
+ bool isAltPressed() const;
+ bool isCtrlPressed() const;
+ bool isShiftPressed() const;
+
+ unsigned char getKeyCode() const;
+
+ const String& getKeySym() const;
+ bool keyDown() const;
+ bool keyUp() const;
+
+ protected:
+
+ bool action_;
+ unsigned int modifiers_;
+ unsigned char key_code_;
+ String key_sym_;
+ };
+
+ class CV_EXPORTS MouseEvent
+ {
+ public:
+ enum Type { MouseMove = 1, MouseButtonPress, MouseButtonRelease, MouseScrollDown, MouseScrollUp, MouseDblClick } ;
+ enum MouseButton { NoButton = 0, LeftButton, MiddleButton, RightButton, VScroll } ;
+
+ MouseEvent(const Type& type, const MouseButton& button, const Point& p, bool alt, bool ctrl, bool shift);
+
+ Type type;
+ MouseButton button;
+ Point pointer;
+ unsigned int key_state;
+ };
+
+ class CV_EXPORTS Camera
+ {
+ public:
+ Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size);
+ Camera(const Vec2f &fov, const Size &window_size);
+ Camera(const cv::Matx33f &K, const Size &window_size);
+ Camera(const cv::Matx44f &proj, const Size &window_size);
+
+ inline const Vec2d & getClip() const { return clip_; }
+ inline void setClip(const Vec2d &clip) { clip_ = clip; }
+
+ inline const Size & getWindowSize() const { return window_size_; }
+ void setWindowSize(const Size &window_size);
+
+ inline const Vec2f & getFov() const { return fov_; }
+ inline void setFov(const Vec2f & fov) { fov_ = fov; }
+
+ inline const Vec2f & getPrincipalPoint() const { return principal_point_; }
+ inline const Vec2f & getFocalLength() const { return focal_; }
+
+ void computeProjectionMatrix(Matx44f &proj) const;
+
+ static Camera KinectCamera(const Size &window_size);
+
+ private:
+ void init(float f_x, float f_y, float c_x, float c_y, const Size &window_size);
+
+ Vec2d clip_;
+ Vec2f fov_;
+ Size window_size_;
+ Vec2f principal_point_;
+ Vec2f focal_;
+ };
+
+ } /* namespace viz */
+} /* namespace cv */
+
+#endif
--- /dev/null
- std::cerr << Mat(clip, false).reshape(1, 1) << "/" << Mat(focal, false).reshape(1, 1) << "/" <<
- Mat(pose, false).reshape(1, 1) << "/" << Mat(view, false).reshape(1, 1) << "/" <<
- cam->GetViewAngle () / 180.0 * CV_PI << "/" <<
- Mat(win_size, false).reshape(1,1) << "/" << Mat(win_pos, false).reshape(1,1) << endl;
+/*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
+//
+// OpenCV Viz module is complete rewrite of
+// PCL visualization module (www.pointclouds.org)
+//
+//M*/
+
+#include "precomp.hpp"
+#include "interactor_style.h"
+
+using namespace cv;
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::InteractorStyle::Initialize()
+{
+ modifier_ = cv::viz::InteractorStyle::KB_MOD_ALT;
+ // Set windows size (width, height) to unknown (-1)
+ win_size_ = Vec2i(-1, -1);
+ win_pos_ = Vec2i(0, 0);
+ max_win_size_ = Vec2i(-1, -1);
+
+ // Create the image filter and PNG writer objects
+ wif_ = vtkSmartPointer<vtkWindowToImageFilter>::New();
+ snapshot_writer_ = vtkSmartPointer<vtkPNGWriter>::New();
+ snapshot_writer_->SetInputConnection(wif_->GetOutputPort());
+
+ init_ = true;
+ stereo_anaglyph_mask_default_ = true;
+
+ // Initialize the keyboard event callback as none
+ keyboardCallback_ = 0;
+ keyboard_callback_cookie_ = 0;
+
+ // Initialize the mouse event callback as none
+ mouseCallback_ = 0;
+ mouse_callback_cookie_ = 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::InteractorStyle::saveScreenshot(const std::string &file)
+{
+ FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
+ wif_->SetInput(Interactor->GetRenderWindow());
+ wif_->Modified(); // Update the WindowToImageFilter
+ snapshot_writer_->Modified();
+ snapshot_writer_->SetFileName(file.c_str());
+ snapshot_writer_->Write();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::InteractorStyle::zoomIn()
+{
+ FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
+ // Zoom in
+ StartDolly();
+ double factor = 10.0 * 0.2 * .5;
+ Dolly(std::pow(1.1, factor));
+ EndDolly();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::InteractorStyle::zoomOut()
+{
+ FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
+ // Zoom out
+ StartDolly();
+ double factor = 10.0 * -0.2 * .5;
+ Dolly(std::pow(1.1, factor));
+ EndDolly();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::InteractorStyle::OnChar()
+{
+ // Make sure we ignore the same events we handle in OnKeyDown to avoid calling things twice
+ FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
+ if (Interactor->GetKeyCode() >= '0' && Interactor->GetKeyCode() <= '9')
+ return;
+ std::string key(Interactor->GetKeySym());
+ if (key.find("XF86ZoomIn") != std::string::npos)
+ zoomIn();
+ else if (key.find("XF86ZoomOut") != std::string::npos)
+ zoomOut();
+
+ int keymod = false;
+ switch (modifier_)
+ {
+ case KB_MOD_ALT:
+ {
+ keymod = Interactor->GetAltKey();
+ break;
+ }
+ case KB_MOD_CTRL:
+ {
+ keymod = Interactor->GetControlKey();
+ break;
+ }
+ case KB_MOD_SHIFT:
+ {
+ keymod = Interactor->GetShiftKey();
+ break;
+ }
+ }
+
+ switch (Interactor->GetKeyCode())
+ {
+ // All of the options below simply exit
+ case 'h': case 'H':
+ case 'l': case 'L':
+ case 'p': case 'P':
+ case 'j': case 'J':
+ case 'c': case 'C':
+ case 43: // KEY_PLUS
+ case 45: // KEY_MINUS
+ case 'f': case 'F':
+ case 'g': case 'G':
+ case 'o': case 'O':
+ case 'u': case 'U':
+ case 'q': case 'Q':
+ {
+ break;
+ }
+ // S and R have a special !ALT case
+ case 'r': case 'R':
+ case 's': case 'S':
+ {
+ if (!keymod)
+ Superclass::OnChar();
+ break;
+ }
+ default:
+ {
+ Superclass::OnChar();
+ break;
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::InteractorStyle::registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie)
+{
+ // Register the callback function and store the user data
+ mouseCallback_ = callback;
+ mouse_callback_cookie_ = cookie;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::InteractorStyle::registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void *cookie)
+{
+ // Register the callback function and store the user data
+ keyboardCallback_ = callback;
+ keyboard_callback_cookie_ = cookie;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void
+cv::viz::InteractorStyle::OnKeyDown()
+{
+
+ CV_Assert("Interactor style not initialized. Please call Initialize() before continuing" && init_);
+ CV_Assert("No renderer given! Use SetRendererCollection() before continuing." && renderer_);
+
+ FindPokedRenderer(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1]);
+
+ if (wif_->GetInput() == NULL)
+ {
+ wif_->SetInput(Interactor->GetRenderWindow());
+ wif_->Modified();
+ snapshot_writer_->Modified();
+ }
+
+ // Save the initial windows width/height
+ if (win_size_[0] == -1 || win_size_[1] == -1)
+ win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize());
+
+
+ // Get the status of special keys (Cltr+Alt+Shift)
+ bool shift = Interactor->GetShiftKey();
+ bool ctrl = Interactor->GetControlKey();
+ bool alt = Interactor->GetAltKey();
+
+ bool keymod = false;
+ switch (modifier_)
+ {
+ case KB_MOD_ALT: keymod = alt; break;
+ case KB_MOD_CTRL: keymod = ctrl; break;
+ case KB_MOD_SHIFT: keymod = shift; break;
+ }
+
+ std::string key(Interactor->GetKeySym());
+ if (key.find("XF86ZoomIn") != std::string::npos)
+ zoomIn();
+ else if (key.find("XF86ZoomOut") != std::string::npos)
+ zoomOut();
+
+ switch (Interactor->GetKeyCode())
+ {
+ case 'h': case 'H':
+ {
+ std::cout << "| Help:\n"
+ "-------\n"
+ " p, P : switch to a point-based representation\n"
+ " w, W : switch to a wireframe-based representation (where available)\n"
+ " s, S : switch to a surface-based representation (where available)\n"
+ "\n"
+ " j, J : take a .PNG snapshot of the current window view\n"
+ " c, C : display current camera/window parameters\n"
+ " f, F : fly to point mode\n"
+ "\n"
+ " e, E : exit the interactor\n"
+ " q, Q : stop and call VTK's TerminateApp\n"
+ "\n"
+ " +/- : increment/decrement overall point size\n"
+ " +/- [+ ALT] : zoom in/out \n"
+ "\n"
+ " r, R [+ ALT] : reset camera [to viewpoint = {0, 0, 0} -> center_{x, y, z}]\n"
+ "\n"
+ " ALT + s, S : turn stereo mode on/off\n"
+ " ALT + f, F : switch between maximized window mode and original size\n"
+ "\n"
+ << std::endl;
+ break;
+ }
+
+ // Switch representation to points
+ case 'p': case 'P':
+ {
+ vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors();
+ vtkCollectionSimpleIterator ait;
+ for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); )
+ {
+ for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); )
+ {
+ vtkActor* apart = reinterpret_cast <vtkActor*>(path->GetLastNode()->GetViewProp());
+ apart->GetProperty()->SetRepresentationToPoints();
+ }
+ }
+ break;
+ }
+ // Save a PNG snapshot with the current screen
+ case 'j': case 'J':
+ {
+ char cam_fn[80], snapshot_fn[80];
+ unsigned t = static_cast<unsigned>(time(0));
+ sprintf(snapshot_fn, "screenshot-%d.png" , t);
+ saveScreenshot(snapshot_fn);
+
+ sprintf(cam_fn, "screenshot-%d.cam", t);
+ ofstream ofs_cam;
+ ofs_cam.open(cam_fn);
+ vtkSmartPointer<vtkCamera> cam = Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActiveCamera();
+ double clip[2], focal[3], pos[3], view[3];
+ cam->GetClippingRange(clip);
+ cam->GetFocalPoint(focal);
+ cam->GetPosition(pos);
+ cam->GetViewUp(view);
+
+ int *win_pos = Interactor->GetRenderWindow()->GetPosition();
+ int *win_size = Interactor->GetRenderWindow()->GetSize();
+ ofs_cam << clip[0] << "," << clip[1] << "/" << focal[0] << "," << focal[1] << "," << focal[2] << "/" <<
+ pos[0] << "," << pos[1] << "," << pos[2] << "/" << view[0] << "," << view[1] << "," << view[2] << "/" <<
+ cam->GetViewAngle() / 180.0 * CV_PI << "/" << win_size[0] << "," << win_size[1] << "/" << win_pos[0] << "," << win_pos[1]
+ << endl;
+ ofs_cam.close();
+
+ std::cout << "Screenshot (" << snapshot_fn << ") and camera information (" << cam_fn << ") successfully captured." << std::endl;
+ break;
+ }
+ // display current camera settings/parameters
+ case 'c': case 'C':
+ {
+ vtkSmartPointer<vtkCamera> cam = Interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer()->GetActiveCamera();
+
+ Vec2d clip;
+ Vec3d focal, pose, view;
+ cam->GetClippingRange(clip.val);
+ cam->GetFocalPoint(focal.val);
+ cam->GetPosition(pose.val);
+ cam->GetViewUp(view.val);
+ Vec2i win_pos(Interactor->GetRenderWindow()->GetPosition());
+ Vec2i win_size(Interactor->GetRenderWindow()->GetSize());
+
++ cv::print(Mat(clip, false).reshape(1, 1));
++ std::cout << "/";
++ cv::print(Mat(focal, false).reshape(1, 1));
++ std::cout << "/";
++ cv::print(Mat(pose, false).reshape(1, 1));
++ std::cout << "/";
++ cv::print(Mat(view, false).reshape(1, 1));
++ std::cout << "/" << cam->GetViewAngle () / 180.0 * CV_PI;
++ cv::print(Mat(win_size, false).reshape(1, 1));
++ std::cout << "/";
++ cv::print(Mat(win_pos, false).reshape(1, 1));
++ std::cout << std::endl;
+ break;
+ }
+ case '=':
+ {
+ zoomIn();
+ break;
+ }
+ case 43: // KEY_PLUS
+ {
+ if (alt)
+ zoomIn();
+ else
+ {
+ vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors();
+ vtkCollectionSimpleIterator ait;
+ for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); )
+ {
+ for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); )
+ {
+ vtkActor* apart = reinterpret_cast <vtkActor*>(path->GetLastNode()->GetViewProp());
+ float psize = apart->GetProperty()->GetPointSize();
+ if (psize < 63.0f)
+ apart->GetProperty()->SetPointSize(psize + 1.0f);
+ }
+ }
+ }
+ break;
+ }
+ case 45: // KEY_MINUS
+ {
+ if (alt)
+ zoomOut();
+ else
+ {
+ vtkSmartPointer<vtkActorCollection> ac = CurrentRenderer->GetActors();
+ vtkCollectionSimpleIterator ait;
+ for (ac->InitTraversal(ait); vtkActor* actor = ac->GetNextActor(ait); )
+ {
+ for (actor->InitPathTraversal(); vtkAssemblyPath* path = actor->GetNextPath(); )
+ {
+ vtkActor* apart = static_cast<vtkActor*>(path->GetLastNode()->GetViewProp());
+ float psize = apart->GetProperty()->GetPointSize();
+ if (psize > 1.0f)
+ apart->GetProperty()->SetPointSize(psize - 1.0f);
+ }
+ }
+ }
+ break;
+ }
+ // Switch between maximize and original window size
+ case 'f': case 'F':
+ {
+ if (keymod)
+ {
+ Vec2i screen_size(Interactor->GetRenderWindow()->GetScreenSize());
+ Vec2i win_size(Interactor->GetRenderWindow()->GetSize());
+
+ // Is window size = max?
+ if (win_size == max_win_size_)
+ {
+ Interactor->GetRenderWindow()->SetSize(win_size_.val);
+ Interactor->GetRenderWindow()->SetPosition(win_pos_.val);
+ Interactor->GetRenderWindow()->Render();
+ Interactor->Render();
+ }
+ // Set to max
+ else
+ {
+ win_pos_ = Vec2i(Interactor->GetRenderWindow()->GetPosition());
+ win_size_ = win_size;
+
+ Interactor->GetRenderWindow()->SetSize(screen_size.val);
+ Interactor->GetRenderWindow()->Render();
+ Interactor->Render();
+ max_win_size_ = Vec2i(Interactor->GetRenderWindow()->GetSize());
+ }
+ }
+ else
+ {
+ AnimState = VTKIS_ANIM_ON;
+ vtkAssemblyPath *path = NULL;
+ Interactor->GetPicker()->Pick(Interactor->GetEventPosition()[0], Interactor->GetEventPosition()[1], 0.0, CurrentRenderer);
+ vtkAbstractPropPicker *picker;
+ if ((picker = vtkAbstractPropPicker::SafeDownCast(Interactor->GetPicker())))
+ path = picker->GetPath();
+ if (path != NULL)
+ Interactor->FlyTo(CurrentRenderer, picker->GetPickPosition());
+ AnimState = VTKIS_ANIM_OFF;
+ }
+ break;
+ }
+ // 's'/'S' w/out ALT
+ case 's': case 'S':
+ {
+ if (keymod)
+ {
+ int stereo_render = Interactor->GetRenderWindow()->GetStereoRender();
+ if (!stereo_render)
+ {
+ if (stereo_anaglyph_mask_default_)
+ {
+ Interactor->GetRenderWindow()->SetAnaglyphColorMask(4, 3);
+ stereo_anaglyph_mask_default_ = false;
+ }
+ else
+ {
+ Interactor->GetRenderWindow()->SetAnaglyphColorMask(2, 5);
+ stereo_anaglyph_mask_default_ = true;
+ }
+ }
+ Interactor->GetRenderWindow()->SetStereoRender(!stereo_render);
+ Interactor->GetRenderWindow()->Render();
+ Interactor->Render();
+ }
+ else
+ Superclass::OnKeyDown();
+ break;
+ }
+
+ case 'o': case 'O':
+ {
+ vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
+ int flag = cam->GetParallelProjection();
+ cam->SetParallelProjection(!flag);
+
+ CurrentRenderer->SetActiveCamera(cam);
+ CurrentRenderer->Render();
+ break;
+ }
+
+ // Overwrite the camera reset
+ case 'r': case 'R':
+ {
+ if (!keymod)
+ {
+ Superclass::OnKeyDown();
+ break;
+ }
+
+ vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
+
+ static WidgetActorMap::iterator it = widget_actor_map_->begin();
+ // it might be that some actors don't have a valid transformation set -> we skip them to avoid a seg fault.
+ bool found_transformation = false;
+
+ for (size_t idx = 0; idx < widget_actor_map_->size(); ++idx, ++it)
+ {
+ if (it == widget_actor_map_->end())
+ it = widget_actor_map_->begin();
+
+ vtkProp3D * actor = vtkProp3D::SafeDownCast(it->second);
+ if (actor && actor->GetUserMatrix())
+ {
+ found_transformation = true;
+ break;
+ }
+ }
+
+ // if a valid transformation was found, use it otherwise fall back to default view point.
+ if (found_transformation)
+ {
+ vtkProp3D * actor = vtkProp3D::SafeDownCast(it->second);
+ cam->SetPosition(actor->GetUserMatrix()->GetElement(0, 3),
+ actor->GetUserMatrix()->GetElement(1, 3),
+ actor->GetUserMatrix()->GetElement(2, 3));
+
+ cam->SetFocalPoint(actor->GetUserMatrix()->GetElement(0, 3) - actor->GetUserMatrix()->GetElement(0, 2),
+ actor->GetUserMatrix()->GetElement(1, 3) - actor->GetUserMatrix()->GetElement(1, 2),
+ actor->GetUserMatrix()->GetElement(2, 3) - actor->GetUserMatrix()->GetElement(2, 2));
+
+ cam->SetViewUp(actor->GetUserMatrix()->GetElement(0, 1),
+ actor->GetUserMatrix()->GetElement(1, 1),
+ actor->GetUserMatrix()->GetElement(2, 1));
+ }
+ else
+ {
+ cam->SetPosition(0, 0, 0);
+ cam->SetFocalPoint(0, 0, 1);
+ cam->SetViewUp(0, -1, 0);
+ }
+
+ // go to the next actor for the next key-press event.
+ if (it != widget_actor_map_->end())
+ ++it;
+ else
+ it = widget_actor_map_->begin();
+
+ CurrentRenderer->SetActiveCamera(cam);
+ CurrentRenderer->ResetCameraClippingRange();
+ CurrentRenderer->Render();
+ break;
+ }
+
+ case 'q': case 'Q':
+ {
+ Interactor->ExitCallback();
+ return;
+ }
+ default:
+ {
+ Superclass::OnKeyDown();
+ break;
+ }
+ }
+
+ KeyboardEvent event(true, Interactor->GetKeySym(), Interactor->GetKeyCode(), Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
+ // Check if there is a keyboard callback registered
+ if (keyboardCallback_)
+ keyboardCallback_(event, keyboard_callback_cookie_);
+
+ renderer_->Render();
+ Interactor->Render();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::InteractorStyle::OnKeyUp()
+{
+ KeyboardEvent event(false, Interactor->GetKeySym(), Interactor->GetKeyCode(), Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
+ // Check if there is a keyboard callback registered
+ if (keyboardCallback_)
+ keyboardCallback_(event, keyboard_callback_cookie_);
+
+ Superclass::OnKeyUp();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::InteractorStyle::OnMouseMove()
+{
+ Vec2i p(Interactor->GetEventPosition());
+ MouseEvent event(MouseEvent::MouseMove, MouseEvent::NoButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
+ if (mouseCallback_)
+ mouseCallback_(event, mouse_callback_cookie_);
+ Superclass::OnMouseMove();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::InteractorStyle::OnLeftButtonDown()
+{
+ Vec2i p(Interactor->GetEventPosition());
+ MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick;
+ MouseEvent event(type, MouseEvent::LeftButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
+ if (mouseCallback_)
+ mouseCallback_(event, mouse_callback_cookie_);
+ Superclass::OnLeftButtonDown();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::InteractorStyle::OnLeftButtonUp()
+{
+ Vec2i p(Interactor->GetEventPosition());
+ MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::LeftButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
+ if (mouseCallback_)
+ mouseCallback_(event, mouse_callback_cookie_);
+ Superclass::OnLeftButtonUp();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::InteractorStyle::OnMiddleButtonDown()
+{
+ Vec2i p(Interactor->GetEventPosition());
+
+ MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick;
+ MouseEvent event(type, MouseEvent::MiddleButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
+ if (mouseCallback_)
+ mouseCallback_(event, mouse_callback_cookie_);
+ Superclass::OnMiddleButtonDown();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::InteractorStyle::OnMiddleButtonUp()
+{
+ Vec2i p(Interactor->GetEventPosition());
+ MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::MiddleButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
+ if (mouseCallback_)
+ mouseCallback_(event, mouse_callback_cookie_);
+ Superclass::OnMiddleButtonUp();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::InteractorStyle::OnRightButtonDown()
+{
+ Vec2i p(Interactor->GetEventPosition());
+
+ MouseEvent::Type type = (Interactor->GetRepeatCount() == 0) ? MouseEvent::MouseButtonPress : MouseEvent::MouseDblClick;
+ MouseEvent event(type, MouseEvent::RightButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
+ if (mouseCallback_)
+ mouseCallback_(event, mouse_callback_cookie_);
+ Superclass::OnRightButtonDown();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::InteractorStyle::OnRightButtonUp()
+{
+ Vec2i p(Interactor->GetEventPosition());
+ MouseEvent event(MouseEvent::MouseButtonRelease, MouseEvent::RightButton, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
+ if (mouseCallback_)
+ mouseCallback_(event, mouse_callback_cookie_);
+ Superclass::OnRightButtonUp();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::InteractorStyle::OnMouseWheelForward()
+{
+ Vec2i p(Interactor->GetEventPosition());
+ MouseEvent event(MouseEvent::MouseScrollUp, MouseEvent::VScroll, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
+ // If a mouse callback registered, call it!
+ if (mouseCallback_)
+ mouseCallback_(event, mouse_callback_cookie_);
+ if (Interactor->GetRepeatCount() && mouseCallback_)
+ mouseCallback_(event, mouse_callback_cookie_);
+
+ if (Interactor->GetAltKey())
+ {
+ // zoom
+ vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
+ double opening_angle = cam->GetViewAngle();
+ if (opening_angle > 15.0)
+ opening_angle -= 1.0;
+
+ cam->SetViewAngle(opening_angle);
+ cam->Modified();
+ CurrentRenderer->SetActiveCamera(cam);
+ CurrentRenderer->ResetCameraClippingRange();
+ CurrentRenderer->Modified();
+ CurrentRenderer->Render();
+ renderer_->Render();
+ Interactor->Render();
+ }
+ else
+ Superclass::OnMouseWheelForward();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::InteractorStyle::OnMouseWheelBackward()
+{
+ Vec2i p(Interactor->GetEventPosition());
+ MouseEvent event(MouseEvent::MouseScrollDown, MouseEvent::VScroll, p, Interactor->GetAltKey(), Interactor->GetControlKey(), Interactor->GetShiftKey());
+ // If a mouse callback registered, call it!
+ if (mouseCallback_)
+ mouseCallback_(event, mouse_callback_cookie_);
+
+ if (Interactor->GetRepeatCount() && mouseCallback_)
+ mouseCallback_(event, mouse_callback_cookie_);
+
+ if (Interactor->GetAltKey())
+ {
+ // zoom
+ vtkSmartPointer<vtkCamera> cam = CurrentRenderer->GetActiveCamera();
+ double opening_angle = cam->GetViewAngle();
+ if (opening_angle < 170.0)
+ opening_angle += 1.0;
+
+ cam->SetViewAngle(opening_angle);
+ cam->Modified();
+ CurrentRenderer->SetActiveCamera(cam);
+ CurrentRenderer->ResetCameraClippingRange();
+ CurrentRenderer->Modified();
+ CurrentRenderer->Render();
+ renderer_->Render();
+ Interactor->Render();
+ }
+ else
+ Superclass::OnMouseWheelBackward();
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::InteractorStyle::OnTimer()
+{
+ CV_Assert("Interactor style not initialized." && init_);
+ CV_Assert("Renderer has not been set." && renderer_);
+ renderer_->Render();
+ Interactor->Render();
+}
+
+namespace cv
+{
+ namespace viz
+ {
+ //Standard VTK macro for *New()
+ vtkStandardNewMacro(InteractorStyle)
+ }
+}
--- /dev/null
- typedef std::map<std::string, vtkSmartPointer<vtkProp> > WidgetActorMap;
+/*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
+//
+// OpenCV Viz module is complete rewrite of
+// PCL visualization module (www.pointclouds.org)
+//
+//M*/
+
+#ifndef __OPENCV_VIZ_PRECOMP_HPP__
+#define __OPENCV_VIZ_PRECOMP_HPP__
+
+#include <map>
+#include <ctime>
+#include <list>
+#include <vector>
+
+#if defined __GNUC__
+#pragma GCC system_header
+#ifdef __DEPRECATED
+#undef __DEPRECATED
+#define __DEPRECATED_DISABLED__
+#endif
+#endif
+
+#include <vtkAppendPolyData.h>
+#include <vtkAssemblyPath.h>
+#include <vtkCellData.h>
+#include <vtkLineSource.h>
+#include <vtkPropPicker.h>
+#include <vtkSmartPointer.h>
+#include <vtkDataSet.h>
+#include <vtkPolygon.h>
+#include <vtkPointPicker.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkDiskSource.h>
+#include <vtkPlaneSource.h>
+#include <vtkSphereSource.h>
+#include <vtkArrowSource.h>
+#include <vtkOutlineSource.h>
+#include <vtkTransform.h>
+#include <vtkTransformPolyDataFilter.h>
+#include <vtkTubeFilter.h>
+#include <vtkCubeSource.h>
+#include <vtkAxes.h>
+#include <vtkFloatArray.h>
+#include <vtkDoubleArray.h>
+#include <vtkPointData.h>
+#include <vtkPolyData.h>
+#include <vtkPolyDataReader.h>
+#include <vtkPolyDataMapper.h>
+#include <vtkDataSetMapper.h>
+#include <vtkCellArray.h>
+#include <vtkCommand.h>
+#include <vtkPLYReader.h>
+#include <vtkPolyLine.h>
+#include <vtkVectorText.h>
+#include <vtkFollower.h>
+#include <vtkInteractorStyle.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkRendererCollection.h>
+#include <vtkPNGWriter.h>
+#include <vtkWindowToImageFilter.h>
+#include <vtkInteractorStyleTrackballCamera.h>
+#include <vtkProperty.h>
+#include <vtkCamera.h>
+#include <vtkObjectFactory.h>
+#include <vtkPlanes.h>
+#include <vtkImageViewer.h>
+#include <vtkImageFlip.h>
+#include <vtkRenderWindow.h>
+#include <vtkTextProperty.h>
+#include <vtkProperty2D.h>
+#include <vtkLODActor.h>
+#include <vtkTextActor.h>
+#include <vtkRenderWindowInteractor.h>
+#include <vtkMath.h>
+#include <vtkExtractEdges.h>
+#include <vtkFrustumSource.h>
+#include <vtkTextureMapToPlane.h>
+#include <vtkPolyDataNormals.h>
+#include <vtkAlgorithmOutput.h>
+
+#if defined __GNUC__ && defined __DEPRECATED_DISABLED__
+#define __DEPRECATED
+#undef __DEPRECATED_DISABLED__
+#endif
+
++#include <opencv2/ts.hpp>
++#include <opencv2/core.hpp>
++
+namespace cv
+{
+ namespace viz
+ {
- typedef std::map<std::string, Viz3d> VizMap;
- typedef std::pair<std::string, Viz3d> VizPair;
++ typedef std::map<String, vtkSmartPointer<vtkProp> > WidgetActorMap;
+ }
+}
+
+#include "viz3d_impl.hpp"
+
+namespace cv
+{
+ namespace viz
+ {
- #include <opencv2/core.hpp>
++ typedef std::map<String, Viz3d> VizMap;
++ typedef std::pair<String, Viz3d> VizPair;
+ }
+}
+
+#include <opencv2/viz.hpp>
+#include <opencv2/viz/types.hpp>
+#include "opencv2/viz/widget_accessor.hpp"
+
+#endif
--- /dev/null
- cv::viz::KeyboardEvent::KeyboardEvent(bool _action, const std::string& _key_sym, unsigned char key, bool alt, bool ctrl, bool shift)
+/*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
+//
+// OpenCV Viz module is complete rewrite of
+// PCL visualization module (www.pointclouds.org)
+//
+//M*/
+
+#include "precomp.hpp"
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////
+/// cv::viz::Color
+
+cv::viz::Color::Color() : Scalar(0, 0, 0) {}
+cv::viz::Color::Color(double gray) : Scalar(gray, gray, gray) {}
+cv::viz::Color::Color(double blue, double green, double red) : Scalar(blue, green, red) {}
+cv::viz::Color::Color(const Scalar& color) : Scalar(color) {}
+
+cv::viz::Color cv::viz::Color::black() { return Color( 0, 0, 0); }
+cv::viz::Color cv::viz::Color::green() { return Color( 0, 255, 0); }
+cv::viz::Color cv::viz::Color::blue() { return Color(255, 0, 0); }
+cv::viz::Color cv::viz::Color::cyan() { return Color(255, 255, 0); }
+
+cv::viz::Color cv::viz::Color::red() { return Color( 0, 0, 255); }
+cv::viz::Color cv::viz::Color::yellow() { return Color( 0, 255, 255); }
+cv::viz::Color cv::viz::Color::magenta() { return Color(255, 0, 255); }
+cv::viz::Color cv::viz::Color::white() { return Color(255, 255, 255); }
+
+cv::viz::Color cv::viz::Color::gray() { return Color(128, 128, 128); }
+
+////////////////////////////////////////////////////////////////////
+/// cv::viz::KeyboardEvent
+
- if (fabs(left-right) < std::numeric_limits<double>::epsilon()) principal_point_[0] = static_cast<float>(window_size.width) * 0.5f;
++cv::viz::KeyboardEvent::KeyboardEvent(bool _action, const String& _key_sym, unsigned char key, bool alt, bool ctrl, bool shift)
+ : action_(_action), modifiers_(0), key_code_(key), key_sym_(_key_sym)
+{
+ if (alt)
+ modifiers_ = Alt;
+
+ if (ctrl)
+ modifiers_ |= Ctrl;
+
+ if (shift)
+ modifiers_ |= Shift;
+}
+
+bool cv::viz::KeyboardEvent::isAltPressed() const { return (modifiers_ & Alt) != 0; }
+bool cv::viz::KeyboardEvent::isCtrlPressed() const { return (modifiers_ & Ctrl) != 0; }
+bool cv::viz::KeyboardEvent::isShiftPressed() const { return (modifiers_ & Shift) != 0; }
+unsigned char cv::viz::KeyboardEvent::getKeyCode() const { return key_code_; }
+const cv::String& cv::viz::KeyboardEvent::getKeySym() const { return key_sym_; }
+bool cv::viz::KeyboardEvent::keyDown() const { return action_; }
+bool cv::viz::KeyboardEvent::keyUp() const { return !action_; }
+
+////////////////////////////////////////////////////////////////////
+/// cv::viz::MouseEvent
+
+cv::viz::MouseEvent::MouseEvent(const Type& _type, const MouseButton& _button, const Point& _p, bool alt, bool ctrl, bool shift)
+ : type(_type), button(_button), pointer(_p), key_state(0)
+{
+ if (alt)
+ key_state = KeyboardEvent::Alt;
+
+ if (ctrl)
+ key_state |= KeyboardEvent::Ctrl;
+
+ if (shift)
+ key_state |= KeyboardEvent::Shift;
+}
+
+////////////////////////////////////////////////////////////////////
+/// cv::viz::Mesh3d
+
+struct cv::viz::Mesh3d::loadMeshImpl
+{
+ static cv::viz::Mesh3d loadMesh(const String &file)
+ {
+ Mesh3d mesh;
+
+ vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New();
+ reader->SetFileName(file.c_str());
+ reader->Update();
+
+ vtkSmartPointer<vtkPolyData> poly_data = reader->GetOutput();
+ CV_Assert("File does not exist or file format is not supported." && poly_data);
+
+ vtkSmartPointer<vtkPoints> mesh_points = poly_data->GetPoints();
+ vtkIdType nr_points = mesh_points->GetNumberOfPoints();
+
+ mesh.cloud.create(1, nr_points, CV_32FC3);
+
+ Vec3f *mesh_cloud = mesh.cloud.ptr<Vec3f>();
+ for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints(); i++)
+ {
+ Vec3d point;
+ mesh_points->GetPoint(i, point.val);
+ mesh_cloud[i] = point;
+ }
+
+ // Then the color information, if any
+ vtkUnsignedCharArray* poly_colors = 0;
+ if (poly_data->GetPointData())
+ poly_colors = vtkUnsignedCharArray::SafeDownCast(poly_data->GetPointData()->GetScalars());
+
+ if (poly_colors && (poly_colors->GetNumberOfComponents() == 3))
+ {
+ mesh.colors.create(1, nr_points, CV_8UC3);
+ Vec3b *mesh_colors = mesh.colors.ptr<cv::Vec3b>();
+
+ for (vtkIdType i = 0; i < mesh_points->GetNumberOfPoints(); i++)
+ {
+ Vec3b point_color;
+ poly_colors->GetTupleValue(i, point_color.val);
+
+ std::swap(point_color[0], point_color[2]); // RGB -> BGR
+ mesh_colors[i] = point_color;
+ }
+ }
+ else
+ mesh.colors.release();
+
+ // Now handle the polygons
+ vtkIdType* cell_points;
+ vtkIdType nr_cell_points;
+ vtkCellArray * mesh_polygons = poly_data->GetPolys();
+ mesh_polygons->InitTraversal();
+
+ mesh.polygons.create(1, mesh_polygons->GetSize(), CV_32SC1);
+
+ int* polygons = mesh.polygons.ptr<int>();
+ while (mesh_polygons->GetNextCell(nr_cell_points, cell_points))
+ {
+ *polygons++ = nr_cell_points;
+ for (int i = 0; i < nr_cell_points; ++i)
+ *polygons++ = static_cast<int>(cell_points[i]);
+ }
+
+ return mesh;
+ }
+};
+
+cv::viz::Mesh3d cv::viz::Mesh3d::loadMesh(const String& file)
+{
+ return loadMeshImpl::loadMesh(file);
+}
+
+////////////////////////////////////////////////////////////////////
+/// Camera implementation
+
+cv::viz::Camera::Camera(float f_x, float f_y, float c_x, float c_y, const Size &window_size)
+{
+ init(f_x, f_y, c_x, c_y, window_size);
+}
+
+cv::viz::Camera::Camera(const Vec2f &fov, const Size &window_size)
+{
+ CV_Assert(window_size.width > 0 && window_size.height > 0);
+ setClip(Vec2d(0.01, 1000.01)); // Default clipping
+ setFov(fov);
+ window_size_ = window_size;
+ // Principal point at the center
+ principal_point_ = Vec2f(static_cast<float>(window_size.width)*0.5f, static_cast<float>(window_size.height)*0.5f);
+ focal_ = Vec2f(principal_point_[0] / tan(fov_[0]*0.5f), principal_point_[1] / tan(fov_[1]*0.5f));
+}
+
+cv::viz::Camera::Camera(const cv::Matx33f & K, const Size &window_size)
+{
+ float f_x = K(0,0);
+ float f_y = K(1,1);
+ float c_x = K(0,2);
+ float c_y = K(1,2);
+ init(f_x, f_y, c_x, c_y, window_size);
+}
+
+cv::viz::Camera::Camera(const Matx44f &proj, const Size &window_size)
+{
+ CV_Assert(window_size.width > 0 && window_size.height > 0);
+
+ double near = proj(2,3) / (proj(2,2) - 1.0);
+ double far = near * (proj(2,2) - 1.0) / (proj(2,2) + 1.0);
+ double left = near * (proj(0,2)-1) / proj(0,0);
+ double right = 2.0 * near / proj(0,0) + left;
+ double bottom = near * (proj(1,2)-1) / proj(1,1);
+ double top = 2.0 * near / proj(1,1) + bottom;
+
- if (fabs(top-bottom) < std::numeric_limits<double>::epsilon()) principal_point_[1] = static_cast<float>(window_size.height) * 0.5f;
++ double epsilon = 2.2204460492503131e-16;
++
++ if (fabs(left-right) < epsilon) principal_point_[0] = static_cast<float>(window_size.width) * 0.5f;
+ else principal_point_[0] = (left * static_cast<float>(window_size.width)) / (left - right);
+ focal_[0] = -near * principal_point_[0] / left;
+
++ if (fabs(top-bottom) < epsilon) principal_point_[1] = static_cast<float>(window_size.height) * 0.5f;
+ else principal_point_[1] = (top * static_cast<float>(window_size.height)) / (top - bottom);
+ focal_[1] = near * principal_point_[1] / top;
+
+ setClip(Vec2d(near, far));
+ fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0]));
+ fov_[1] = (atan2(principal_point_[1],focal_[1]) + atan2(window_size.height-principal_point_[1],focal_[1]));
+
+ window_size_ = window_size;
+}
+
+void cv::viz::Camera::init(float f_x, float f_y, float c_x, float c_y, const Size &window_size)
+{
+ CV_Assert(window_size.width > 0 && window_size.height > 0);
+ setClip(Vec2d(0.01, 1000.01));// Default clipping
+
+ fov_[0] = (atan2(c_x,f_x) + atan2(window_size.width-c_x,f_x));
+ fov_[1] = (atan2(c_y,f_y) + atan2(window_size.height-c_y,f_y));
+
+ principal_point_[0] = c_x;
+ principal_point_[1] = c_y;
+
+ focal_[0] = f_x;
+ focal_[1] = f_y;
+
+ window_size_ = window_size;
+}
+
+void cv::viz::Camera::setWindowSize(const Size &window_size)
+{
+ CV_Assert(window_size.width > 0 && window_size.height > 0);
+
+ // Get the scale factor and update the principal points
+ float scalex = static_cast<float>(window_size.width) / static_cast<float>(window_size_.width);
+ float scaley = static_cast<float>(window_size.height) / static_cast<float>(window_size_.height);
+
+ principal_point_[0] *= scalex;
+ principal_point_[1] *= scaley;
+ focal_ *= scaley;
+ // Vertical field of view is fixed! Update horizontal field of view
+ fov_[0] = (atan2(principal_point_[0],focal_[0]) + atan2(window_size.width-principal_point_[0],focal_[0]));
+
+ window_size_ = window_size;
+}
+
+void cv::viz::Camera::computeProjectionMatrix(Matx44f &proj) const
+{
+ double top = clip_[0] * principal_point_[1] / focal_[1];
+ double left = -clip_[0] * principal_point_[0] / focal_[0];
+ double right = clip_[0] * (window_size_.width - principal_point_[0]) / focal_[0];
+ double bottom = -clip_[0] * (window_size_.height - principal_point_[1]) / focal_[1];
+
+ double temp1 = 2.0 * clip_[0];
+ double temp2 = 1.0 / (right - left);
+ double temp3 = 1.0 / (top - bottom);
+ double temp4 = 1.0 / (clip_[0] - clip_[1]);
+
+ proj = Matx44d::zeros();
+ proj(0,0) = temp1 * temp2;
+ proj(1,1) = temp1 * temp3;
+ proj(0,2) = (right + left) * temp2;
+ proj(1,2) = (top + bottom) * temp3;
+ proj(2,2) = (clip_[1]+clip_[0]) * temp4;
+ proj(3,2) = -1.0;
+ proj(2,3) = (temp1 * clip_[1]) * temp4;
+}
+
+cv::viz::Camera cv::viz::Camera::KinectCamera(const Size &window_size)
+{
+ // Without distortion, RGB Camera
+ // Received from http://nicolas.burrus.name/index.php/Research/KinectCalibration
+ Matx33f K = Matx33f::zeros();
+ K(0,0) = 5.2921508098293293e+02;
+ K(0,2) = 3.2894272028759258e+02;
+ K(1,1) = 5.2556393630057437e+02;
+ K(1,2) = 2.6748068171871557e+02;
+ K(2,2) = 1.0f;
+ return Camera(K, window_size);
+}
--- /dev/null
- cv::viz::Viz3d::VizImpl::VizImpl(const std::string &name)
+/*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
+//
+// OpenCV Viz module is complete rewrite of
+// PCL visualization module (www.pointclouds.org)
+//
+//M*/
+
+#include "precomp.hpp"
+#include "viz3d_impl.hpp"
+
+#include <vtkRenderWindowInteractor.h>
+
+#if 1 || !defined __APPLE__
+vtkRenderWindowInteractor* vtkRenderWindowInteractorFixNew()
+{
+ return vtkRenderWindowInteractor::New();
+}
+#endif
+
+/////////////////////////////////////////////////////////////////////////////////////////////
- void cv::viz::Viz3d::VizImpl::saveScreenshot(const std::string &file) { style_->saveScreenshot(file); }
++cv::viz::Viz3d::VizImpl::VizImpl(const String &name)
+ : style_(vtkSmartPointer<cv::viz::InteractorStyle>::New())
+ , widget_actor_map_(new WidgetActorMap)
+ , s_lastDone_(0.0)
+{
+ renderer_ = vtkSmartPointer<vtkRenderer>::New();
+
+ // Create a RendererWindow
+ window_ = vtkSmartPointer<vtkRenderWindow>::New();
+
+ // Set the window size as 1/2 of the screen size
+ cv::Vec2i window_size = cv::Vec2i(window_->GetScreenSize()) / 2;
+ window_->SetSize(window_size.val);
+
+ window_->AddRenderer(renderer_);
+
+ // Create the interactor style
+ style_->Initialize();
+ style_->setRenderer(renderer_);
+ style_->setWidgetActorMap(widget_actor_map_);
+ style_->UseTimersOn();
+
+ /////////////////////////////////////////////////
+ interactor_ = vtkSmartPointer <vtkRenderWindowInteractor>::Take(vtkRenderWindowInteractorFixNew());
+
+ window_->AlphaBitPlanesOff();
+ window_->PointSmoothingOff();
+ window_->LineSmoothingOff();
+ window_->PolygonSmoothingOff();
+ window_->SwapBuffersOn();
+ window_->SetStereoTypeToAnaglyph();
+
+ interactor_->SetRenderWindow(window_);
+ interactor_->SetInteractorStyle(style_);
+ interactor_->SetDesiredUpdateRate(30.0);
+
+ // Initialize and create timer, also create window
+ interactor_->Initialize();
+ timer_id_ = interactor_->CreateRepeatingTimer(5000L);
+
+ // Set a simple PointPicker
+ vtkSmartPointer<vtkPointPicker> pp = vtkSmartPointer<vtkPointPicker>::New();
+ pp->SetTolerance(pp->GetTolerance() * 2);
+ interactor_->SetPicker(pp);
+
+ exit_main_loop_timer_callback_ = vtkSmartPointer<ExitMainLoopTimerCallback>::New();
+ exit_main_loop_timer_callback_->viz_ = this;
+ exit_main_loop_timer_callback_->right_timer_id = -1;
+ interactor_->AddObserver(vtkCommand::TimerEvent, exit_main_loop_timer_callback_);
+
+ exit_callback_ = vtkSmartPointer<ExitCallback>::New();
+ exit_callback_->viz_ = this;
+ interactor_->AddObserver(vtkCommand::ExitEvent, exit_callback_);
+
+ resetStoppedFlag();
+
+
+ //////////////////////////////
+ String window_name;
+ VizAccessor::generateWindowName(name, window_name);
+ window_->SetWindowName(window_name.c_str());
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+cv::viz::Viz3d::VizImpl::~VizImpl()
+{
+ if (interactor_)
+ interactor_->DestroyTimer(timer_id_);
+ if (renderer_) renderer_->Clear();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::showWidget(const String &id, const Widget &widget, const Affine3f &pose)
+{
+ WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id);
+ bool exists = wam_itr != widget_actor_map_->end();
+ if (exists)
+ {
+ // Remove it if it exists and add it again
+ removeActorFromRenderer(wam_itr->second);
+ }
+ // Get the actor and set the user matrix
+ vtkProp3D *actor = vtkProp3D::SafeDownCast(WidgetAccessor::getProp(widget));
+ if (actor)
+ {
+ // If the actor is 3D, apply pose
+ vtkSmartPointer<vtkMatrix4x4> matrix = convertToVtkMatrix(pose.matrix);
+ actor->SetUserMatrix(matrix);
+ actor->Modified();
+ }
+ // If the actor is a vtkFollower, then it should always face the camera
+ vtkFollower *follower = vtkFollower::SafeDownCast(actor);
+ if (follower)
+ {
+ follower->SetCamera(renderer_->GetActiveCamera());
+ }
+
+ renderer_->AddActor(WidgetAccessor::getProp(widget));
+ (*widget_actor_map_)[id] = WidgetAccessor::getProp(widget);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::removeWidget(const String &id)
+{
+ WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id);
+ bool exists = wam_itr != widget_actor_map_->end();
+ CV_Assert("Widget does not exist." && exists);
+ CV_Assert("Widget could not be removed." && removeActorFromRenderer(wam_itr->second));
+ widget_actor_map_->erase(wam_itr);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+cv::viz::Widget cv::viz::Viz3d::VizImpl::getWidget(const String &id) const
+{
+ WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id);
+ bool exists = wam_itr != widget_actor_map_->end();
+ CV_Assert("Widget does not exist." && exists);
+
+ Widget widget;
+ WidgetAccessor::setProp(widget, wam_itr->second);
+ return widget;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::setWidgetPose(const String &id, const Affine3f &pose)
+{
+ WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id);
+ bool exists = wam_itr != widget_actor_map_->end();
+ CV_Assert("Widget does not exist." && exists);
+
+ vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second);
+ CV_Assert("Widget is not 3D." && actor);
+
+ vtkSmartPointer<vtkMatrix4x4> matrix = convertToVtkMatrix(pose.matrix);
+ actor->SetUserMatrix(matrix);
+ actor->Modified();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::updateWidgetPose(const String &id, const Affine3f &pose)
+{
+ WidgetActorMap::iterator wam_itr = widget_actor_map_->find(id);
+ bool exists = wam_itr != widget_actor_map_->end();
+ CV_Assert("Widget does not exist." && exists);
+
+ vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second);
+ CV_Assert("Widget is not 3D." && actor);
+
+ vtkSmartPointer<vtkMatrix4x4> matrix = actor->GetUserMatrix();
+ if (!matrix)
+ {
+ setWidgetPose(id, pose);
+ return ;
+ }
+ Matx44f matrix_cv = convertToMatx(matrix);
+ Affine3f updated_pose = pose * Affine3f(matrix_cv);
+ matrix = convertToVtkMatrix(updated_pose.matrix);
+
+ actor->SetUserMatrix(matrix);
+ actor->Modified();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+cv::Affine3f cv::viz::Viz3d::VizImpl::getWidgetPose(const String &id) const
+{
+ WidgetActorMap::const_iterator wam_itr = widget_actor_map_->find(id);
+ bool exists = wam_itr != widget_actor_map_->end();
+ CV_Assert("Widget does not exist." && exists);
+
+ vtkProp3D *actor = vtkProp3D::SafeDownCast(wam_itr->second);
+ CV_Assert("Widget is not 3D." && actor);
+
+ vtkSmartPointer<vtkMatrix4x4> matrix = actor->GetUserMatrix();
+ Matx44f matrix_cv = convertToMatx(matrix);
+ return Affine3f(matrix_cv);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::setDesiredUpdateRate(double rate)
+{
+ if (interactor_)
+ interactor_->SetDesiredUpdateRate(rate);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+double cv::viz::Viz3d::VizImpl::getDesiredUpdateRate()
+{
+ if (interactor_)
+ return interactor_->GetDesiredUpdateRate();
+ return 0.0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
++void cv::viz::Viz3d::VizImpl::saveScreenshot(const String &file) { style_->saveScreenshot(file.c_str()); }
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::registerMouseCallback(MouseCallback callback, void* cookie)
+{ style_->registerMouseCallback(callback, cookie); }
+
+void cv::viz::Viz3d::VizImpl::registerKeyboardCallback(KeyboardCallback callback, void* cookie)
+{ style_->registerKeyboardCallback(callback, cookie); }
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::spin()
+{
+ resetStoppedFlag();
+ window_->Render();
+ interactor_->Start();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::spinOnce(int time, bool force_redraw)
+{
+ resetStoppedFlag();
+
+ if (time <= 0)
+ time = 1;
+
+ if (force_redraw)
+ interactor_->Render();
+
+ double s_now_ = cv::getTickCount() / cv::getTickFrequency();
+ if (s_lastDone_ > s_now_)
+ s_lastDone_ = s_now_;
+
+ if ((s_now_ - s_lastDone_) > (1.0 / interactor_->GetDesiredUpdateRate()))
+ {
+ exit_main_loop_timer_callback_->right_timer_id = interactor_->CreateRepeatingTimer(time);
+ interactor_->Start();
+ interactor_->DestroyTimer(exit_main_loop_timer_callback_->right_timer_id);
+ s_lastDone_ = s_now_;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::removeAllWidgets()
+{
+ widget_actor_map_->clear();
+ renderer_->RemoveAllViewProps();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+bool cv::viz::Viz3d::VizImpl::removeActorFromRenderer(const vtkSmartPointer<vtkProp> &actor)
+{
+ vtkProp* actor_to_remove = vtkProp::SafeDownCast(actor);
+
+ vtkPropCollection* actors = renderer_->GetViewProps();
+ actors->InitTraversal();
+ vtkProp* current_actor = NULL;
+ while ((current_actor = actors->GetNextProp()) != NULL)
+ {
+ if (current_actor != actor_to_remove)
+ continue;
+ renderer_->RemoveActor(actor);
+ return true;
+ }
+ return false;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::createActorFromVTKDataSet(const vtkSmartPointer<vtkDataSet> &data, vtkSmartPointer<vtkLODActor> &actor, bool use_scalars)
+{
+ if (!actor)
+ actor = vtkSmartPointer<vtkLODActor>::New();
+
+ vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
+#if VTK_MAJOR_VERSION <= 5
+ mapper->SetInput(data);
+#else
+ mapper->SetInputData(data);
+#endif
+
+ if (use_scalars)
+ {
+ vtkSmartPointer<vtkDataArray> scalars = data->GetPointData()->GetScalars();
+ if (scalars)
+ {
+ cv::Vec3d minmax(scalars->GetRange());
+ mapper->SetScalarRange(minmax.val);
+ mapper->SetScalarModeToUsePointData();
+
+ // interpolation OFF, if data is a vtkPolyData that contains only vertices, ON for anything else.
+ vtkPolyData* polyData = vtkPolyData::SafeDownCast(data);
+ bool interpolation = (polyData && polyData->GetNumberOfCells() != polyData->GetNumberOfVerts());
+
+ mapper->SetInterpolateScalarsBeforeMapping(interpolation);
+ mapper->ScalarVisibilityOn();
+ }
+ }
+ mapper->ImmediateModeRenderingOff();
+
+ actor->SetNumberOfCloudPoints(int(std::max<vtkIdType>(1, data->GetNumberOfPoints() / 10)));
+ actor->GetProperty()->SetInterpolationToFlat();
+ actor->GetProperty()->BackfaceCullingOn();
+
+ actor->SetMapper(mapper);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::setBackgroundColor(const Color& color)
+{
+ Color c = vtkcolor(color);
+ renderer_->SetBackground(c.val);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::setCamera(const Camera &camera)
+{
+ vtkCamera& active_camera = *renderer_->GetActiveCamera();
+
+ // Set the intrinsic parameters of the camera
+ window_->SetSize(camera.getWindowSize().width, camera.getWindowSize().height);
+ double aspect_ratio = static_cast<double>(camera.getWindowSize().width)/static_cast<double>(camera.getWindowSize().height);
+
+ Matx44f proj_mat;
+ camera.computeProjectionMatrix(proj_mat);
+ // Use the intrinsic parameters of the camera to simulate more realistically
+ Matx44f old_proj_mat = convertToMatx(active_camera.GetProjectionTransformMatrix(aspect_ratio, -1.0, 1.0));
+ vtkTransform *transform = vtkTransform::New();
+ // This is a hack around not being able to set Projection Matrix
+ transform->SetMatrix(convertToVtkMatrix(proj_mat * old_proj_mat.inv()));
+ active_camera.SetUserTransform(transform);
+ transform->Delete();
+
+ renderer_->ResetCameraClippingRange();
+ renderer_->Render();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+cv::viz::Camera cv::viz::Viz3d::VizImpl::getCamera() const
+{
+ vtkCamera& active_camera = *renderer_->GetActiveCamera();
+
+ Size window_size(renderer_->GetRenderWindow()->GetSize()[0],
+ renderer_->GetRenderWindow()->GetSize()[1]);
+ double aspect_ratio = static_cast<double>(window_size.width) / static_cast<double>(window_size.height);
+
+ Matx44f proj_matrix = convertToMatx(active_camera.GetProjectionTransformMatrix(aspect_ratio, -1.0f, 1.0f));
+ Camera camera(proj_matrix, window_size);
+ return camera;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::setViewerPose(const Affine3f &pose)
+{
+ vtkCamera& camera = *renderer_->GetActiveCamera();
+
+ // Position = extrinsic translation
+ cv::Vec3f pos_vec = pose.translation();
+
+ // Rotate the view vector
+ cv::Matx33f rotation = pose.rotation();
+ cv::Vec3f y_axis(0.f, 1.f, 0.f);
+ cv::Vec3f up_vec(rotation * y_axis);
+
+ // Compute the new focal point
+ cv::Vec3f z_axis(0.f, 0.f, 1.f);
+ cv::Vec3f focal_vec = pos_vec + rotation * z_axis;
+
+ camera.SetPosition(pos_vec[0], pos_vec[1], pos_vec[2]);
+ camera.SetFocalPoint(focal_vec[0], focal_vec[1], focal_vec[2]);
+ camera.SetViewUp(up_vec[0], up_vec[1], up_vec[2]);
+
+ renderer_->ResetCameraClippingRange();
+ renderer_->Render();
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+cv::Affine3f cv::viz::Viz3d::VizImpl::getViewerPose()
+{
+ vtkCamera& camera = *renderer_->GetActiveCamera();
+
+ Vec3d pos(camera.GetPosition());
+ Vec3d view_up(camera.GetViewUp());
+ Vec3d focal(camera.GetFocalPoint());
+
+ Vec3d y_axis = normalized(view_up);
+ Vec3d z_axis = normalized(focal - pos);
+ Vec3d x_axis = normalized(y_axis.cross(z_axis));
+
+ cv::Matx33d R;
+ R(0, 0) = x_axis[0];
+ R(0, 1) = y_axis[0];
+ R(0, 2) = z_axis[0];
+
+ R(1, 0) = x_axis[1];
+ R(1, 1) = y_axis[1];
+ R(1, 2) = z_axis[1];
+
+ R(2, 0) = x_axis[2];
+ R(2, 1) = y_axis[2];
+ R(2, 2) = z_axis[2];
+
+ return cv::Affine3f(R, pos);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::convertToWindowCoordinates(const Point3d &pt, Point3d &window_coord)
+{
+ Vec3d window_pt;
+ vtkInteractorObserver::ComputeWorldToDisplay(renderer_, pt.x, pt.y, pt.z, window_pt.val);
+ window_coord = window_pt;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction)
+{
+ Vec4d world_pt;
+ vtkInteractorObserver::ComputeDisplayToWorld(renderer_, window_coord.x, window_coord.y, window_coord.z, world_pt.val);
+
+ vtkCamera &active_camera = *renderer_->GetActiveCamera();
+ Vec3d cam_pos;
+ active_camera.GetPosition(cam_pos.val);
+ origin = cam_pos;
+ direction = normalize(Vec3d(world_pt.val) - cam_pos);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::resetCameraViewpoint(const String &id)
+{
+ vtkSmartPointer<vtkMatrix4x4> camera_pose;
+ static WidgetActorMap::iterator it = widget_actor_map_->find(id);
+ if (it != widget_actor_map_->end())
+ {
+ vtkProp3D *actor = vtkProp3D::SafeDownCast(it->second);
+ CV_Assert("Widget is not 3D." && actor);
+ camera_pose = actor->GetUserMatrix();
+ }
+ else
+ return;
+
+ // Prevent a segfault
+ if (!camera_pose) return;
+
+ vtkSmartPointer<vtkCamera> cam = renderer_->GetActiveCamera();
+ cam->SetPosition(camera_pose->GetElement(0, 3),
+ camera_pose->GetElement(1, 3),
+ camera_pose->GetElement(2, 3));
+
+ cam->SetFocalPoint(camera_pose->GetElement(0, 3) - camera_pose->GetElement(0, 2),
+ camera_pose->GetElement(1, 3) - camera_pose->GetElement(1, 2),
+ camera_pose->GetElement(2, 3) - camera_pose->GetElement(2, 2));
+
+ cam->SetViewUp(camera_pose->GetElement(0, 1),
+ camera_pose->GetElement(1, 1),
+ camera_pose->GetElement(2, 1));
+
+ renderer_->SetActiveCamera(cam);
+ renderer_->ResetCameraClippingRange();
+ renderer_->Render();
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::resetCamera()
+{
+ renderer_->ResetCamera();
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::setRepresentation(int representation)
+{
+ vtkActorCollection * actors = renderer_->GetActors();
+ actors->InitTraversal();
+ vtkActor * actor;
+ switch (representation)
+ {
+ case REPRESENTATION_POINTS:
+ {
+ while ((actor = actors->GetNextActor()) != NULL)
+ actor->GetProperty()->SetRepresentationToPoints();
+ break;
+ }
+ case REPRESENTATION_SURFACE:
+ {
+ while ((actor = actors->GetNextActor()) != NULL)
+ actor->GetProperty()->SetRepresentationToSurface();
+ break;
+ }
+ case REPRESENTATION_WIREFRAME:
+ {
+ while ((actor = actors->GetNextActor()) != NULL)
+ actor->GetProperty()->SetRepresentationToWireframe();
+ break;
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::updateCells(vtkSmartPointer<vtkIdTypeArray> &cells, vtkSmartPointer<vtkIdTypeArray> &initcells, vtkIdType nr_points)
+{
+ // If no init cells and cells has not been initialized...
+ if (!cells)
+ cells = vtkSmartPointer<vtkIdTypeArray>::New();
+
+ // If we have less values then we need to recreate the array
+ if (cells->GetNumberOfTuples() < nr_points)
+ {
+ cells = vtkSmartPointer<vtkIdTypeArray>::New();
+
+ // If init cells is given, and there's enough data in it, use it
+ if (initcells && initcells->GetNumberOfTuples() >= nr_points)
+ {
+ cells->DeepCopy(initcells);
+ cells->SetNumberOfComponents(2);
+ cells->SetNumberOfTuples(nr_points);
+ }
+ else
+ {
+ // If the number of tuples is still too small, we need to recreate the array
+ cells->SetNumberOfComponents(2);
+ cells->SetNumberOfTuples(nr_points);
+ vtkIdType *cell = cells->GetPointer(0);
+ // Fill it with 1s
+ std::fill_n(cell, nr_points * 2, 1);
+ cell++;
+ for (vtkIdType i = 0; i < nr_points; ++i, cell += 2)
+ *cell = i;
+ // Save the results in initcells
+ initcells = vtkSmartPointer<vtkIdTypeArray>::New();
+ initcells->DeepCopy(cells);
+ }
+ }
+ else
+ {
+ // The assumption here is that the current set of cells has more data than needed
+ cells->SetNumberOfComponents(2);
+ cells->SetNumberOfTuples(nr_points);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::setFullScreen(bool mode)
+{
+ if (window_)
+ window_->SetFullScreen(mode);
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+cv::String cv::viz::Viz3d::VizImpl::getWindowName() const
+{
+ return (window_ ? window_->GetWindowName() : "");
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+void cv::viz::Viz3d::VizImpl::setWindowPosition(int x, int y) { window_->SetPosition(x, y); }
+void cv::viz::Viz3d::VizImpl::setWindowSize(int xw, int yw) { window_->SetSize(xw, yw); }
+cv::Size cv::viz::Viz3d::VizImpl::getWindowSize() const { return Size(window_->GetSize()[0], window_->GetSize()[1]); }