Improvements of assigning the layer span to the layer slider
on slice update.
This commit is contained in:
parent
5553d10c1e
commit
5632279213
4 changed files with 88 additions and 59 deletions
|
@ -214,7 +214,6 @@ Preview::Preview(wxNotebook* notebook, DynamicPrintConfig* config, BackgroundSli
|
||||||
, m_preferred_color_mode("feature")
|
, m_preferred_color_mode("feature")
|
||||||
, m_loaded(false)
|
, m_loaded(false)
|
||||||
, m_enabled(false)
|
, m_enabled(false)
|
||||||
, m_force_sliders_full_range(false)
|
|
||||||
, m_schedule_background_process(schedule_background_process_func)
|
, m_schedule_background_process(schedule_background_process_func)
|
||||||
{
|
{
|
||||||
#if ENABLE_REMOVE_TABS_FROM_PLATER
|
#if ENABLE_REMOVE_TABS_FROM_PLATER
|
||||||
|
@ -514,14 +513,14 @@ void Preview::show_hide_ui_elements(const std::string& what)
|
||||||
void Preview::reset_sliders()
|
void Preview::reset_sliders()
|
||||||
{
|
{
|
||||||
m_enabled = false;
|
m_enabled = false;
|
||||||
reset_double_slider();
|
// reset_double_slider();
|
||||||
m_double_slider_sizer->Hide((size_t)0);
|
m_double_slider_sizer->Hide((size_t)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Preview::update_sliders(const std::vector<double>& layers_z)
|
void Preview::update_sliders(const std::vector<double>& layers_z)
|
||||||
{
|
{
|
||||||
m_enabled = true;
|
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);
|
m_double_slider_sizer->Show((size_t)0);
|
||||||
Layout();
|
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)
|
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;
|
std::vector<std::pair<int, double>> values;
|
||||||
fill_slider_values(values, layers_z);
|
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);
|
m_slider->SetSliderValues(values);
|
||||||
const double z_low = m_slider->GetLowerValueD();
|
assert(m_slider->GetMinValue() == 0);
|
||||||
const double z_high = m_slider->GetHigherValueD();
|
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 auto& config = wxGetApp().preset_bundle->project_config;
|
||||||
const std::vector<double> &ticks_from_config = (config.option<ConfigOptionFloats>("colorprint_heights"))->values;
|
const std::vector<double> &ticks_from_config = (config.option<ConfigOptionFloats>("colorprint_heights"))->values;
|
||||||
|
|
||||||
m_slider->SetTicksValues(ticks_from_config);
|
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);
|
bool color_print_enable = (wxGetApp().plater()->printer_technology() == ptFFF);
|
||||||
if (color_print_enable) {
|
if (color_print_enable) {
|
||||||
const auto& config = wxGetApp().preset_bundle->full_config();
|
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.
|
// All ticks that would end up outside the slider range should be erased.
|
||||||
// TODO: this should be placed into more appropriate part of code,
|
// TODO: this should be placed into more appropriate part of code,
|
||||||
// this function is e.g. not called when the last object is deleted
|
// 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 = (wxGetApp().preset_bundle->project_config.option<ConfigOptionFloats>("colorprint_heights"))->values;
|
||||||
std::vector<double> &ticks_from_config = (config.option<ConfigOptionFloats>("colorprint_heights"))->values;
|
|
||||||
unsigned int old_size = ticks_from_config.size();
|
unsigned int old_size = ticks_from_config.size();
|
||||||
ticks_from_config.erase(std::remove_if(ticks_from_config.begin(), ticks_from_config.end(),
|
ticks_from_config.erase(std::remove_if(ticks_from_config.begin(), ticks_from_config.end(),
|
||||||
[values](double val) { return values.back().second < val; }),
|
[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();
|
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()
|
void Preview::reset_double_slider()
|
||||||
{
|
{
|
||||||
m_slider->SetHigherValue(0);
|
m_slider->SetHigherValue(0);
|
||||||
|
@ -692,7 +708,7 @@ void Preview::update_double_slider_from_canvas(wxKeyEvent& event)
|
||||||
if (key == 'U' || key == 'D') {
|
if (key == 'U' || key == 'D') {
|
||||||
const int new_pos = key == 'U' ? m_slider->GetHigherValue() + 1 : m_slider->GetHigherValue() - 1;
|
const int new_pos = key == 'U' ? m_slider->GetHigherValue() + 1 : m_slider->GetHigherValue() - 1;
|
||||||
m_slider->SetHigherValue(new_pos);
|
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')
|
else if (key == 'S')
|
||||||
m_slider->ChangeOneLayerLock();
|
m_slider->ChangeOneLayerLock();
|
||||||
|
@ -778,12 +794,8 @@ void Preview::load_print_as_fff()
|
||||||
|
|
||||||
if (IsShown())
|
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)
|
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);
|
m_canvas->load_gcode_preview(*m_gcode_preview_data, colors);
|
||||||
show_hide_ui_elements("full");
|
show_hide_ui_elements("full");
|
||||||
|
|
||||||
|
@ -849,7 +861,6 @@ void Preview::load_print_as_sla()
|
||||||
{
|
{
|
||||||
std::vector<double> layer_zs;
|
std::vector<double> layer_zs;
|
||||||
std::copy(zs.begin(), zs.end(), std::back_inserter(layer_zs));
|
std::copy(zs.begin(), zs.end(), std::back_inserter(layer_zs));
|
||||||
m_force_sliders_full_range = true;
|
|
||||||
update_sliders(layer_zs);
|
update_sliders(layer_zs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -117,7 +117,6 @@ class Preview : public wxPanel
|
||||||
|
|
||||||
bool m_loaded;
|
bool m_loaded;
|
||||||
bool m_enabled;
|
bool m_enabled;
|
||||||
bool m_force_sliders_full_range;
|
|
||||||
|
|
||||||
PrusaDoubleSlider* m_slider {nullptr};
|
PrusaDoubleSlider* m_slider {nullptr};
|
||||||
|
|
||||||
|
@ -177,12 +176,9 @@ private:
|
||||||
|
|
||||||
// Create/Update/Reset double slider on 3dPreview
|
// Create/Update/Reset double slider on 3dPreview
|
||||||
void create_double_slider();
|
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,
|
void fill_slider_values(std::vector<std::pair<int, double>> &values,
|
||||||
const std::vector<double> &layers_z);
|
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();
|
void reset_double_slider();
|
||||||
// update DoubleSlider after keyDown in canvas
|
// update DoubleSlider after keyDown in canvas
|
||||||
void update_double_slider_from_canvas(wxKeyEvent& event);
|
void update_double_slider_from_canvas(wxKeyEvent& event);
|
||||||
|
|
|
@ -1506,6 +1506,21 @@ void PrusaDoubleSlider::SetHigherValue(const int higher_val)
|
||||||
ProcessWindowEvent(e);
|
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)
|
void PrusaDoubleSlider::SetMaxValue(const int max_value)
|
||||||
{
|
{
|
||||||
m_max_value = max_value;
|
m_max_value = max_value;
|
||||||
|
|
|
@ -697,18 +697,20 @@ public:
|
||||||
const wxString& name = wxEmptyString);
|
const wxString& name = wxEmptyString);
|
||||||
~PrusaDoubleSlider() {}
|
~PrusaDoubleSlider() {}
|
||||||
|
|
||||||
int GetLowerValue() const {
|
int GetMinValue() const { return m_min_value; }
|
||||||
return m_lower_value;
|
int GetMaxValue() const { return m_max_value; }
|
||||||
}
|
double GetMinValueD() { return m_values.empty() ? 0. : m_values[m_min_value].second; }
|
||||||
int GetHigherValue() const {
|
double GetMaxValueD() { return m_values.empty() ? 0. : m_values[m_max_value].second; }
|
||||||
return m_higher_value;
|
int GetLowerValue() const { return m_lower_value; }
|
||||||
}
|
int GetHigherValue() const { return m_higher_value; }
|
||||||
int GetActiveValue() const;
|
int GetActiveValue() const;
|
||||||
double GetLowerValueD() { return get_double_value(ssLower); }
|
double GetLowerValueD() { return get_double_value(ssLower); }
|
||||||
double GetHigherValueD() { return get_double_value(ssHigher); }
|
double GetHigherValueD() { return get_double_value(ssHigher); }
|
||||||
wxSize DoGetBestSize() const override;
|
wxSize DoGetBestSize() const override;
|
||||||
void SetLowerValue(const int lower_val);
|
void SetLowerValue(const int lower_val);
|
||||||
void SetHigherValue(const int higher_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 SetMaxValue(const int max_value);
|
||||||
void SetKoefForLabels(const double koef) {
|
void SetKoefForLabels(const double koef) {
|
||||||
m_label_koef = koef;
|
m_label_koef = koef;
|
||||||
|
@ -726,6 +728,12 @@ public:
|
||||||
EnableTickManipulation(false);
|
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 OnPaint(wxPaintEvent& ) { render();}
|
||||||
void OnLeftDown(wxMouseEvent& event);
|
void OnLeftDown(wxMouseEvent& event);
|
||||||
void OnMotion(wxMouseEvent& event);
|
void OnMotion(wxMouseEvent& event);
|
||||||
|
@ -762,7 +770,6 @@ protected:
|
||||||
|
|
||||||
bool is_point_in_rect(const wxPoint& pt, const wxRect& rect);
|
bool is_point_in_rect(const wxPoint& pt, const wxRect& rect);
|
||||||
int is_point_near_tick(const wxPoint& pt);
|
int is_point_near_tick(const wxPoint& pt);
|
||||||
bool is_horizontal() const { return m_style == wxSL_HORIZONTAL; }
|
|
||||||
|
|
||||||
double get_scroll_step();
|
double get_scroll_step();
|
||||||
wxString get_label(const SelectedSlider& selection) const;
|
wxString get_label(const SelectedSlider& selection) const;
|
||||||
|
|
Loading…
Reference in a new issue