ENH: custom gcode info should be owned by every plate

Change-Id: I5e5b000b7d04354d3c3cc311d089cb591a37501e
This commit is contained in:
liz.li 2023-02-01 17:38:02 +08:00 committed by Lane.Wei
parent 5f71eba979
commit e7ea07944f
16 changed files with 545 additions and 680 deletions

View file

@ -4691,7 +4691,8 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
}
case EViewType::ColorPrint:
{
const std::vector<CustomGCode::Item>& custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes : m_custom_gcode_per_print_z;
//BBS: replace model custom gcode with current plate custom gcode
const std::vector<CustomGCode::Item>& custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes : m_custom_gcode_per_print_z;
size_t total_items = 1;
for (size_t extruder_id : m_extruder_ids) {
total_items += color_print_ranges(extruder_id, custom_gcode_per_print_z).size();
@ -4873,7 +4874,8 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
auto generate_partial_times = [this, get_used_filament_from_volume](const TimesList& times, const std::vector<double>& used_filaments) {
PartialTimes items;
std::vector<CustomGCode::Item> custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes : m_custom_gcode_per_print_z;
//BBS: replace model custom gcode with current plate custom gcode
std::vector<CustomGCode::Item> custom_gcode_per_print_z = wxGetApp().is_editor() ? wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes : m_custom_gcode_per_print_z;
std::vector<Color> last_color(m_extruders_count);
for (size_t i = 0; i < m_extruders_count; ++i) {
last_color[i] = m_tools.m_tool_colors[i];

View file

@ -551,15 +551,16 @@ void Preview::update_layers_slider(const std::vector<double>& layers_z, bool kee
// Detect and set manipulation mode for double slider
update_layers_slider_mode();
Plater * plater = wxGetApp().plater();
CustomGCode::Info ticks_info_from_model;
Plater* plater = wxGetApp().plater();
//BBS: replace model custom gcode with current plate custom gcode
CustomGCode::Info ticks_info_from_curr_plate;
if (wxGetApp().is_editor())
ticks_info_from_model = plater->model().custom_gcode_per_print_z;
ticks_info_from_curr_plate = plater->model().get_curr_plate_custom_gcodes();
else {
ticks_info_from_model.mode = CustomGCode::Mode::SingleExtruder;
ticks_info_from_model.gcodes = m_canvas->get_custom_gcode_per_print_z();
ticks_info_from_curr_plate.mode = CustomGCode::Mode::SingleExtruder;
ticks_info_from_curr_plate.gcodes = m_canvas->get_custom_gcode_per_print_z();
}
check_layers_slider_values(ticks_info_from_model.gcodes, layers_z);
check_layers_slider_values(ticks_info_from_curr_plate.gcodes, layers_z);
// first of all update extruder colors to avoid crash, when we are switching printer preset from MM to SM
m_layers_slider->SetExtruderColors(plater->get_extruder_colors_from_plater_config(wxGetApp().is_editor() ? nullptr : m_gcode_result));
@ -580,7 +581,7 @@ void Preview::update_layers_slider(const std::vector<double>& layers_z, bool kee
}
}
m_layers_slider->SetSelectionSpan(idx_low, idx_high);
m_layers_slider->SetTicksValues(ticks_info_from_model);
m_layers_slider->SetTicksValues(ticks_info_from_curr_plate);
auto curr_plate = wxGetApp().plater()->get_partplate_list().get_curr_plate();
auto curr_print_seq = curr_plate->get_real_print_seq();
@ -689,7 +690,8 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode)
if (!gcode_preview_data_valid) {
if (wxGetApp().is_editor())
color_print_values = wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes;
//BBS
color_print_values = wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes;
else
color_print_values = m_canvas->get_custom_gcode_per_print_z();
colors.push_back("#808080"); // gray color for pause print or custom G-code
@ -735,7 +737,8 @@ void Preview::load_print_as_fff(bool keep_z_range, bool only_gcode)
(unsigned int)print->extruders().size() :
m_canvas->get_gcode_extruders_count();
std::vector<Item> gcodes = wxGetApp().is_editor() ?
wxGetApp().plater()->model().custom_gcode_per_print_z.gcodes :
//BBS
wxGetApp().plater()->model().get_curr_plate_custom_gcodes().gcodes :
m_canvas->get_custom_gcode_per_print_z();
const wxString choice = !gcodes.empty() ?
_L("Multicolor Print") :

View file

@ -1,22 +1,6 @@
#include "libslic3r/libslic3r.h"
#include "IMSlider.hpp"
#include "libslic3r/GCode.hpp"
#include "GUI.hpp"
#include "GUI_App.hpp"
#include "Plater.hpp"
#include "I18N.hpp"
#include "libslic3r/Print.hpp"
#include "libslic3r/AppConfig.hpp"
#include "GUI_Utils.hpp"
#include "MsgDialog.hpp"
#include "Tab.hpp"
#include "GUI_ObjectList.hpp"
#include <cmath>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/split.hpp>
#include "Field.hpp"
#include "format.hpp"
#include "NotificationManager.hpp"
#ifndef IMGUI_DEFINE_MATH_OPERATORS
#define IMGUI_DEFINE_MATH_OPERATORS
@ -25,10 +9,6 @@
namespace Slic3r {
using GUI::from_u8;
using GUI::into_u8;
using GUI::format_wxstr;
namespace GUI {
constexpr double min_delta_area = scale_(scale_(25)); // equal to 25 mm2
@ -136,292 +116,6 @@ static std::string short_and_splitted_time(const std::string &time)
}
std::string TickCodeInfo::get_color_for_tick(TickCode tick, Type type, const int extruder)
{
if (mode == SingleExtruder && type == ColorChange && m_use_default_colors) {
#if 1
if (ticks.empty()) return color_generator.get_opposite_color((*m_colors)[0]);
auto before_tick_it = std::lower_bound(ticks.begin(), ticks.end(), tick);
if (before_tick_it == ticks.end()) {
while (before_tick_it != ticks.begin())
if (--before_tick_it; before_tick_it->type == ColorChange) break;
if (before_tick_it->type == ColorChange) return color_generator.get_opposite_color(before_tick_it->color);
return color_generator.get_opposite_color((*m_colors)[0]);
}
if (before_tick_it == ticks.begin()) {
const std::string &frst_color = (*m_colors)[0];
if (before_tick_it->type == ColorChange) return color_generator.get_opposite_color(frst_color, before_tick_it->color);
auto next_tick_it = before_tick_it;
while (next_tick_it != ticks.end())
if (++next_tick_it; next_tick_it->type == ColorChange) break;
if (next_tick_it->type == ColorChange) return color_generator.get_opposite_color(frst_color, next_tick_it->color);
return color_generator.get_opposite_color(frst_color);
}
std::string frst_color = "";
if (before_tick_it->type == ColorChange)
frst_color = before_tick_it->color;
else {
auto next_tick_it = before_tick_it;
while (next_tick_it != ticks.end())
if (++next_tick_it; next_tick_it->type == ColorChange) {
frst_color = next_tick_it->color;
break;
}
}
while (before_tick_it != ticks.begin())
if (--before_tick_it; before_tick_it->type == ColorChange) break;
if (before_tick_it->type == ColorChange) {
if (frst_color.empty()) return color_generator.get_opposite_color(before_tick_it->color);
return color_generator.get_opposite_color(before_tick_it->color, frst_color);
}
if (frst_color.empty()) return color_generator.get_opposite_color((*m_colors)[0]);
return color_generator.get_opposite_color((*m_colors)[0], frst_color);
#else
const std::vector<std::string> &colors = ColorPrintColors::get();
if (ticks.empty()) return colors[0];
m_default_color_idx++;
return colors[m_default_color_idx % colors.size()];
#endif
}
std::string color = (*m_colors)[extruder - 1];
if (type == ColorChange) {
if (!ticks.empty()) {
auto before_tick_it = std::lower_bound(ticks.begin(), ticks.end(), tick);
while (before_tick_it != ticks.begin()) {
--before_tick_it;
if (before_tick_it->type == ColorChange && before_tick_it->extruder == extruder) {
color = before_tick_it->color;
break;
}
}
}
//TODO
//color = get_new_color(color);
}
return color;
}
bool TickCodeInfo::add_tick(const int tick, Type type, const int extruder, double print_z)
{
std::string color;
std::string extra;
if (type == Custom) // custom Gcode
{
//extra = get_custom_code(custom_gcode, print_z);
//if (extra.empty()) return false;
//custom_gcode = extra;
} else if (type == PausePrint) {
//BBS do not set pause extra message
//extra = get_pause_print_msg(pause_print_msg, print_z);
//if (extra.empty()) return false;
pause_print_msg = extra;
}
else {
color = get_color_for_tick(TickCode{ tick }, type, extruder);
if (color.empty()) return false;
}
if (mode == SingleExtruder) m_use_default_colors = true;
ticks.emplace(TickCode{tick, type, extruder, color, extra});
return true;
}
bool TickCodeInfo::edit_tick(std::set<TickCode>::iterator it, double print_z)
{
std::string edited_value;
//TODO
/* BBS
if (it->type == ColorChange)
edited_value = get_new_color(it->color);
else if (it->type == PausePrint)
edited_value = get_pause_print_msg(it->extra, print_z);
else
edited_value = get_custom_code(it->type == Template ? gcode(Template) : it->extra, print_z);
*/
if (edited_value.empty()) return false;
TickCode changed_tick = *it;
if (it->type == ColorChange) {
if (it->color == edited_value) return false;
changed_tick.color = edited_value;
} else if (it->type == Template) {
//if (gcode(Template) == edited_value) return false;
//changed_tick.extra = edited_value;
//changed_tick.type = Custom;
;
} else if (it->type == Custom || it->type == PausePrint) {
if (it->extra == edited_value) return false;
changed_tick.extra = edited_value;
}
ticks.erase(it);
ticks.emplace(changed_tick);
return true;
}
void TickCodeInfo::switch_code(Type type_from, Type type_to)
{
for (auto it{ticks.begin()}, end{ticks.end()}; it != end;)
if (it->type == type_from) {
TickCode tick = *it;
tick.type = type_to;
tick.extruder = 1;
ticks.erase(it);
it = ticks.emplace(tick).first;
} else
++it;
}
bool TickCodeInfo::switch_code_for_tick(std::set<TickCode>::iterator it, Type type_to, const int extruder)
{
const std::string color = get_color_for_tick(*it, type_to, extruder);
if (color.empty()) return false;
TickCode changed_tick = *it;
changed_tick.type = type_to;
changed_tick.extruder = extruder;
changed_tick.color = color;
ticks.erase(it);
ticks.emplace(changed_tick);
return true;
}
void TickCodeInfo::erase_all_ticks_with_code(Type type)
{
for (auto it{ticks.begin()}, end{ticks.end()}; it != end;) {
if (it->type == type)
it = ticks.erase(it);
else
++it;
}
}
bool TickCodeInfo::has_tick_with_code(Type type)
{
for (const TickCode &tick : ticks)
if (tick.type == type) return true;
return false;
}
bool TickCodeInfo::has_tick(int tick) { return ticks.find(TickCode{tick}) != ticks.end(); }
ConflictType TickCodeInfo::is_conflict_tick(const TickCode &tick, Mode out_mode, int only_extruder, double print_z)
{
if ((tick.type == ColorChange && ((mode == SingleExtruder && out_mode == MultiExtruder) || (mode == MultiExtruder && out_mode == SingleExtruder))) ||
(tick.type == ToolChange && (mode == MultiAsSingle && out_mode != MultiAsSingle)))
return ctModeConflict;
// check ColorChange tick
if (tick.type == ColorChange) {
// We should mark a tick as a "MeaninglessColorChange",
// if it has a ColorChange for unused extruder from current print to end of the print
std::set<int> used_extruders_for_tick = get_used_extruders_for_tick(tick.tick, only_extruder, print_z, out_mode);
if (used_extruders_for_tick.find(tick.extruder) == used_extruders_for_tick.end()) return ctMeaninglessColorChange;
// We should mark a tick as a "Redundant",
// if it has a ColorChange for extruder that has not been used before
if (mode == MultiAsSingle && tick.extruder != std::max<int>(only_extruder, 1)) {
auto it = ticks.lower_bound(tick);
if (it == ticks.begin() && it->type == ToolChange && tick.extruder == it->extruder) return ctNone;
while (it != ticks.begin()) {
--it;
if (it->type == ToolChange && tick.extruder == it->extruder) return ctNone;
}
return ctRedundant;
}
}
// check ToolChange tick
if (mode == MultiAsSingle && tick.type == ToolChange) {
// We should mark a tick as a "MeaninglessToolChange",
// if it has a ToolChange to the same extruder
auto it = ticks.find(tick);
if (it == ticks.begin()) return tick.extruder == std::max<int>(only_extruder, 1) ? ctMeaninglessToolChange : ctNone;
while (it != ticks.begin()) {
--it;
if (it->type == ToolChange) return tick.extruder == it->extruder ? ctMeaninglessToolChange : ctNone;
}
}
return ctNone;
}
// Get used extruders for tick.
// Means all extruders(tools) which will be used during printing from current tick to the end
std::set<int> TickCodeInfo::get_used_extruders_for_tick(int tick, int only_extruder, double print_z, Mode force_mode /* = Undef*/) const
{
Mode e_mode = !force_mode ? mode : force_mode;
if (e_mode == MultiExtruder) {
// #ys_FIXME: get tool ordering from _correct_ place
const ToolOrdering &tool_ordering = GUI::wxGetApp().plater()->fff_print().get_tool_ordering();
if (tool_ordering.empty()) return {};
std::set<int> used_extruders;
auto it_layer_tools = std::lower_bound(tool_ordering.begin(), tool_ordering.end(), LayerTools(print_z));
for (; it_layer_tools != tool_ordering.end(); ++it_layer_tools) {
const std::vector<unsigned> &extruders = it_layer_tools->extruders;
for (const auto &extruder : extruders) used_extruders.emplace(extruder + 1);
}
return used_extruders;
}
const int default_initial_extruder = e_mode == MultiAsSingle ? std::max(only_extruder, 1) : 1;
if (ticks.empty() || e_mode == SingleExtruder) return {default_initial_extruder};
std::set<int> used_extruders;
auto it_start = ticks.lower_bound(TickCode{tick});
auto it = it_start;
if (it == ticks.begin() && it->type == ToolChange && tick != it->tick) // In case of switch of ToolChange to ColorChange, when tick exists,
// we shouldn't change color for extruder, which will be deleted
{
used_extruders.emplace(it->extruder);
if (tick < it->tick) used_extruders.emplace(default_initial_extruder);
}
while (it != ticks.begin()) {
--it;
if (it->type == ToolChange && tick != it->tick) {
used_extruders.emplace(it->extruder);
break;
}
}
if (it == ticks.begin() && used_extruders.empty()) used_extruders.emplace(default_initial_extruder);
for (it = it_start; it != ticks.end(); ++it)
if (it->type == ToolChange && tick != it->tick) used_extruders.emplace(it->extruder);
return used_extruders;
}
IMSlider::IMSlider(int lowerValue, int higherValue, int minValue, int maxValue, long style)
{
m_lower_value = lowerValue;
@ -521,11 +215,6 @@ Info IMSlider::GetTicksValues() const
void IMSlider::SetTicksValues(const Info &custom_gcode_per_print_z)
{
if (!m_can_change_color) {
m_ticks.erase_all_ticks_with_code(ToolChange);
return;
}
if (m_values.empty()) {
m_ticks.mode = m_mode;
return;
@ -542,10 +231,12 @@ void IMSlider::SetTicksValues(const Info &custom_gcode_per_print_z)
if (!was_empty && m_ticks.empty())
// Switch to the "Feature type"/"Tool" from the very beginning of a new object slicing after deleting of the old one
post_ticks_changed_event();
;// post_ticks_changed_event();
// init extruder sequence in respect to the extruders count
if (m_ticks.empty()) m_extruders_sequence.init(m_extruder_colors.size());
if (m_ticks.has_tick_with_code(ToolChange) && !m_can_change_color) {
m_ticks.erase_all_ticks_with_code(ToolChange);
post_ticks_changed_event();
}
if (custom_gcode_per_print_z.mode && !custom_gcode_per_print_z.gcodes.empty()) m_ticks.mode = custom_gcode_per_print_z.mode;
@ -955,10 +646,6 @@ void IMSlider::draw_ticks(const ImRect& slideable_region) {
ImTextureID pause_icon_id = m_pause_icon_id;
ImVec2 icon_pos = ImVec2(slideable_region.GetCenter().x + icon_offset.x, tick_pos - icon_offset.y);
button_with_pos(pause_icon_id, icon_size, icon_pos);
if (ImGui::IsMouseHoveringRect(icon_pos, icon_pos + icon_size)) {
if(context.IO.MouseClicked[0])
int a = 0;
}
}
++tick_it;
}
@ -968,7 +655,6 @@ void IMSlider::draw_ticks(const ImRect& slideable_region) {
m_ticks.ticks.end();
if (tick_it != m_ticks.ticks.end()) {
// draw delete icon
ImTextureID delete_icon_id = m_delete_icon_id;
ImVec2 icon_pos = ImVec2(slideable_region.GetCenter().x + icon_offset.x, get_tick_pos(tick_it->tick) - icon_offset.y);
button_with_pos(m_delete_icon_id, icon_size, icon_pos);
if (ImGui::IsMouseHoveringRect(icon_pos, icon_pos + icon_size)) {
@ -1441,8 +1127,7 @@ void IMSlider::render_go_to_layer_dialog()
void IMSlider::render_menu()
{
ImGuiWrapper::push_menu_style(m_scale);
std::vector<std::string> colors = wxGetApp().plater()->get_extruder_colors_from_plater_config();
int extruder_num = colors.size();
int extruder_num = m_extruder_colors.size();
if (m_show_menu) {
ImGui::OpenPopup("slider_menu_popup");
@ -1482,7 +1167,7 @@ void IMSlider::render_menu()
}
else if (begin_menu(_u8L("Change Filament").c_str())) {
for (int i = 0; i < extruder_num; i++) {
std::array<float, 4> rgba = decode_color_to_float_array(colors[i]);
std::array<float, 4> rgba = decode_color_to_float_array(m_extruder_colors[i]);
ImU32 icon_clr = IM_COL32(rgba[0] * 255.0f, rgba[1] * 255.0f, rgba[2] * 255.0f, rgba[3] * 255.0f);
if (menu_item_with_icon((_u8L("Filament ") + std::to_string(i + 1)).c_str(), "", ImVec2(14, 14) * m_scale, icon_clr)) add_code_as_tick(ToolChange, i + 1);
}

View file

@ -1,16 +1,9 @@
#ifndef slic3r_GUI_IMSlider_hpp_
#define slic3r_GUI_IMSlider_hpp_
#include "libslic3r/CustomGCode.hpp"
#include "wxExtensions.hpp"
#include "IMSlider_Utils.hpp"
#include "TickCode.hpp"
#include <imgui/imgui.h>
#include <wx/window.h>
#include <wx/control.h>
#include <wx/dc.h>
#include <wx/slider.h>
#include <vector>
#include <set>
class wxMenu;
@ -43,42 +36,6 @@ enum SelectedSlider {
ssHigher = 2
};
enum FocusedItem {
fiNone,
fiRevertIcon,
fiOneLayerIcon,
fiCogIcon,
fiColorBand,
fiActionIcon,
fiLowerThumb,
fiHigherThumb,
fiSmartWipeTower,
fiTick
};
enum ConflictType
{
ctNone,
ctModeConflict,
ctMeaninglessColorChange,
ctMeaninglessToolChange,
ctRedundant
};
enum MouseAction
{
maNone,
maAddMenu, // show "Add" context menu for NOTexist active tick
maEditMenu, // show "Edit" context menu for exist active tick
maCogIconMenu, // show context for "cog" icon
maForceColorEdit, // force color editing from colored band
maAddTick, // force tick adding
maDeleteTick, // force tick deleting
maCogIconClick, // LeftMouseClick on "cog" icon
maOneLayerIconClick, // LeftMouseClick on "one_layer" icon
maRevertIconClick, // LeftMouseClick on "revert" icon
};
enum DrawMode
{
dmRegular,
@ -94,116 +51,6 @@ enum LabelType
ltEstimatedTime,
};
enum VSliderMode
{
Regular,
Colored,
};
struct TickCode
{
bool operator<(const TickCode& other) const { return other.tick > this->tick; }
bool operator>(const TickCode& other) const { return other.tick < this->tick; }
int tick = 0;
Type type = ColorChange;
int extruder = 0;
std::string color;
std::string extra;
};
class TickCodeInfo
{
std::string custom_gcode;
std::string pause_print_msg;
bool m_suppress_plus = false;
bool m_suppress_minus = false;
bool m_use_default_colors= false;
// int m_default_color_idx = 0;
std::vector<std::string>* m_colors {nullptr};
ColorGenerator color_generator;
std::string get_color_for_tick(TickCode tick, Type type, const int extruder);
public:
std::set<TickCode> ticks {};
Mode mode = Undef;
bool empty() const { return ticks.empty(); }
void set_pause_print_msg(const std::string& message) { pause_print_msg = message; }
bool add_tick(const int tick, Type type, int extruder, double print_z);
bool edit_tick(std::set<TickCode>::iterator it, double print_z);
void switch_code(Type type_from, Type type_to);
bool switch_code_for_tick(std::set<TickCode>::iterator it, Type type_to, const int extruder);
void erase_all_ticks_with_code(Type type);
bool has_tick_with_code(Type type);
bool has_tick(int tick);
ConflictType is_conflict_tick(const TickCode& tick, Mode out_mode, int only_extruder, double print_z);
// Get used extruders for tick.
// Means all extruders(tools) which will be used during printing from current tick to the end
std::set<int> get_used_extruders_for_tick(int tick, int only_extruder, double print_z, Mode force_mode = Undef) const;
void suppress_plus (bool suppress) { m_suppress_plus = suppress; }
void suppress_minus(bool suppress) { m_suppress_minus = suppress; }
bool suppressed_plus () { return m_suppress_plus; }
bool suppressed_minus() { return m_suppress_minus; }
void set_default_colors(bool default_colors_on) { m_use_default_colors = default_colors_on; }
void set_extruder_colors(std::vector<std::string>* extruder_colors) { m_colors = extruder_colors; }
};
struct ExtrudersSequence
{
bool is_mm_intervals = true;
double interval_by_mm = 3.0;
int interval_by_layers = 10;
bool random_sequence { false };
bool color_repetition { false };
std::vector<size_t> extruders = { 0 };
bool operator==(const ExtrudersSequence& other) const
{
return (other.is_mm_intervals == this->is_mm_intervals ) &&
(other.interval_by_mm == this->interval_by_mm ) &&
(other.interval_by_layers == this->interval_by_layers ) &&
(other.random_sequence == this->random_sequence ) &&
(other.color_repetition == this->color_repetition ) &&
(other.extruders == this->extruders ) ;
}
bool operator!=(const ExtrudersSequence& other) const
{
return (other.is_mm_intervals != this->is_mm_intervals ) ||
(other.interval_by_mm != this->interval_by_mm ) ||
(other.interval_by_layers != this->interval_by_layers ) ||
(other.random_sequence != this->random_sequence ) ||
(other.color_repetition != this->color_repetition ) ||
(other.extruders != this->extruders ) ;
}
void add_extruder(size_t pos, size_t extruder_id = size_t(0))
{
extruders.insert(extruders.begin() + pos+1, extruder_id);
}
void delete_extruder(size_t pos)
{
if (extruders.size() == 1)
return;// last item can't be deleted
extruders.erase(extruders.begin() + pos);
}
void init(size_t extruders_count)
{
extruders.clear();
for (size_t extruder = 0; extruder < extruders_count; extruder++)
extruders.push_back(extruder);
}
};
class IMSlider
{
@ -262,7 +109,7 @@ public:
void UseDefaultColors(bool def_colors_on) { m_ticks.set_default_colors(def_colors_on); }
void on_mouse_wheel(wxMouseEvent& evt);
void post_ticks_changed_event(Type type = Custom);
void post_ticks_changed_event(Type type = Unknown);
bool check_ticks_changed_event(Type type);
bool switch_one_layer_mode();
void show_go_to_layer(bool show) { m_show_go_to_layer_dialog = show; }
@ -279,7 +126,6 @@ public:
}
Type get_post_tick_event_type() { return m_tick_change_event_type; }
ExtrudersSequence m_extruders_sequence;
float m_scale = 1.0;
void set_scale(float scale = 1.0);
void on_change_color_mode(bool is_dark);
@ -362,7 +208,6 @@ private:
DrawMode m_draw_mode = dmRegular;
Mode m_mode = SingleExtruder;
VSliderMode m_vslider_mode = Regular;
int m_only_extruder = -1;
long m_style;

View file

@ -1255,11 +1255,14 @@ std::vector<int> PartPlate::get_extruders(bool conside_custom_gcode) const
}
if (conside_custom_gcode) {
for (auto item : m_model->custom_gcode_per_print_z.gcodes) {
if (item.type == CustomGCode::Type::ToolChange)
plate_extruders.push_back(item.extruder);
}
}
//BBS
if (m_model->plates_custom_gcodes.find(m_plate_index) != m_model->plates_custom_gcodes.end()) {
for (auto item : m_model->plates_custom_gcodes.at(m_plate_index).gcodes) {
if (item.type == CustomGCode::Type::ToolChange)
plate_extruders.push_back(item.extruder);
}
}
}
std::sort(plate_extruders.begin(), plate_extruders.end());
auto it_end = std::unique(plate_extruders.begin(), plate_extruders.end());
@ -3080,7 +3083,11 @@ int PartPlateList::select_plate(int index)
m_current_plate = index;
m_plate_list[m_current_plate]->set_selected();
//BBS
if(m_model)
m_model->curr_plate_index = index;
//BBS update bed origin
if (m_intialized && m_plater) {
Vec2d pos = compute_shape_position(index, m_plate_cols);

View file

@ -2422,8 +2422,10 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_COLLAPSE_SIDEBAR, [this](SimpleEvent&) { this->q->collapse_sidebar(!this->q->is_sidebar_collapsed()); });
preview->get_wxglcanvas()->Bind(EVT_CUSTOMEVT_TICKSCHANGED, [this](wxCommandEvent& event) {
Type tick_event_type = (Type)event.GetInt();
Model &model = wxGetApp().plater()->model();
model.custom_gcode_per_print_z = preview->get_canvas3d()->get_gcode_viewer().get_layers_slider()->GetTicksValues();
Model& model = wxGetApp().plater()->model();
//BBS: replace model custom gcode with current plate custom gcode
model.plates_custom_gcodes[model.curr_plate_index] = preview->get_canvas3d()->get_gcode_viewer().get_layers_slider()->GetTicksValues();
preview->on_tick_changed(tick_event_type);
// BBS set to invalid state only
@ -3215,8 +3217,8 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
}
if (!config_substitutions.empty()) show_substitutions_info(config_substitutions.substitutions, filename.string());
this->model.custom_gcode_per_print_z = model.custom_gcode_per_print_z;
// BBS
this->model.plates_custom_gcodes = model.plates_custom_gcodes;
this->model.design_info = model.design_info;
this->model.model_info = model.model_info;
}
@ -4038,7 +4040,8 @@ void Plater::priv::delete_all_objects_from_model()
sidebar->obj_list()->delete_all_objects_from_list();
object_list_changed();
model.custom_gcode_per_print_z.gcodes.clear();
//BBS
model.plates_custom_gcodes.clear();
}
void Plater::priv::reset(bool apply_presets_change)
@ -4088,7 +4091,8 @@ void Plater::priv::reset(bool apply_presets_change)
else
wxGetApp().load_current_presets(false, false);
model.custom_gcode_per_print_z.gcodes.clear();
//BBS
model.plates_custom_gcodes.clear();
// BBS
m_saved_timestamp = m_backup_timestamp = size_t(-1);
@ -10270,7 +10274,6 @@ std::vector<std::string> Plater::get_extruder_colors_from_plater_config(const GC
std::vector<std::string> Plater::get_colors_for_color_print(const GCodeProcessorResult* const result) const
{
std::vector<std::string> colors = get_extruder_colors_from_plater_config(result);
colors.reserve(colors.size() + p->model.custom_gcode_per_print_z.gcodes.size());
if (wxGetApp().is_gcode_viewer() && result != nullptr) {
for (const CustomGCode::Item& code : result->custom_gcode_per_print_z) {
@ -10279,7 +10282,9 @@ std::vector<std::string> Plater::get_colors_for_color_print(const GCodeProcessor
}
}
else {
for (const CustomGCode::Item& code : p->model.custom_gcode_per_print_z.gcodes) {
//BBS
colors.reserve(colors.size() + p->model.get_curr_plate_custom_gcodes().gcodes.size());
for (const CustomGCode::Item& code : p->model.get_curr_plate_custom_gcodes().gcodes) {
if (code.type == CustomGCode::ColorChange)
colors.emplace_back(code.color);
}

193
src/slic3r/GUI/TickCode.cpp Normal file
View file

@ -0,0 +1,193 @@
#include "TickCode.hpp"
namespace Slic3r {
namespace GUI {
std::string TickCodeInfo::get_color_for_tick(TickCode tick, Type type, const int extruder)
{
if (mode == SingleExtruder && type == ColorChange && m_use_default_colors) {
#if 1
if (ticks.empty()) return color_generator.get_opposite_color((*m_colors)[0]);
auto before_tick_it = std::lower_bound(ticks.begin(), ticks.end(), tick);
if (before_tick_it == ticks.end()) {
while (before_tick_it != ticks.begin())
if (--before_tick_it; before_tick_it->type == ColorChange) break;
if (before_tick_it->type == ColorChange) return color_generator.get_opposite_color(before_tick_it->color);
return color_generator.get_opposite_color((*m_colors)[0]);
}
if (before_tick_it == ticks.begin()) {
const std::string &frst_color = (*m_colors)[0];
if (before_tick_it->type == ColorChange) return color_generator.get_opposite_color(frst_color, before_tick_it->color);
auto next_tick_it = before_tick_it;
while (next_tick_it != ticks.end())
if (++next_tick_it; next_tick_it->type == ColorChange) break;
if (next_tick_it->type == ColorChange) return color_generator.get_opposite_color(frst_color, next_tick_it->color);
return color_generator.get_opposite_color(frst_color);
}
std::string frst_color = "";
if (before_tick_it->type == ColorChange)
frst_color = before_tick_it->color;
else {
auto next_tick_it = before_tick_it;
while (next_tick_it != ticks.end())
if (++next_tick_it; next_tick_it->type == ColorChange) {
frst_color = next_tick_it->color;
break;
}
}
while (before_tick_it != ticks.begin())
if (--before_tick_it; before_tick_it->type == ColorChange) break;
if (before_tick_it->type == ColorChange) {
if (frst_color.empty()) return color_generator.get_opposite_color(before_tick_it->color);
return color_generator.get_opposite_color(before_tick_it->color, frst_color);
}
if (frst_color.empty()) return color_generator.get_opposite_color((*m_colors)[0]);
return color_generator.get_opposite_color((*m_colors)[0], frst_color);
#else
const std::vector<std::string> &colors = ColorPrintColors::get();
if (ticks.empty()) return colors[0];
m_default_color_idx++;
return colors[m_default_color_idx % colors.size()];
#endif
}
std::string color = (*m_colors)[extruder - 1];
if (type == ColorChange) {
if (!ticks.empty()) {
auto before_tick_it = std::lower_bound(ticks.begin(), ticks.end(), tick);
while (before_tick_it != ticks.begin()) {
--before_tick_it;
if (before_tick_it->type == ColorChange && before_tick_it->extruder == extruder) {
color = before_tick_it->color;
break;
}
}
}
//TODO
//color = get_new_color(color);
}
return color;
}
bool TickCodeInfo::add_tick(const int tick, Type type, const int extruder, double print_z)
{
std::string color;
std::string extra;
if (type == Custom) // custom Gcode
{
//extra = get_custom_code(custom_gcode, print_z);
//if (extra.empty()) return false;
//custom_gcode = extra;
} else if (type == PausePrint) {
//BBS do not set pause extra message
//extra = get_pause_print_msg(pause_print_msg, print_z);
//if (extra.empty()) return false;
pause_print_msg = extra;
}
else {
color = get_color_for_tick(TickCode{ tick }, type, extruder);
if (color.empty()) return false;
}
if (mode == SingleExtruder) m_use_default_colors = true;
ticks.emplace(TickCode{tick, type, extruder, color, extra});
return true;
}
bool TickCodeInfo::edit_tick(std::set<TickCode>::iterator it, double print_z)
{
std::string edited_value;
//TODO
/* BBS
if (it->type == ColorChange)
edited_value = get_new_color(it->color);
else if (it->type == PausePrint)
edited_value = get_pause_print_msg(it->extra, print_z);
else
edited_value = get_custom_code(it->type == Template ? gcode(Template) : it->extra, print_z);
*/
if (edited_value.empty()) return false;
TickCode changed_tick = *it;
if (it->type == ColorChange) {
if (it->color == edited_value) return false;
changed_tick.color = edited_value;
} else if (it->type == Template) {
//if (gcode(Template) == edited_value) return false;
//changed_tick.extra = edited_value;
//changed_tick.type = Custom;
;
} else if (it->type == Custom || it->type == PausePrint) {
if (it->extra == edited_value) return false;
changed_tick.extra = edited_value;
}
ticks.erase(it);
ticks.emplace(changed_tick);
return true;
}
void TickCodeInfo::switch_code(Type type_from, Type type_to)
{
for (auto it{ticks.begin()}, end{ticks.end()}; it != end;)
if (it->type == type_from) {
TickCode tick = *it;
tick.type = type_to;
tick.extruder = 1;
ticks.erase(it);
it = ticks.emplace(tick).first;
} else
++it;
}
bool TickCodeInfo::switch_code_for_tick(std::set<TickCode>::iterator it, Type type_to, const int extruder)
{
const std::string color = get_color_for_tick(*it, type_to, extruder);
if (color.empty()) return false;
TickCode changed_tick = *it;
changed_tick.type = type_to;
changed_tick.extruder = extruder;
changed_tick.color = color;
ticks.erase(it);
ticks.emplace(changed_tick);
return true;
}
void TickCodeInfo::erase_all_ticks_with_code(Type type)
{
for (auto it{ticks.begin()}, end{ticks.end()}; it != end;) {
if (it->type == type)
it = ticks.erase(it);
else
++it;
}
}
bool TickCodeInfo::has_tick_with_code(Type type)
{
for (const TickCode &tick : ticks)
if (tick.type == type) return true;
return false;
}
bool TickCodeInfo::has_tick(int tick) { return ticks.find(TickCode{tick}) != ticks.end(); }
}}

View file

@ -0,0 +1,63 @@
#ifndef slic3r_GUI_TickCode_hpp_
#define slic3r_GUI_TickCode_hpp_
#include "libslic3r/CustomGCode.hpp"
#include "IMSlider_Utils.hpp"
#include <set>
namespace Slic3r {
using namespace CustomGCode;
namespace GUI {
struct TickCode
{
bool operator<(const TickCode& other) const { return other.tick > this->tick; }
bool operator>(const TickCode& other) const { return other.tick < this->tick; }
int tick = 0;
Type type = ColorChange;
int extruder = 0;
std::string color;
std::string extra;
};
class TickCodeInfo
{
std::string pause_print_msg;
bool m_suppress_plus = false;
bool m_suppress_minus = false;
bool m_use_default_colors = false;
std::vector<std::string>* m_colors{ nullptr };// reference to IMSlider::m_extruder_colors
ColorGenerator color_generator;
std::string get_color_for_tick(TickCode tick, Type type, const int extruder);
public:
std::set<TickCode> ticks{};
Mode mode = Undef;
bool empty() const { return ticks.empty(); }
void set_pause_print_msg(const std::string& message) { pause_print_msg = message; }
bool add_tick(const int tick, Type type, int extruder, double print_z);
bool edit_tick(std::set<TickCode>::iterator it, double print_z);
void switch_code(Type type_from, Type type_to);
bool switch_code_for_tick(std::set<TickCode>::iterator it, Type type_to, const int extruder);
void erase_all_ticks_with_code(Type type);
bool has_tick_with_code(Type type);
bool has_tick(int tick);
void suppress_plus(bool suppress) { m_suppress_plus = suppress; }
void suppress_minus(bool suppress) { m_suppress_minus = suppress; }
bool suppressed_plus() { return m_suppress_plus; }
bool suppressed_minus() { return m_suppress_minus; }
void set_default_colors(bool default_colors_on) { m_use_default_colors = default_colors_on; }
void set_extruder_colors(std::vector<std::string>* extruder_colors) { m_colors = extruder_colors; }
};
}} // Slic3r
#endif // slic3r_GUI_TickCode_hpp_