diff --git a/include/guik/viewer/async_light_viewer.hpp b/include/guik/viewer/async_light_viewer.hpp index 421ab303..c4ab641a 100644 --- a/include/guik/viewer/async_light_viewer.hpp +++ b/include/guik/viewer/async_light_viewer.hpp @@ -32,6 +32,7 @@ class AsyncLightViewer : public AsyncLightViewerContext { void invoke(const std::function& func); void invoke_after_rendering(const std::function& func); + void invoke_once(const std::string& label, const std::function& func); void clear_images(); void remove_image(const std::string& name); @@ -41,7 +42,8 @@ class AsyncLightViewer : public AsyncLightViewerContext { void clear_plots(bool clear_settings = true); void remove_plot(const std::string& plot_name, const std::string& label = ""); void setup_plot(const std::string& plot_name, int width, int height, int plot_flags = 0, int x_flags = 0, int y_flags = 0, int order = -1); - void link_plot_axes(const std::string& plot_name, int link_id, int axis); + void link_plot_axis(const std::string& plot_name, int link_id, int axis); + void link_plot_axes(const std::string& plot_name, int link_id, int axes = -1); void setup_legend(const std::string& plot_name, int loc, int flags = 0); void fit_plot(const std::string& plot_name); void fit_all_plots(); diff --git a/include/guik/viewer/light_viewer.hpp b/include/guik/viewer/light_viewer.hpp index daa9418c..36914478 100644 --- a/include/guik/viewer/light_viewer.hpp +++ b/include/guik/viewer/light_viewer.hpp @@ -33,8 +33,12 @@ class LightViewer : public guik::Application, public guik::LightViewerContext { bool toggle_spin_once(); virtual void register_ui_callback(const std::string& name, const std::function& callback = 0) override; + // Invoke a task in the visualization thread void invoke(const std::function& func); + // Invoke a task after rendering in the visualization thread void invoke_after_rendering(const std::function& func); + // Invoke a labeled task only once + void invoke_once(const std::string& label, const std::function& func); virtual void clear() override; virtual void clear_text() override; @@ -55,7 +59,8 @@ class LightViewer : public guik::Application, public guik::LightViewerContext { void clear_plots(bool clear_settings = true); void remove_plot(const std::string& plot_name, const std::string& label = ""); void setup_plot(const std::string& plot_name, int width, int height, int plot_flags = 0, int x_flags = 0, int y_flags = 0, int order = -1); - void link_plot_axes(const std::string& plot_name, int link_id, int axis); + void link_plot_axis(const std::string& plot_name, int link_id, int axis); // axis = ImAxis_X1 or ImAxis_X2, ... + void link_plot_axes(const std::string& plot_name, int link_id, int axes = -1); // axes = (1 << ImAxis_X1) | (1 << ImAxis_X2) ... void setup_legend(const std::string& plot_name, int loc, int flags = 0); void fit_plot(const std::string& plot_name); void fit_all_plots(); @@ -286,6 +291,7 @@ class LightViewer : public guik::Application, public guik::LightViewerContext { std::mutex invoke_requests_mutex; std::deque> invoke_requests; + std::unordered_set invoke_once_called; std::mutex post_render_invoke_requests_mutex; std::deque> post_render_invoke_requests; diff --git a/include/guik/viewer/plot_setting.hpp b/include/guik/viewer/plot_setting.hpp index 2510825d..bd84c584 100644 --- a/include/guik/viewer/plot_setting.hpp +++ b/include/guik/viewer/plot_setting.hpp @@ -40,7 +40,7 @@ struct PlotSetting { int order; int axis_link_id; // -1 for invalid - int linked_axes; // 1 << ImAxes_X1 | 1 << ImAxes_X2 | ... + int linked_axes; // 1 << ImAxis_X1 | 1 << ImAxis_X2 | ... bool set_axes_to_fit; }; diff --git a/src/guik/viewer/async_light_viewer.cpp b/src/guik/viewer/async_light_viewer.cpp index 02dcf7f1..b0df3111 100644 --- a/src/guik/viewer/async_light_viewer.cpp +++ b/src/guik/viewer/async_light_viewer.cpp @@ -109,6 +109,10 @@ void AsyncLightViewer::invoke_after_rendering(const std::function& func) guik::viewer()->invoke_after_rendering(func); } +void AsyncLightViewer::invoke_once(const std::string& label, const std::function& func) { + guik::viewer()->invoke_once(label, func); +} + void AsyncLightViewer::clear_images() { guik::viewer()->invoke([] { guik::viewer()->clear_images(); }); } @@ -136,8 +140,12 @@ void AsyncLightViewer::setup_plot(const std::string& plot_name, int width, int h guik::viewer()->invoke([=] { guik::viewer()->setup_plot(plot_name, width, height, plot_flags, x_flags, y_flags, order); }); } -void AsyncLightViewer::link_plot_axes(const std::string& plot_name, int link_id, int axis) { - guik::viewer()->invoke([=] { guik::viewer()->link_plot_axes(plot_name, link_id, axis); }); +void AsyncLightViewer::link_plot_axis(const std::string& plot_name, int link_id, int axis) { + guik::viewer()->invoke([=] { guik::viewer()->link_plot_axis(plot_name, link_id, axis); }); +} + +void AsyncLightViewer::link_plot_axes(const std::string& plot_name, int link_id, int axes) { + guik::viewer()->invoke([=] { guik::viewer()->link_plot_axes(plot_name, link_id, axes); }); } void AsyncLightViewer::setup_legend(const std::string& plot_name, int loc, int flags) { diff --git a/src/guik/viewer/light_viewer.cpp b/src/guik/viewer/light_viewer.cpp index 846ed07c..00cd8753 100644 --- a/src/guik/viewer/light_viewer.cpp +++ b/src/guik/viewer/light_viewer.cpp @@ -439,7 +439,7 @@ void LightViewer::setup_plot(const std::string& plot_name, int width, int height setting.order = order >= 0 ? order : 8192 + plot_settings.size(); } -void LightViewer::link_plot_axes(const std::string& plot_name, int link_id, int axis) { +void LightViewer::link_plot_axis(const std::string& plot_name, int link_id, int axis) { auto& setting = plot_settings[plot_name]; setting.axis_link_id = link_id; setting.linked_axes |= (1 << axis); @@ -449,6 +449,16 @@ void LightViewer::link_plot_axes(const std::string& plot_name, int link_id, int } } +void LightViewer::link_plot_axes(const std::string& plot_name, int link_id, int axes) { + auto& setting = plot_settings[plot_name]; + setting.axis_link_id = link_id; + setting.linked_axes = axes; + + if (plot_linked_axis_limits.count(link_id) == 0) { + plot_linked_axis_limits[link_id] = Eigen::Matrix::Zero(); + } +} + void LightViewer::setup_legend(const std::string& plot_name, int loc, int flags) { auto& setting = plot_settings[plot_name]; setting.legend_loc = loc; @@ -694,6 +704,14 @@ void LightViewer::invoke_after_rendering(const std::function& func) { post_render_invoke_requests.push_back(func); } +void LightViewer::invoke_once(const std::string& label, const std::function& func) { + std::lock_guard lock(invoke_requests_mutex); + if (invoke_once_called.count(label) == 0) { + invoke_requests.push_back(func); + invoke_once_called.insert(label); + } +} + std::shared_ptr LightViewer::sub_viewer(const std::string& context_name, const Eigen::Vector2i& canvas_size) { using namespace glk::console;