diff --git a/modules/viz/include/opencv2/viz.hpp b/modules/viz/include/opencv2/viz.hpp index 5c2fe03d9..d4f08af72 100644 --- a/modules/viz/include/opencv2/viz.hpp +++ b/modules/viz/include/opencv2/viz.hpp @@ -63,9 +63,12 @@ namespace cv //! 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); - //! retrieves a window by its name + //! retrieves a window by its name. If no window with such name, then it creates new. CV_EXPORTS Viz3d get(const String &window_name); + //! Unregisters all Viz windows from internal database. After it 'get()' will create new windows instead getting existing from the database. + CV_EXPORTS void unregisterAllWindows(); + //! checks float value for Nan inline bool isNan(float x) { @@ -88,32 +91,6 @@ namespace cv template inline bool isNan(const Point3_<_Tp>& p) { return isNan(p.x) || isNan(p.y) || isNan(p.z); } - //! helper class that provides access by name infrastructure - class CV_EXPORTS VizAccessor - { - public: - static VizAccessor & getInstance(); - static void release(); - - Viz3d get(const String &window_name); - - //! window names automatically have Viz - prefix even though not provided by the users - static void generateWindowName(const String &window_name, String &output); - - private: - VizAccessor(); // Singleton - ~VizAccessor(); - - void add(Viz3d window); - void remove(const String &window_name); - - static VizAccessor * instance_; - - struct VizAccessorImpl; - VizAccessorImpl * impl_; - - friend class Viz3d; - }; } /* namespace viz */ } /* namespace cv */ diff --git a/modules/viz/include/opencv2/viz/viz3d.hpp b/modules/viz/include/opencv2/viz/viz3d.hpp index 59654b5c9..fe19c6172 100644 --- a/modules/viz/include/opencv2/viz/viz3d.hpp +++ b/modules/viz/include/opencv2/viz/viz3d.hpp @@ -121,6 +121,8 @@ namespace cv void create(const String &window_name); void release(); + + friend class VizStorage; }; } /* namespace viz */ diff --git a/modules/viz/src/precomp.hpp b/modules/viz/src/precomp.hpp index 6df03e4f6..1b685e8fb 100644 --- a/modules/viz/src/precomp.hpp +++ b/modules/viz/src/precomp.hpp @@ -135,20 +135,35 @@ namespace cv namespace viz { typedef std::map > WidgetActorMap; + typedef std::map VizMap; + typedef std::pair VizPair; + + class VizStorage + { + public: + static void unregisterAll(); + + //! window names automatically have Viz - prefix even though not provided by the users + static String generateWindowName(const String &window_name); + + private: + VizStorage(); // Static + ~VizStorage(); + + static void add(Viz3d window); + static Viz3d get(const String &window_name); + static void remove(const String &window_name); + static bool windowExists(const String &window_name); + static void removeUnreferenced(); + + static VizMap storage; + friend class Viz3d; + }; } } #include "interactor_style.h" #include "viz3d_impl.hpp" -namespace cv -{ - namespace viz - { - typedef std::map VizMap; - typedef std::pair VizPair; - } -} - #endif diff --git a/modules/viz/src/viz.cpp b/modules/viz/src/viz.cpp index 747c8de34..703da98cd 100644 --- a/modules/viz/src/viz.cpp +++ b/modules/viz/src/viz.cpp @@ -107,70 +107,46 @@ namespace cv { namespace viz }} /////////////////////////////////////////////////////////////////////////////////////////////// -/// Viz accessor implementation +/// VizStorage implementation -cv::viz::VizAccessor * cv::viz::VizAccessor::instance_ = 0; +cv::viz::VizMap cv::viz::VizStorage::storage; +void cv::viz::VizStorage::unregisterAll() { storage.clear(); } -struct cv::viz::VizAccessor::VizAccessorImpl +cv::viz::Viz3d cv::viz::VizStorage::get(const String &window_name) { - cv::viz::VizMap viz_map; -}; - -cv::viz::VizAccessor::VizAccessor() { impl_ = new cv::viz::VizAccessor::VizAccessorImpl;} -cv::viz::VizAccessor::~VizAccessor() { delete impl_; } - -cv::viz::VizAccessor & cv::viz::VizAccessor::getInstance() -{ - if (!instance_) - instance_ = new VizAccessor(); - - return *instance_; + String name = generateWindowName(window_name); + VizMap::iterator vm_itr = storage.find(name); + CV_Assert(vm_itr != storage.end()); + return vm_itr->second; } -void cv::viz::VizAccessor::release() -{ - if (instance_) - { - delete instance_; - instance_ = 0; - } -} - -cv::viz::Viz3d cv::viz::VizAccessor::get(const String & window_name) -{ - // Add the prefix Viz - String name; - generateWindowName(window_name, name); - - VizMap::iterator vm_itr = impl_->viz_map.find(name); - return vm_itr != impl_->viz_map.end() ? vm_itr->second : Viz3d(window_name); -} - -void cv::viz::VizAccessor::add(Viz3d window) +void cv::viz::VizStorage::add(Viz3d window) { String window_name = window.getWindowName(); - VizMap::iterator vm_itr = impl_->viz_map.find(window_name); - if (vm_itr == impl_->viz_map.end()) - impl_->viz_map.insert(VizPair(window_name, window)); + VizMap::iterator vm_itr = storage.find(window_name); + CV_Assert(vm_itr == storage.end()); + storage.insert(VizPair(window_name, window)); } -void cv::viz::VizAccessor::remove(const String &window_name) +bool cv::viz::VizStorage::windowExists(const String &window_name) { - // Add the prefix Viz - String name; - generateWindowName(window_name, name); - - VizMap::iterator vm_itr = impl_->viz_map.find(name); - if (vm_itr != impl_->viz_map.end()) - impl_->viz_map.erase(vm_itr); + String name = generateWindowName(window_name); + return storage.find(name) != storage.end(); } -void cv::viz::VizAccessor::generateWindowName(const String &window_name, String &output) +void cv::viz::VizStorage::removeUnreferenced() { - output = "Viz"; + for(VizMap::iterator pos = storage.begin(); pos != storage.end(); ++pos) + if(pos->second.impl_->ref_counter == 1) + storage.erase(pos); +} + +cv::String cv::viz::VizStorage::generateWindowName(const String &window_name) +{ + String output = "Viz"; // Already is Viz if (window_name == output) - return; + return output; String prefixed = output + " - "; if (window_name.substr(0, prefixed.length()) == prefixed) @@ -179,9 +155,9 @@ void cv::viz::VizAccessor::generateWindowName(const String &window_name, String output = prefixed + window_name; // Doesn't have prefix else output = (window_name == "" ? output : prefixed + window_name); + + return output; } -cv::viz::Viz3d cv::viz::get(const String &window_name) -{ - return cv::viz::VizAccessor::getInstance().get(window_name); -} +cv::viz::Viz3d cv::viz::get(const String &window_name) { return Viz3d(window_name); } +void cv::viz::unregisterAllWindows() { VizStorage::unregisterAll(); } diff --git a/modules/viz/src/viz3d.cpp b/modules/viz/src/viz3d.cpp index f5a0bc889..ec57a3f44 100644 --- a/modules/viz/src/viz3d.cpp +++ b/modules/viz/src/viz3d.cpp @@ -52,7 +52,8 @@ 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); + if (impl_) + CV_XADD(&impl_->ref_counter, 1); } cv::viz::Viz3d& cv::viz::Viz3d::operator=(const Viz3d& other) @@ -70,24 +71,28 @@ 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); + if (impl_) + release(); + + if (VizStorage::windowExists(window_name)) + *this = VizStorage::get(window_name); + else + { + impl_ = new VizImpl(window_name); + impl_->ref_counter = 1; + + // Register the window + VizStorage::add(*this); + } } void cv::viz::Viz3d::release() { - // If the current referene count is equal to 2, we can delete it - // - 2 : because minimum there will be two instances, one of which is in the map - if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 2) - { - // Erase the window - cv::viz::VizAccessor::getInstance().remove(getWindowName()); + if (impl_ && CV_XADD(&impl_->ref_counter, -1) == 1) delete impl_; - impl_ = 0; - } + + impl_ = 0; + VizStorage::removeUnreferenced(); } void cv::viz::Viz3d::spin() { impl_->spin(); }