resolved problem with multiple spin()/spinOnce()

pull/2173/head
Anatoly Baksheev 11 years ago
parent 57d5ad5131
commit 16281027af
  1. 16
      modules/viz/doc/viz3d.rst
  2. 3
      modules/viz/include/opencv2/viz/viz3d.hpp
  3. 7
      modules/viz/src/interactor_style.cpp
  4. 2
      modules/viz/src/interactor_style.hpp
  5. 3
      modules/viz/src/viz3d.cpp
  6. 186
      modules/viz/src/vizimpl.cpp
  7. 88
      modules/viz/src/vizimpl.hpp
  8. 21
      modules/viz/test/tests_simple.cpp

@ -134,8 +134,6 @@ The Viz3d class represents a 3D visualizer window. This class is implicitly shar
void setRenderingProperty(const String &id, int property, double value);
double getRenderingProperty(const String &id, int property);
void setDesiredUpdateRate(double rate);
double getDesiredUpdateRate();
void setRepresentation(int representation);
private:
@ -425,20 +423,6 @@ Returns rendering property of a widget.
* **SHADING_GOURAUD**
* **SHADING_PHONG**
viz::Viz3d::setDesiredUpdateRate
--------------------------------
Sets desired update rate of the window.
.. ocv:function:: void setDesiredUpdateRate(double rate)
:param rate: Desired update rate. The default is 30.
viz::Viz3d::getDesiredUpdateRate
--------------------------------
Returns desired update rate of the window.
.. ocv:function:: double getDesiredUpdateRate()
viz::Viz3d::setRepresentation
-----------------------------
Sets geometry representation of the widgets to surface, wireframe or points.

@ -113,9 +113,6 @@ namespace cv
void setRenderingProperty(const String &id, int property, double value);
double getRenderingProperty(const String &id, int property);
void setDesiredUpdateRate(double rate);
double getDesiredUpdateRate();
void setRepresentation(int representation);
private:

@ -220,8 +220,6 @@ int cv::viz::InteractorStyle::getModifiers()
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]);
// Save the initial windows width/height
@ -403,8 +401,8 @@ void cv::viz::InteractorStyle::OnKeyDown()
vtkSmartPointer<vtkRenderWindow> window = Interactor->GetRenderWindow();
if (!window->GetStereoRender())
{
static Vec2i default_mask(4, 3), alternative_mask(2, 5);
window->SetAnaglyphColorMask (stereo_anaglyph_mask_default_ ? default_mask.val : alternative_mask.val);
static Vec2i red_blue(4, 3), magenta_green(2, 5);
window->SetAnaglyphColorMask (stereo_anaglyph_mask_default_ ? red_blue.val : magenta_green.val);
stereo_anaglyph_mask_default_ = !stereo_anaglyph_mask_default_;
}
window->SetStereoRender(!window->GetStereoRender());
@ -637,6 +635,5 @@ void cv::viz::InteractorStyle::OnMouseWheelBackward()
void cv::viz::InteractorStyle::OnTimer()
{
CV_Assert("Interactor style not initialized." && init_);
CV_Assert("Renderer has not been set." && renderer_);
Interactor->Render();
}

@ -63,7 +63,6 @@ namespace cv
virtual void Initialize();
void setWidgetActorMap(const Ptr<WidgetActorMap>& actors) { widget_actor_map_ = actors; }
void setRenderer(vtkSmartPointer<vtkRenderer>& renderer) { renderer_ = renderer; }
void registerMouseCallback(void (*callback)(const MouseEvent&, void*), void* cookie = 0);
void registerKeyboardCallback(void (*callback)(const KeyboardEvent&, void*), void * cookie = 0);
void saveScreenshot(const String &file);
@ -73,7 +72,6 @@ namespace cv
/** \brief Set to true after initialization is complete. */
bool init_;
vtkSmartPointer<vtkRenderer> renderer_;
Ptr<WidgetActorMap> widget_actor_map_;
Vec2i win_size_;

@ -145,7 +145,4 @@ void cv::viz::Viz3d::setBackgroundMeshLab() {impl_->setBackgroundMeshLab(); }
void cv::viz::Viz3d::setRenderingProperty(const String &id, int property, double value) { getWidget(id).setRenderingProperty(property, value); }
double cv::viz::Viz3d::getRenderingProperty(const String &id, int property) { return getWidget(id).getRenderingProperty(property); }
void cv::viz::Viz3d::setDesiredUpdateRate(double rate) { impl_->setDesiredUpdateRate(rate); }
double cv::viz::Viz3d::getDesiredUpdateRate() { return impl_->getDesiredUpdateRate(); }
void cv::viz::Viz3d::setRepresentation(int representation) { impl_->setRepresentation(representation); }

