diff --git a/modules/viz/include/opencv2/viz.hpp b/modules/viz/include/opencv2/viz.hpp index c7976a999..f3745767a 100644 --- a/modules/viz/include/opencv2/viz.hpp +++ b/modules/viz/include/opencv2/viz.hpp @@ -58,13 +58,17 @@ namespace cv { namespace viz - { + { + typedef std::map VizMap; + typedef std::pair VizPair; + //! takes coordiante frame data and builds transfrom to global coordinate frame CV_EXPORTS Affine3f makeTransformToGlobal(const Vec3f& axis_x, const Vec3f& axis_y, const Vec3f& axis_z, const Vec3f& origin = Vec3f::all(0)); //! constructs camera pose from position, focal_point and up_vector (see gluLookAt() for more infromation CV_EXPORTS Affine3f makeCameraPose(const Vec3f& position, const Vec3f& focal_point, const Vec3f& y_dir); + CV_EXPORTS Viz3d get(const String &window_name); //! checks float value for Nan inline bool isNan(float x) @@ -87,6 +91,24 @@ namespace cv //! checks point for Nans template inline bool isNan(const Point3_<_Tp>& p) { return isNan(p.x) || isNan(p.y) || isNan(p.z); } + + class CV_EXPORTS VizAccessor + { + public: + ~VizAccessor(); + static VizAccessor * getInstance(); + + Viz3d get(const String &window_name); + void add(Viz3d window); + void remove(const String &window_name); + + private: + VizAccessor(); // Singleton + + static VizAccessor * instance_; + static bool is_instantiated_; + static VizMap viz_map_; + }; } } diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 33b274325..f4adcd835 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -21,6 +21,8 @@ namespace cv typedef void (*MouseCallback)(const MouseEvent&, void*); Viz3d(const String& window_name = String()); + Viz3d(const Viz3d&); + Viz3d& operator=(const Viz3d&); ~Viz3d(); void setBackgroundColor(const Color& color = Color::black()); @@ -50,6 +52,8 @@ namespace cv Size getWindowSize() const; void setWindowSize(const Size &window_size); + + String getWindowName() const; void spin(); void spinOnce(int time = 1, bool force_redraw = false); @@ -58,11 +62,12 @@ namespace cv void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0); void registerMouseCallback(MouseCallback callback, void* cookie = 0); private: - Viz3d(const Viz3d&); - Viz3d& operator=(const Viz3d&); struct VizImpl; VizImpl* impl_; + + void create(const String &window_name); + void release(); }; } /* namespace viz */ diff --git a/modules/viz/src/viz.cpp b/modules/viz/src/viz.cpp index 2d563f6c1..a1e56134f 100644 --- a/modules/viz/src/viz.cpp +++ b/modules/viz/src/viz.cpp @@ -85,3 +85,58 @@ namespace cv } } } + +/////////////////////////////////////////////////////////////////////////////////////////////// +/// Viz accessor implementation + +cv::viz::VizAccessor * cv::viz::VizAccessor::instance_ = 0; +bool cv::viz::VizAccessor::is_instantiated_ = false; +cv::viz::VizMap cv::viz::VizAccessor::viz_map_; + +cv::viz::VizAccessor::VizAccessor() {} + +cv::viz::VizAccessor::~VizAccessor() +{ + is_instantiated_ = false; +} + +cv::viz::VizAccessor * cv::viz::VizAccessor::getInstance() +{ + if (is_instantiated_) + { + std::cout << "HERE" << std::endl; + instance_ = new VizAccessor(); + is_instantiated_ = true; + } + return instance_; +} + +cv::viz::Viz3d cv::viz::VizAccessor::get(const String & window_name) +{ + VizMap::iterator vm_itr = viz_map_.find(window_name); + bool exists = vm_itr != viz_map_.end(); + if (exists) return vm_itr->second; + else return viz_map_.insert(VizPair(window_name, Viz3d(window_name))).first->second; +} + +void cv::viz::VizAccessor::add(Viz3d window) +{ + String window_name = window.getWindowName(); + VizMap::iterator vm_itr = viz_map_.find(window_name); + bool exists = vm_itr != viz_map_.end(); + if (exists) return ; + viz_map_.insert(std::pair(window_name, window)); +} + +void cv::viz::VizAccessor::remove(const String &window_name) +{ + VizMap::iterator vm_itr = viz_map_.find(window_name); + bool exists = vm_itr != viz_map_.end(); + if (!exists) return ; + viz_map_.erase(vm_itr); +} + +cv::viz::Viz3d cv::viz::get(const String &window_name) +{ + return cv::viz::VizAccessor::getInstance()->get(window_name); +} \ No newline at end of file diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index ced6e73e1..61502a7d3 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -2,8 +2,44 @@ #include "viz3d_impl.hpp" -cv::viz::Viz3d::Viz3d(const String& window_name) : impl_(new VizImpl(window_name)) {} -cv::viz::Viz3d::~Viz3d() { delete impl_; } +cv::viz::Viz3d::Viz3d(const String& window_name) : impl_(0) { create(window_name); } + +cv::viz::Viz3d::Viz3d(const Viz3d& other) : impl_(other.impl_) +{ + if (impl_) CV_XADD(&impl_->ref_counter, 1); +} + +cv::viz::Viz3d& cv::viz::Viz3d::operator=(const Viz3d& other) +{ + if (this != &other) + { + release(); + impl_ = other.impl_; + if (impl_) CV_XADD(&impl_->ref_counter, 1); + } + return *this; +} + +cv::viz::Viz3d::~Viz3d() { release(); } + +void cv::viz::Viz3d::create(const String &window_name) +{ + if (impl_) release(); + impl_ = new VizImpl(window_name); + impl_->ref_counter = 1; + // Register the window +// cv::viz::VizAccessor::getInstance()->add(*this); +} + +void cv::viz::Viz3d::release() +{ + if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 1) + { + cv::viz::VizAccessor::getInstance()->remove(getWindowName()); + delete impl_; + impl_ = 0; + } +} void cv::viz::Viz3d::setBackgroundColor(const Color& color) { impl_->setBackgroundColor(color); } @@ -55,4 +91,5 @@ void cv::viz::Viz3d::convertToWindowCoordinates(const Point3d &pt, Point3d &wind void cv::viz::Viz3d::converTo3DRay(const Point3d &window_coord, Point3d &origin, Vec3d &direction) { impl_->converTo3DRay(window_coord, origin, direction); } cv::Size cv::viz::Viz3d::getWindowSize() const { return impl_->getWindowSize(); } -void cv::viz::Viz3d::setWindowSize(const Size &window_size) { impl_->setWindowSize(window_size.width, window_size.height); } \ No newline at end of file +void cv::viz::Viz3d::setWindowSize(const Size &window_size) { impl_->setWindowSize(window_size.width, window_size.height); } +cv::String cv::viz::Viz3d::getWindowName() const { return impl_->getWindowName(); } \ No newline at end of file diff --git a/modules/viz/src/viz3d_impl.cpp b/modules/viz/src/viz3d_impl.cpp index a2aa31bed..be389b241 100644 --- a/modules/viz/src/viz3d_impl.cpp +++ b/modules/viz/src/viz3d_impl.cpp @@ -86,7 +86,7 @@ cv::viz::Viz3d::VizImpl::~VizImpl () if (interactor_ != NULL) interactor_->DestroyTimer (timer_id_); - renderer_->Clear(); + if (renderer_) renderer_->Clear(); } ///////////////////////////////////////////////////////////////////////////////////////////// @@ -968,6 +968,11 @@ void cv::viz::Viz3d::VizImpl::setWindowName (const std::string &name) window_->SetWindowName (name.c_str ()); } +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]); } diff --git a/modules/viz/src/viz3d_impl.hpp b/modules/viz/src/viz3d_impl.hpp index e190b720b..5f8ad367b 100644 --- a/modules/viz/src/viz3d_impl.hpp +++ b/modules/viz/src/viz3d_impl.hpp @@ -11,6 +11,8 @@ public: typedef cv::Ptr Ptr; typedef Viz3d::KeyboardCallback KeyboardCallback; typedef Viz3d::MouseCallback MouseCallback; + + int ref_counter; VizImpl (const String &name); virtual ~VizImpl (); @@ -142,6 +144,7 @@ public: void setWindowSize (int xw, int yw); void setFullScreen (bool mode); void setWindowName (const String &name); + String getWindowName() const; void setBackgroundColor (const Color& color); void spin ();