Improvements of assigning the layer span to the layer slider

on slice update.
This commit is contained in:
bubnikv 2018-12-20 10:55:50 +01:00
parent 5553d10c1e
commit 5632279213
4 changed files with 88 additions and 59 deletions

View File

@ -214,7 +214,6 @@ Preview::Preview(wxNotebook* notebook, DynamicPrintConfig* config, BackgroundSli
, m_preferred_color_mode("feature")
, m_loaded(false)
, m_enabled(false)
, m_force_sliders_full_range(false)
, m_schedule_background_process(schedule_background_process_func)
{
#if ENABLE_REMOVE_TABS_FROM_PLATER
@ -514,14 +513,14 @@ void Preview::show_hide_ui_elements(const std::string& what)
void Preview::reset_sliders()
{
m_enabled = false;
reset_double_slider();
// reset_double_slider();
m_double_slider_sizer->Hide((size_t)0);
}
void Preview::update_sliders(const std::vector<double>& layers_z)
{
m_enabled = true;
update_double_slider(layers_z, m_force_sliders_full_range);
update_double_slider(layers_z);
m_double_slider_sizer->Show((size_t)0);
Layout();
}
@ -597,26 +596,70 @@ void Preview::create_double_slider()
});
}
// Find an index of a value in a sorted vector, which is in <z-eps, z+eps>.
// Returns -1 if there is no such member.
static int find_close_layer_idx(const std::vector<double>& zs, double &z, double eps)
{
if (zs.empty())
return -1;
auto it_h = std::lower_bound(zs.begin(), zs.end(), z);
if (it_h == zs.end()) {
auto it_l = it_h;
-- it_l;
if (z - *it_l < eps)
return int(zs.size() - 1);
} else if (it_h == zs.begin()) {
if (*it_h - z < eps)
return 0;
} else {
auto it_l = it_h;
-- it_l;
double dist_l = z - *it_l;
double dist_h = *it_h - z;
if (std::min(dist_l, dist_h) < eps) {
return (dist_l < dist_h) ? int(it_l - zs.begin()) : int(it_h - zs.begin());
}
}
return -1;
}
void Preview::update_double_slider(const std::vector<double>& layers_z, bool force_sliders_full_range)
{
// Save the initial slider span.
double z_low = m_slider->GetLowerValueD();
double z_high = m_slider->GetHigherValueD();
bool was_empty = m_slider->GetMaxValue() == 0;
bool span_changed = layers_z.empty() || std::abs(layers_z.back() - m_slider->GetMaxValueD()) > 1e-6;
force_sliders_full_range |= was_empty | span_changed;
bool snap_to_min = force_sliders_full_range || m_slider->is_lower_at_min();
bool snap_to_max = force_sliders_full_range || m_slider->is_higher_at_max();
std::vector<std::pair<int, double>> values;
fill_slider_values(values, layers_z);
m_slider->SetMaxValue(layers_z.size() - 1);
if (force_sliders_full_range)
m_slider->SetHigherValue(layers_z.size() - 1);
m_slider->SetSliderValues(values);
const double z_low = m_slider->GetLowerValueD();
const double z_high = m_slider->GetHigherValueD();
assert(m_slider->GetMinValue() == 0);
m_slider->SetMaxValue(layers_z.empty() ? 0 : layers_z.size() - 1);
int idx_low = 0;
int idx_high = m_slider->GetMaxValue();
if (! layers_z.empty()) {
if (! snap_to_min) {
int idx_new = find_close_layer_idx(layers_z, z_low, 1e-6);
if (idx_new != -1)
idx_low = idx_new;
}
if (! snap_to_max) {
int idx_new = find_close_layer_idx(layers_z, z_high, 1e-6);
if (idx_new != -1)
idx_high = idx_new;
}
}
m_slider->SetSelectionSpan(idx_low, idx_high);
const auto& config = wxGetApp().preset_bundle->project_config;
const std::vector<double> &ticks_from_config = (config.option<ConfigOptionFloats>("colorprint_heights"))->values;
m_slider->SetTicksValues(ticks_from_config);
set_double_slider_thumbs(layers_z, z_low, z_high);
bool color_print_enable = (wxGetApp().plater()->printer_technology() == ptFFF);
if (color_print_enable) {
const auto& config = wxGetApp().preset_bundle->full_config();
@ -638,8 +681,7 @@ void Preview::fill_slider_values(std::vector<std::pair<int, double>> &values,
// All ticks that would end up outside the slider range should be erased.
// TODO: this should be placed into more appropriate part of code,
// this function is e.g. not called when the last object is deleted
auto& config = wxGetApp().preset_bundle->project_config;
std::vector<double> &ticks_from_config = (config.option<ConfigOptionFloats>("colorprint_heights"))->values;
std::vector<double> &ticks_from_config = (wxGetApp().preset_bundle->project_config.option<ConfigOptionFloats>("colorprint_heights"))->values;
unsigned int old_size = ticks_from_config.size();
ticks_from_config.erase(std::remove_if(ticks_from_config.begin(), ticks_from_config.end(),
[values](double val) { return values.back().second < val; }),
@ -648,32 +690,6 @@ void Preview::fill_slider_values(std::vector<std::pair<int, double>> &values,
m_schedule_background_process();
}
void Preview::set_double_slider_thumbs(const std::vector<double> &layers_z,
const double z_low,
const double z_high)
{
// Force slider full range only when slider is created.
// Support selected diapason on the all next steps
if (z_high == 0.0) {
m_slider->SetLowerValue(0);
m_slider->SetHigherValue(layers_z.size() - 1);
return;
}
for (int i = layers_z.size() - 1; i >= 0; i--)
// if (z_low >= layers_z[i]) {
if (fabs(z_low - layers_z[i]) <= 1e-6) {
m_slider->SetLowerValue(i);
break;
}
for (int i = layers_z.size() - 1; i >= 0; i--)
// if (z_high >= layers_z[i]) {
if (fabs(z_high-layers_z[i]) <= 1e-6) {
m_slider->SetHigherValue(i);
break;
}
}
void Preview::reset_double_slider()
{
m_slider->SetHigherValue(0);
@ -692,7 +708,7 @@ void Preview::update_double_slider_from_canvas(wxKeyEvent& event)
if (key == 'U' || key == 'D') {
const int new_pos = key == 'U' ? m_slider->GetHigherValue() + 1 : m_slider->GetHigherValue() - 1;
m_slider->SetHigherValue(new_pos);
if (event.ShiftDown()) m_slider->SetLowerValue(m_slider->GetHigherValue());
if (event.ShiftDown() || m_slider->is_one_layer()) m_slider->SetLowerValue(m_slider->GetHigherValue());
}
else if (key == 'S')
m_slider->ChangeOneLayerLock();
@ -778,12 +794,8 @@ void Preview::load_print_as_fff()
if (IsShown())
{
// used to set the sliders to the extremes of the current zs range
m_force_sliders_full_range = false;
if (gcode_preview_data_valid)
{
m_force_sliders_full_range = (m_canvas->get_volumes_count() == 0);
m_canvas->load_gcode_preview(*m_gcode_preview_data, colors);
show_hide_ui_elements("full");
@ -849,7 +861,6 @@ void Preview::load_print_as_sla()
{
std::vector<double> layer_zs;
std::copy(zs.begin(), zs.end(), std::back_inserter(layer_zs));
m_force_sliders_full_range = true;
update_sliders(layer_zs);
}

View File

@ -117,7 +117,6 @@ class Preview : public wxPanel
bool m_loaded;
bool m_enabled;
bool m_force_sliders_full_range;
PrusaDoubleSlider* m_slider {nullptr};
@ -177,12 +176,9 @@ private:
// Create/Update/Reset double slider on 3dPreview
void create_double_slider();
void update_double_slider(const std::vector<double>& layers_z, bool force_sliders_full_range);
void update_double_slider(const std::vector<double>& layers_z, bool force_sliders_full_range = false);
void fill_slider_values(std::vector<std::pair<int, double>> &values,
const std::vector<double> &layers_z);
void set_double_slider_thumbs( const std::vector<double> &layers_z,
const double z_low,
const double z_high);
void reset_double_slider();
// update DoubleSlider after keyDown in canvas
void update_double_slider_from_canvas(wxKeyEvent& event);

View File

@ -1506,6 +1506,21 @@ void PrusaDoubleSlider::SetHigherValue(const int higher_val)
ProcessWindowEvent(e);
}
void PrusaDoubleSlider::SetSelectionSpan(const int lower_val, const int higher_val)
{
m_lower_value = std::max(lower_val, m_min_value);
m_higher_value = std::max(std::min(higher_val, m_max_value), m_lower_value);
if (m_lower_value < m_higher_value)
m_is_one_layer = false;
Refresh();
Update();
wxCommandEvent e(wxEVT_SCROLL_CHANGED);
e.SetEventObject(this);
ProcessWindowEvent(e);
}
void PrusaDoubleSlider::SetMaxValue(const int max_value)
{
m_max_value = max_value;

View File

@ -697,18 +697,20 @@ public:
const wxString& name = wxEmptyString);
~PrusaDoubleSlider() {}
int GetLowerValue() const {
return m_lower_value;
}
int GetHigherValue() const {
return m_higher_value;
}
int GetMinValue() const { return m_min_value; }
int GetMaxValue() const { return m_max_value; }
double GetMinValueD() { return m_values.empty() ? 0. : m_values[m_min_value].second; }
double GetMaxValueD() { return m_values.empty() ? 0. : m_values[m_max_value].second; }
int GetLowerValue() const { return m_lower_value; }
int GetHigherValue() const { return m_higher_value; }
int GetActiveValue() const;
double GetLowerValueD() { return get_double_value(ssLower); }
double GetHigherValueD() { return get_double_value(ssHigher); }
wxSize DoGetBestSize() const override;
void SetLowerValue(const int lower_val);
void SetHigherValue(const int higher_val);
// Set low and high slider position. If the span is non-empty, disable the "one layer" mode.
void SetSelectionSpan(const int lower_val, const int higher_val);
void SetMaxValue(const int max_value);
void SetKoefForLabels(const double koef) {
m_label_koef = koef;
@ -726,6 +728,12 @@ public:
EnableTickManipulation(false);
}
bool is_horizontal() const { return m_style == wxSL_HORIZONTAL; }
bool is_one_layer() const { return m_is_one_layer; }
bool is_lower_at_min() const { return m_lower_value == m_min_value; }
bool is_higher_at_max() const { return m_higher_value == m_max_value; }
bool is_full_span() const { return this->is_lower_at_min() && this->is_higher_at_max(); }
void OnPaint(wxPaintEvent& ) { render();}
void OnLeftDown(wxMouseEvent& event);
void OnMotion(wxMouseEvent& event);
@ -762,7 +770,6 @@ protected:
bool is_point_in_rect(const wxPoint& pt, const wxRect& rect);
int is_point_near_tick(const wxPoint& pt);
bool is_horizontal() const { return m_style == wxSL_HORIZONTAL; }
double get_scroll_step();
wxString get_label(const SelectedSlider& selection) const;