@ -46,25 +46,17 @@
#include "precomp.hpp"
/////////////////////////////////////////////////////////////////////////////////////////////
cv::viz::Viz3d::VizImpl::VizImpl(const String &name)
: s_lastDone_(0.0), style_(vtkSmartPointer<InteractorStyle>::New()), widget_actor_map_(new WidgetActorMap)
cv::viz::Viz3d::VizImpl::VizImpl(const String &name) : spin_once_state_(false), widget_actor_map_(new WidgetActorMap)
{
renderer_ = vtkSmartPointer<vtkRenderer>::New();
// Create render window
window_ = vtkSmartPointer<vtkRenderWindow>::New();
window_name_ = VizStorage::generateWindowName(name);
// 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>::New();
window_->AlphaBitPlanesOff();
window_->PointSmoothingOff();
window_->LineSmoothingOff();
@ -72,37 +64,89 @@ cv::viz::Viz3d::VizImpl::VizImpl(const String &name)
window_->SwapBuffersOn();
window_->SetStereoTypeToAnaglyph();
interactor_->SetRenderWindow(window_);
interactor_->SetInteractorStyle(style_);
interactor_->SetDesiredUpdateRate(24.0);
// Create the interactor style
style_ = vtkSmartPointer<InteractorStyle>::New();
style_->setWidgetActorMap(widget_actor_map_);
style_->UseTimersOn();
style_->Initialize();
// Initialize and create timer, also create window
interactor_->Initialize();
timer_id_ = interactor_->CreateRepeatingTimer(5000L);
timer_callback_ = vtkSmartPointer<TimerCallback>::New();
exit_callback_ = vtkSmartPointer<ExitCallback>::New();
exit_callback_->viz = this;
}
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_);
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::TimerCallback::Execute(vtkObject* caller, unsigned long event_id, void* cookie)
{
if (event_id == vtkCommand::TimerEvent && timer_id == *reinterpret_cast<int*>(cookie))
{
vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkRenderWindowInteractor::SafeDownCast(caller);
interactor->TerminateApp();
}
}
exit_callback_ = vtkSmartPointer<ExitCallback>::New();
exit_callback_->viz_ = this;
interactor_->AddObserver(vtkCommand::ExitEvent, exit_callback_);
void cv::viz::Viz3d::VizImpl::ExitCallback::Execute(vtkObject*, unsigned long event_id, void*)
{
if (event_id == vtkCommand::ExitEvent)
{
viz->interactor_->TerminateApp();
viz->interactor_ = 0;
}
}
resetStoppedFlag();
/////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////
String window_name = VizStorage::generateWindowName(name);
window_->SetWindowName(window_name.c_str());
bool cv::viz::Viz3d::VizImpl::wasStopped() const
{
bool stopped = spin_once_state_ ? interactor_ == 0 : false;
spin_once_state_ &= !stopped;
return stopped;
}
void cv::viz::Viz3d::VizImpl::close()
{
if (!interactor_)
return;
interactor_->GetRenderWindow()->Finalize();
interactor_->TerminateApp(); // This tends to close the window...
}
/////////////////////////////////////////////////////////////////////////////////////////////
cv::viz::Viz3d::VizImpl::~VizImpl()
void cv::viz::Viz3d::VizImpl::spin()
{
if (interactor_)
interactor_->DestroyTimer(timer_id_);
if (renderer_)
renderer_->Clear();
interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor_->SetRenderWindow(window_);
interactor_->SetInteractorStyle(style_);
window_->Render();
window_->SetWindowName(window_name_.c_str());
interactor_->Start();
interactor_ = 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::spinOnce(int time, bool force_redraw)
{
if (interactor_ == 0)
{
spin_once_state_ = true;
interactor_ = vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor_->SetRenderWindow(window_);
interactor_->SetInteractorStyle(style_);
interactor_->AddObserver(vtkCommand::TimerEvent, timer_callback_);
interactor_->AddObserver(vtkCommand::ExitEvent, exit_callback_);
window_->Render();
window_->SetWindowName(window_name_.c_str());
}
vtkSmartPointer<vtkRenderWindowInteractor> local = interactor_;
if (force_redraw)
local->Render();
timer_callback_->timer_id = local->CreateOneShotTimer(std::max(1, time));
local->Start();
local->DestroyTimer(timer_callback_->timer_id);
}
/////////////////////////////////////////////////////////////////////////////////////////////
@ -208,19 +252,6 @@ cv::Affine3d cv::viz::Viz3d::VizImpl::getWidgetPose(const String &id) const
return Affine3d(*actor->GetUserMatrix()->Element);
}
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::setDesiredUpdateRate(double rate)
{
if (interactor_)
interactor_->SetDesiredUpdateRate(rate);
}
/////////////////////////////////////////////////////////////////////////////////////////////
double cv::viz::Viz3d::VizImpl::getDesiredUpdateRate()
{
return interactor_ ? interactor_->GetDesiredUpdateRate() : 0.0;
}
/////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::saveScreenshot(const String &file) { style_->saveScreenshot(file.c_str()); }
@ -231,37 +262,6 @@ void cv::viz::Viz3d::VizImpl::registerMouseCallback(MouseCallback callback, void
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()
@ -282,18 +282,15 @@ void cv::viz::Viz3d::VizImpl::showImage(InputArray image, const Size& window_siz
/////////////////////////////////////////////////////////////////////////////////////////////
bool cv::viz::Viz3d::VizImpl::removeActorFromRenderer(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;
}
if (current_actor == actor)
{
renderer_->RemoveActor(actor);
return true;
}
return false;
}
@ -313,11 +310,8 @@ void cv::viz::Viz3d::VizImpl::setBackgroundGradient(const Color& up, const Colo
renderer_->GradientBackgroundOn();
}
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::setBackgroundMeshLab()
{
setBackgroundGradient(Color(2, 1, 1), Color(240, 120, 120));
}
{ setBackgroundGradient(Color(2, 1, 1), Color(240, 120, 120)); }
//////////////////////////////////////////////////////////////////////////////////////////////
void cv::viz::Viz3d::VizImpl::setBackgroundTexture(InputArray image)
@ -512,14 +506,8 @@ void cv::viz::Viz3d::VizImpl::setRepresentation(int representation)
}
//////////////////////////////////////////////////////////////////////////////////////////////
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() : ""; }
cv::String cv::viz::Viz3d::VizImpl::getWindowName() const { return window_name_; }
void cv::viz::Viz3d::VizImpl::setFullScreen(bool mode) { window_->SetFullScreen(mode); }
void cv::viz::Viz3d::VizImpl::setWindowPosition(const Point& position) { window_->SetPosition(position.x, position.y); }
void cv::viz::Viz3d::VizImpl::setWindowSize(const Size& window_size) { window_->SetSize(window_size.width, window_size.height); }
cv::Size cv::viz::Viz3d::VizImpl::getWindowSize() const { return Size(window_->GetSize()[0], window_->GetSize()[1]); }
cv::Size cv::viz::Viz3d::VizImpl::getWindowSize() const { return Size(Point(Vec2i(window_->GetSize()))); }

