mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-13 09:47:58 -06:00
Fix of #6232 - Layer preview number scale and print time problem.
Problem description: When "Print Settings -> Multiple Extruders -> No sparse layer" is enabled, then "Smart" Wipe Tower is used for wiping. As a result, each layer with tool changes is splited for min 3 parts: first tool, wiping, second tool ... But vertical slider wasn't respect to this case.
This commit is contained in:
parent
eda19a7e56
commit
995512f280
2 changed files with 77 additions and 5 deletions
|
@ -328,7 +328,12 @@ double Control::get_double_value(const SelectedSlider& selection)
|
||||||
|
|
||||||
int Control::get_tick_from_value(double value)
|
int Control::get_tick_from_value(double value)
|
||||||
{
|
{
|
||||||
auto it = std::lower_bound(m_values.begin(), m_values.end(), value - epsilon());
|
std::vector<double>::iterator it;
|
||||||
|
if (m_is_smart_wipe_tower)
|
||||||
|
it = std::find_if(m_values.begin(), m_values.end(),
|
||||||
|
[value](const double & val) { return fabs(value - val) <= epsilon(); });
|
||||||
|
else
|
||||||
|
it = std::lower_bound(m_values.begin(), m_values.end(), value - epsilon());
|
||||||
|
|
||||||
if (it == m_values.end())
|
if (it == m_values.end())
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -391,6 +396,16 @@ void Control::SetLayersTimes(const std::vector<float>& layers_times)
|
||||||
m_layers_times[0] = layers_times[0];
|
m_layers_times[0] = layers_times[0];
|
||||||
for (size_t i = 1; i < layers_times.size(); i++)
|
for (size_t i = 1; i < layers_times.size(); i++)
|
||||||
m_layers_times[i] = m_layers_times[i - 1] + layers_times[i];
|
m_layers_times[i] = m_layers_times[i - 1] + layers_times[i];
|
||||||
|
|
||||||
|
// Erase duplicates values from m_values and save it to the m_layers_values
|
||||||
|
// They will be used for show the correct estimated time for MM print, when "No sparce layer" is enabled
|
||||||
|
// See https://github.com/prusa3d/PrusaSlicer/issues/6232
|
||||||
|
m_is_smart_wipe_tower = m_values.size() != m_layers_times.size();
|
||||||
|
if (m_is_smart_wipe_tower) {
|
||||||
|
m_layers_values = m_values;
|
||||||
|
sort(m_layers_values.begin(), m_layers_values.end());
|
||||||
|
m_layers_values.erase(unique(m_layers_values.begin(), m_layers_values.end()), m_layers_values.end());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Control::SetLayersTimes(const std::vector<double>& layers_times)
|
void Control::SetLayersTimes(const std::vector<double>& layers_times)
|
||||||
|
@ -511,6 +526,18 @@ void Control::render()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Control::is_wipe_tower_layer(int tick) const
|
||||||
|
{
|
||||||
|
if (!m_is_smart_wipe_tower || tick >= (int)m_values.size())
|
||||||
|
return false;
|
||||||
|
if (tick == 0 || (tick == (int)m_values.size() - 1 && m_values[tick] > m_values[tick - 1]))
|
||||||
|
return false;
|
||||||
|
if (m_values[tick - 1] == m_values[tick + 1] && m_values[tick] < m_values[tick + 1])
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Control::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end)
|
void Control::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_end)
|
||||||
{
|
{
|
||||||
const int tick = m_selection == ssLower ? m_lower_value : m_higher_value;
|
const int tick = m_selection == ssLower ? m_lower_value : m_higher_value;
|
||||||
|
@ -522,6 +549,11 @@ void Control::draw_action_icon(wxDC& dc, const wxPoint pt_beg, const wxPoint pt_
|
||||||
if (tick == 0)
|
if (tick == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (is_wipe_tower_layer(tick)) {
|
||||||
|
m_rect_tick_action = wxRect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
wxBitmap* icon = m_focus == fiActionIcon ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp();
|
wxBitmap* icon = m_focus == fiActionIcon ? &m_bmp_add_tick_off.bmp() : &m_bmp_add_tick_on.bmp();
|
||||||
if (m_ticks.ticks.find(TickCode{tick}) != m_ticks.ticks.end())
|
if (m_ticks.ticks.find(TickCode{tick}) != m_ticks.ticks.end())
|
||||||
icon = m_focus == fiActionIcon ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp();
|
icon = m_focus == fiActionIcon ? &m_bmp_del_tick_off.bmp() : &m_bmp_del_tick_on.bmp();
|
||||||
|
@ -670,6 +702,21 @@ wxString Control::get_label(int tick, LabelType label_type/* = ltHeightWithLayer
|
||||||
if (value >= m_values.size())
|
if (value >= m_values.size())
|
||||||
return "ErrVal";
|
return "ErrVal";
|
||||||
|
|
||||||
|
// When "Print Settings -> Multiple Extruders -> No sparse layer" is enabled, then "Smart" Wipe Tower is used for wiping.
|
||||||
|
// As a result, each layer with tool changes is splited for min 3 parts: first tool, wiping, second tool ...
|
||||||
|
// So, vertical slider have to respect to this case.
|
||||||
|
// see https://github.com/prusa3d/PrusaSlicer/issues/6232.
|
||||||
|
// m_values contains data for all layer's parts,
|
||||||
|
// but m_layers_values contains just unique Z values.
|
||||||
|
// Use this function for correct conversion slider position to number of printed layer
|
||||||
|
auto get_layer_number = [this](int value) {
|
||||||
|
double layer_print_z = m_values[is_wipe_tower_layer(value) ? std::max<int>(value - 1, 0) : value];
|
||||||
|
auto it = std::lower_bound(m_layers_values.begin(), m_layers_values.end(), layer_print_z - epsilon());
|
||||||
|
if (it == m_layers_values.end())
|
||||||
|
return -1;
|
||||||
|
return int(it - m_layers_values.begin());
|
||||||
|
};
|
||||||
|
|
||||||
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
#if ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||||
if (m_draw_mode == dmSequentialGCodeView) {
|
if (m_draw_mode == dmSequentialGCodeView) {
|
||||||
return (Slic3r::GUI::get_app_config()->get("seq_top_gcode_indices") == "1") ?
|
return (Slic3r::GUI::get_app_config()->get("seq_top_gcode_indices") == "1") ?
|
||||||
|
@ -682,15 +729,21 @@ wxString Control::get_label(int tick, LabelType label_type/* = ltHeightWithLayer
|
||||||
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
#endif // ENABLE_GCODE_LINES_ID_IN_H_SLIDER
|
||||||
else {
|
else {
|
||||||
if (label_type == ltEstimatedTime) {
|
if (label_type == ltEstimatedTime) {
|
||||||
return (value < m_layers_times.size()) ? short_and_splitted_time(get_time_dhms(m_layers_times[value])) : "";
|
if (m_is_smart_wipe_tower) {
|
||||||
|
int layer_number = get_layer_number(value);
|
||||||
|
return layer_number < 0 ? "" : short_and_splitted_time(get_time_dhms(m_layers_times[layer_number]));
|
||||||
|
}
|
||||||
|
return value < m_layers_times.size() ? short_and_splitted_time(get_time_dhms(m_layers_times[value])) : "";
|
||||||
}
|
}
|
||||||
wxString str = m_values.empty() ?
|
wxString str = m_values.empty() ?
|
||||||
wxString::Format("%.*f", 2, m_label_koef * value) :
|
wxString::Format("%.*f", 2, m_label_koef * value) :
|
||||||
wxString::Format("%.*f", 2, m_values[value]);
|
wxString::Format("%.*f", 2, m_values[value]);
|
||||||
if (label_type == ltHeight)
|
if (label_type == ltHeight)
|
||||||
return str;
|
return str;
|
||||||
if (label_type == ltHeightWithLayer)
|
if (label_type == ltHeightWithLayer) {
|
||||||
return format_wxstr("%1%\n(%2%)", str, m_values.empty() ? value : value + 1);
|
size_t layer_number = m_is_smart_wipe_tower ? (size_t)get_layer_number(value) : (m_values.empty() ? value : value + 1);
|
||||||
|
return format_wxstr("%1%\n(%2%)", str, layer_number);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxEmptyString;
|
return wxEmptyString;
|
||||||
|
@ -725,10 +778,17 @@ void Control::draw_tick_text(wxDC& dc, const wxPoint& pos, int tick, LabelType l
|
||||||
text_pos = wxPoint(std::max(2, pos.x - text_width - 1 - m_thumb_size.x), pos.y - 0.5 * text_height + 1);
|
text_pos = wxPoint(std::max(2, pos.x - text_width - 1 - m_thumb_size.x), pos.y - 0.5 * text_height + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxColour old_clr = dc.GetTextForeground();
|
||||||
|
const wxPen& pen = is_wipe_tower_layer(tick) && (tick == m_lower_value || tick == m_higher_value) ? DARK_ORANGE_PEN : wxPen(old_clr);
|
||||||
|
dc.SetPen(pen);
|
||||||
|
dc.SetTextForeground(pen.GetColour());
|
||||||
|
|
||||||
if (label_type == ltEstimatedTime)
|
if (label_type == ltEstimatedTime)
|
||||||
dc.DrawLabel(label, wxRect(text_pos, wxSize(text_width, text_height)), wxALIGN_RIGHT);
|
dc.DrawLabel(label, wxRect(text_pos, wxSize(text_width, text_height)), wxALIGN_RIGHT);
|
||||||
else
|
else
|
||||||
dc.DrawText(label, text_pos);
|
dc.DrawText(label, text_pos);
|
||||||
|
|
||||||
|
dc.SetTextForeground(old_clr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Control::draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const
|
void Control::draw_thumb_text(wxDC& dc, const wxPoint& pos, const SelectedSlider& selection) const
|
||||||
|
@ -1291,6 +1351,8 @@ wxString Control::get_tooltip(int tick/*=-1*/)
|
||||||
if (m_focus == fiColorBand)
|
if (m_focus == fiColorBand)
|
||||||
return m_mode != SingleExtruder ? "" :
|
return m_mode != SingleExtruder ? "" :
|
||||||
_L("Edit current color - Right click the colored slider segment");
|
_L("Edit current color - Right click the colored slider segment");
|
||||||
|
if (m_focus == fiSmartWipeTower)
|
||||||
|
return _L("This is wipe tower layer");
|
||||||
if (m_draw_mode == dmSlaPrint)
|
if (m_draw_mode == dmSlaPrint)
|
||||||
return ""; // no drawn ticks and no tooltips for them in SlaPrinting mode
|
return ""; // no drawn ticks and no tooltips for them in SlaPrinting mode
|
||||||
|
|
||||||
|
@ -1424,8 +1486,14 @@ void Control::OnMotion(wxMouseEvent& event)
|
||||||
else if (is_point_in_rect(pos, m_rect_higher_thumb))
|
else if (is_point_in_rect(pos, m_rect_higher_thumb))
|
||||||
m_focus = fiHigherThumb;
|
m_focus = fiHigherThumb;
|
||||||
else {
|
else {
|
||||||
m_focus = fiTick;
|
|
||||||
tick = get_tick_near_point(pos);
|
tick = get_tick_near_point(pos);
|
||||||
|
if (tick < 0 && m_is_smart_wipe_tower) {
|
||||||
|
tick = get_value_from_position(pos);
|
||||||
|
m_focus = tick > 0 && is_wipe_tower_layer(tick) && (tick == m_lower_value || tick == m_higher_value) ?
|
||||||
|
fiSmartWipeTower : fiTick;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_focus = fiTick;
|
||||||
}
|
}
|
||||||
m_moving_pos = pos;
|
m_moving_pos = pos;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ enum FocusedItem {
|
||||||
fiActionIcon,
|
fiActionIcon,
|
||||||
fiLowerThumb,
|
fiLowerThumb,
|
||||||
fiHigherThumb,
|
fiHigherThumb,
|
||||||
|
fiSmartWipeTower,
|
||||||
fiTick
|
fiTick
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -305,6 +306,7 @@ protected:
|
||||||
void correct_higher_value();
|
void correct_higher_value();
|
||||||
void move_current_thumb(const bool condition);
|
void move_current_thumb(const bool condition);
|
||||||
void enter_window(wxMouseEvent& event, const bool enter);
|
void enter_window(wxMouseEvent& event, const bool enter);
|
||||||
|
bool is_wipe_tower_layer(int tick) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -368,6 +370,7 @@ private:
|
||||||
bool m_is_focused = false;
|
bool m_is_focused = false;
|
||||||
bool m_force_mode_apply = true;
|
bool m_force_mode_apply = true;
|
||||||
bool m_enable_action_icon = true;
|
bool m_enable_action_icon = true;
|
||||||
|
bool m_is_smart_wipe_tower = false; //This flag indicates that for current print is used "smart" wipe tower (Print Settings->Multiple Extruders->No sparse layer is enabled)
|
||||||
|
|
||||||
DrawMode m_draw_mode = dmRegular;
|
DrawMode m_draw_mode = dmRegular;
|
||||||
|
|
||||||
|
@ -396,6 +399,7 @@ private:
|
||||||
std::vector<double> m_values;
|
std::vector<double> m_values;
|
||||||
TickCodeInfo m_ticks;
|
TickCodeInfo m_ticks;
|
||||||
std::vector<double> m_layers_times;
|
std::vector<double> m_layers_times;
|
||||||
|
std::vector<double> m_layers_values;
|
||||||
std::vector<std::string> m_extruder_colors;
|
std::vector<std::string> m_extruder_colors;
|
||||||
std::string m_print_obj_idxs;
|
std::string m_print_obj_idxs;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue