// License: Apache 2.0. See LICENSE file in root directory. // Copyright(c) 2017 Intel Corporation. All Rights Reserved. #pragma once #include "rendering.h" #include "ux-window.h" #include "rs-config.h" #define GLFW_INCLUDE_GLU #include <GLFW/glfw3.h> #include "opengl3.h" #include <imgui.h> #include <imgui_impl_glfw.h> #include <map> #include <set> #include <array> #include <unordered_map> #include <fstream> #include "objects-in-frame.h" #include "processing-block-model.h" #include "realsense-ui-advanced-mode.h" #include "fw-update-helper.h" #include "updates-model.h" #include "calibration-model.h" #include <rsutils/time/periodic-timer.h> #include <rsutils/number/stabilized-value.h> #include "option-model.h" namespace rs2 { std::vector<const char*> get_string_pointers(const std::vector<std::string>& vec); bool restore_processing_block(const char* name, std::shared_ptr<rs2::processing_block> pb, bool enable = true); std::string get_device_sensor_name(subdevice_model* sub); class frame_queues { public: frame_queue& at(int id) { std::lock_guard<std::mutex> lock(_lookup_mutex); return _queues[id]; } template<class T> void foreach(T action) { std::lock_guard<std::mutex> lock(_lookup_mutex); for (auto&& kvp : _queues) action(kvp.second); } private: std::unordered_map<int, frame_queue> _queues; std::mutex _lookup_mutex; }; // Preserve user selections in UI struct subdevice_ui_selection { int selected_res_id = 0; std::map<int, int> selected_res_id_map; // used for depth and ir mixed resolutions bool is_multiple_resolutions = false; // used for depth and ir mixed resolutions int selected_shared_fps_id = 0; std::map<int, int> selected_fps_id; std::map<int, int> selected_format_id; }; class subdevice_model { public: void populate_options( const std::string & opt_base_label, bool * options_invalidated, std::string & error_message ); subdevice_model(device& dev, std::shared_ptr<sensor> s, std::shared_ptr< atomic_objects_in_frame > objects, std::string& error_message, viewer_model& viewer, bool new_device_connected = true); ~subdevice_model(); bool is_there_common_fps(); bool supports_on_chip_calib(); bool draw_stream_selection(std::string& error_message); bool is_selected_combination_supported(); std::vector<stream_profile> get_selected_profiles(bool enforce_inter_stream_policies = true); std::vector<stream_profile> get_supported_profiles(); void stop(std::shared_ptr<notifications_model> not_model); void play(const std::vector<stream_profile>& profiles, viewer_model& viewer, std::shared_ptr<rs2::asynchronous_syncer>); bool is_synchronized_frame(viewer_model& viewer, const frame& f); void update(std::string& error_message, notifications_model& model); void draw_options(const std::vector<rs2_option>& drawing_order, bool update_read_only_options, std::string& error_message, notifications_model& model); uint64_t num_supported_non_default_options() const; bool draw_option(rs2_option opt, bool update_read_only_options, std::string& error_message, notifications_model& model) { if (options_metadata.find(opt) != options_metadata.end()) return options_metadata[opt].draw_option(update_read_only_options, streaming, error_message, model); return false; } bool is_paused() const; void pause(); void resume(); void update_ui(std::vector<stream_profile> profiles_vec); void get_sorted_profiles(std::vector<stream_profile>& profiles); template<typename T, typename V> bool check_profile(stream_profile p, T cond, std::map<V, std::map<int, stream_profile>>& profiles_map, std::vector<stream_profile>& results, V key, int num_streams, stream_profile& def_p); void restore_ui_selection() { ui = last_valid_ui; } void store_ui_selection() { last_valid_ui = ui; } void get_depth_ir_mismatch_resolutions_ids(int& depth_res_id, int& ir1_res_id, int& ir2_res_id) const; template<typename T> bool get_default_selection_index(const std::vector<T>& values, const T& def, int* index) { auto max_default = values.begin(); for (auto it = values.begin(); it != values.end(); it++) { if (*it == def) { *index = (int)(it - values.begin()); return true; } if (*max_default < *it) { max_default = it; } } *index = (int)(max_default - values.begin()); return false; } viewer_model& viewer; std::function<void()> on_frame = [] {}; std::ofstream _fout; std::shared_ptr<sensor> s; device dev; std::shared_ptr< atomic_objects_in_frame > detected_objects; std::map< rs2_option, option_model > options_metadata; std::vector<std::string> resolutions; std::map<int, std::vector<std::string>> fpses_per_stream; std::vector<std::string> shared_fpses; std::map<int, std::vector<std::string>> formats; std::map<int, bool> stream_enabled; std::map<int, bool> prev_stream_enabled; std::map<int, std::string> stream_display_names; subdevice_ui_selection ui; subdevice_ui_selection last_valid_ui; std::vector<std::pair<int, int>> res_values; std::map<int, std::vector<std::pair<int, int>>> profile_id_to_res; // used for depth and ir mixed resolutions std::map<int, std::vector<int>> fps_values_per_stream; std::vector<int> shared_fps_values; bool show_single_fps_list = false; std::map<int, std::vector<rs2_format>> format_values; std::vector<stream_profile> profiles; frame_queues queues; std::mutex _queue_lock; bool _options_invalidated = false; int next_option = 0; std::vector<rs2_option> supported_options; bool streaming = false; std::map<int, bool> streaming_map; // used for depth and ir mixed resolutions bool allow_change_resolution_while_streaming = false; bool allow_change_fps_while_streaming = false; rect normalized_zoom{ 0, 0, 1, 1 }; rect roi_rect; bool auto_exposure_enabled = false; float depth_units = 1.f; float stereo_baseline = -1.f; bool roi_checked = false; std::atomic<bool> _pause; std::atomic<bool> _is_being_recorded{ false }; bool draw_streams_selector = true; bool draw_fps_selector = true; bool draw_advanced_mode_prompt = false; region_of_interest algo_roi; bool show_algo_roi = false; float roi_percentage; std::shared_ptr<rs2::colorizer> depth_colorizer; std::shared_ptr<rs2::yuy_decoder> yuy2rgb; std::shared_ptr<rs2::y411_decoder> y411; std::vector<std::shared_ptr<processing_block_model>> post_processing; bool post_processing_enabled = true; std::vector<std::shared_ptr<processing_block_model>> const_effects; bool uvmapping_calib_full = false; private: bool draw_resolutions(std::string& error_message, std::string& label, std::function<void()> streaming_tooltip, float col0, float col1); bool draw_fps(std::string& error_message, std::string& label, std::function<void()> streaming_tooltip, float col0, float col1); bool draw_streams_and_formats(std::string& error_message, std::string& label, std::function<void()> streaming_tooltip, float col0, float col1); bool draw_res_stream_formats(std::string& error_message, std::string& label, std::function<void()> streaming_tooltip, float col0, float col1); bool draw_resolutions_combo_box_multiple_resolutions(std::string& error_message, std::string& label, std::function<void()> streaming_tooltip, float col0, float col1, int stream_type_id, int depth_res_id); bool draw_formats_combo_box_multiple_resolutions(std::string& error_message, std::string& label, std::function<void()> streaming_tooltip, float col0, float col1, int stream_type_id); bool is_multiple_resolutions_supported() const { return false; } std::pair<int, int> get_max_resolution(rs2_stream stream) const; void sort_resolutions(std::vector<std::pair<int, int>>& resolutions) const; bool is_ir_calibration_profile() const; // used in method get_max_resolution per stream std::map<rs2_stream, std::vector<std::pair<int, int>>> resolutions_per_stream; const float SHORT_RANGE_MIN_DISTANCE = 0.05f; // 5 cm const float SHORT_RANGE_MAX_DISTANCE = 4.0f; // 4 meters std::atomic_bool _destructing; }; }