@ -55,7 +55,13 @@ public:
int ref_counter;
VizImpl(const String &name);
virtual ~VizImpl();
virtual ~VizImpl() {};
bool wasStopped() const;
void close();
void spin();
void spinOnce(int time = 1, bool force_redraw = false);
void showWidget(const String &id, const Widget &widget, const Affine3d &pose = Affine3d::Identity());
void removeWidget(const String &id);
@ -68,26 +74,6 @@ public:
void updateWidgetPose(const String &id, const Affine3d &pose);
Affine3d getWidgetPose(const String &id) const;
void setDesiredUpdateRate(double rate);
double getDesiredUpdateRate();
/** \brief Returns true when the user tried to close the window */
bool wasStopped() const { return interactor_ ? stopped_ : true; }
/** \brief Set the stopped flag back to false */
void resetStoppedFlag() { if (interactor_) stopped_ = false; }
/** \brief Stop the interaction and close the visualizaton window. */
void close()
{
stopped_ = true;
if (interactor_)
{
interactor_->GetRenderWindow()->Finalize();
interactor_->TerminateApp(); // This tends to close the window...
}
}
void setRepresentation(int representation);
void setCamera(const Camera &camera);
@ -114,72 +100,36 @@ public:
void setBackgroundTexture(InputArray image);
void setBackgroundMeshLab();
void spin();
void spinOnce(int time = 1, bool force_redraw = false);
void registerKeyboardCallback(KeyboardCallback callback, void* cookie = 0);
void registerMouseCallback(MouseCallback callback, void* cookie = 0);
private:
vtkSmartPointer<vtkRenderWindowInteractor> interactor_;
struct ExitMainLoopTimerCallback : public vtkCommand
struct TimerCallback : public vtkCommand
{
static ExitMainLoopTimerCallback* New() { return new ExitMainLoopTimerCallback; }
virtual void Execute(vtkObject* vtkNotUsed(caller), unsigned long event_id, void* call_data)
{
if (event_id != vtkCommand::TimerEvent)
return;
int timer_id = *reinterpret_cast<int*>(call_data);
if (timer_id != right_timer_id)
return;
// Stop vtk loop and send notification to app to wake it up
viz_->interactor_->TerminateApp();
}
int right_timer_id;
VizImpl* viz_;
static TimerCallback* New() { return new TimerCallback; }
virtual void Execute(vtkObject* caller, unsigned long event_id, void* cookie);
int timer_id;
};
struct ExitCallback : public vtkCommand
{
static ExitCallback* New() { return new ExitCallback; }
virtual void Execute(vtkObject*, unsigned long event_id, void*)
{
if (event_id == vtkCommand::ExitEvent)
{
viz_->stopped_ = true;
viz_->interactor_->GetRenderWindow()->Finalize();
viz_->interactor_->TerminateApp();
}
}
VizImpl* viz_;
virtual void Execute(vtkObject*, unsigned long event_id, void*);
VizImpl* viz;
};
/** \brief Set to false if the interaction loop is running. */
bool stopped_;
double s_lastDone_;
mutable bool spin_once_state_;
vtkSmartPointer<vtkRenderWindowInteractor> interactor_;
/** \brief Global timer ID. Used in destructor only. */
int timer_id_;
vtkSmartPointer<vtkRenderWindow> window_;
String window_name_;
/** \brief Callback object enabling us to leave the main loop, when a timer fires. */
vtkSmartPointer<ExitMainLoopTimerCallback> exit_main_loop_timer_callback_;
vtkSmartPointer<TimerCallback> timer_callback_;
vtkSmartPointer<ExitCallback> exit_callback_;
vtkSmartPointer<vtkRenderer> renderer_;
vtkSmartPointer<vtkRenderWindow> window_;
/** \brief The render window interactor style. */
vtkSmartPointer<InteractorStyle> style_;
/** \brief Internal list with actor pointers and name IDs for all widget actors */
cv::Ptr<WidgetActorMap> widget_actor_map_;
/** \brief Boolean that holds whether or not the camera parameters were manually initialized*/
bool camera_set_;
Ptr<WidgetActorMap> widget_actor_map_;
bool removeActorFromRenderer(vtkSmartPointer<vtkProp> actor);
};

@ -236,7 +236,7 @@ TEST(Viz, show_trajectories)
viz.setViewerPose(makeCameraPose(pose * 7.5, Vec3d(0.0, 0.5, 0.0), Vec3d(0.0, 0.1, 0.0)));
viz.spinOnce(20, true);
}
//viz.spin();
viz.spin();
}
TEST(Viz, show_trajectory_reposition)
@ -299,7 +299,7 @@ TEST(Viz, show_overlay_image)
viz.getWidget("img1").cast<WImageOverlay>().setImage(lena * pow(sin(i*10*CV_PI/180) * 0.5 + 0.5, 1.0));
viz.spinOnce(1, true);
}
//viz.spin();
viz.spin();
}
@ -338,7 +338,7 @@ TEST(Viz, show_image_3d)
viz.getWidget("img0").cast<WImage3D>().setImage(lena * pow(sin(i++*7.5*CV_PI/180) * 0.5 + 0.5, 1.0));
viz.spinOnce(1, true);
}
//viz.spin();
viz.spin();
}
TEST(Viz, show_simple_widgets)
@ -365,7 +365,7 @@ TEST(Viz, show_simple_widgets)
viz.showWidget("grid1", WGrid(Vec2i(7,7), Vec2d::all(0.75), Color::gray()), Affine3d().translate(Vec3d(0.0, 0.0, -1.0)));
viz.spinOnce(1500, true);
viz.spin();
viz.getWidget("text2d").cast<WText>().setText("New simple text");
viz.getWidget("text3d").cast<WText3D>().setText("Updated text 3D");
viz.spin();
@ -379,18 +379,7 @@ TEST(Viz, show_follower)
viz.showWidget("cube", WCube());
viz.showWidget("t3d_2", WText3D("Simple 3D follower", Point3d(-0.5, -0.5, 0.5), 0.125, true, Color::green()));
viz.setBackgroundMeshLab();
viz.spinOnce(1500, true);
viz.getWidget("t3d_2").cast<WText3D>().setText("Updated follower 3D");
viz.spin();
}
TEST(Viz, DISABLED_spin_twice_____________________________TODO_UI_BUG)
{
Mesh mesh = Mesh::load(get_dragon_ply_file_path());
Viz3d viz("spin_twice");
viz.showWidget("coosys", WCoordinateSystem());
viz.showWidget("mesh", WMesh(mesh));
viz.spin();
viz.getWidget("t3d_2").cast<WText3D>().setText("Updated follower 3D");
viz.spin();
}

Loading…
Cancel
Save