mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-02 06:30:38 +08:00
Merge branch 'lm_purging_volumes_SPE-2147' into master_27x
This commit is contained in:
commit
ed8c373dc7
@ -1510,9 +1510,20 @@ std::vector<std::vector<float>> WipeTower::extract_wipe_volumes(const PrintConfi
|
||||
// Extract purging volumes for each extruder pair:
|
||||
std::vector<std::vector<float>> wipe_volumes;
|
||||
const unsigned int number_of_extruders = (unsigned int)(sqrt(wiping_matrix.size())+EPSILON);
|
||||
for (unsigned int i = 0; i<number_of_extruders; ++i)
|
||||
for (size_t i = 0; i<number_of_extruders; ++i)
|
||||
wipe_volumes.push_back(std::vector<float>(wiping_matrix.begin()+i*number_of_extruders, wiping_matrix.begin()+(i+1)*number_of_extruders));
|
||||
|
||||
// For SEMM printers, the project can be configured to use defaults from configuration,
|
||||
// in which case the custom matrix shall be ignored. We will overwrite the values.
|
||||
if (config.single_extruder_multi_material && ! config.wiping_volumes_use_custom_matrix) {
|
||||
for (size_t i = 0; i < number_of_extruders; ++i) {
|
||||
for (size_t j = 0; j < number_of_extruders; ++j) {
|
||||
if (i != j)
|
||||
wipe_volumes[i][j] = (i == j ? 0.f : config.multimaterial_purging.value * config.filament_purge_multiplier.get_at(j) / 100.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Also include filament_minimal_purge_on_wipe_tower. This is needed for the preview.
|
||||
for (unsigned int i = 0; i<number_of_extruders; ++i)
|
||||
for (unsigned int j = 0; j<number_of_extruders; ++j)
|
||||
|
@ -479,7 +479,7 @@ static std::vector<std::string> s_Preset_filament_options {
|
||||
"filament_colour", "filament_diameter", "filament_type", "filament_soluble", "filament_notes", "filament_max_volumetric_speed",
|
||||
"extrusion_multiplier", "filament_density", "filament_cost", "filament_spool_weight", "filament_loading_speed", "filament_loading_speed_start", "filament_load_time",
|
||||
"filament_unloading_speed", "filament_unloading_speed_start", "filament_unload_time", "filament_toolchange_delay", "filament_cooling_moves", "filament_stamping_loading_speed", "filament_stamping_distance",
|
||||
"filament_cooling_initial_speed", "filament_cooling_final_speed", "filament_ramming_parameters", "filament_minimal_purge_on_wipe_tower",
|
||||
"filament_cooling_initial_speed", "filament_purge_multiplier", "filament_cooling_final_speed", "filament_ramming_parameters", "filament_minimal_purge_on_wipe_tower",
|
||||
"filament_multitool_ramming", "filament_multitool_ramming_volume", "filament_multitool_ramming_flow",
|
||||
"temperature", "idle_temperature", "first_layer_temperature", "bed_temperature", "first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed",
|
||||
"max_fan_speed", "bridge_fan_speed", "disable_fan_first_layers", "full_fan_speed_layer", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed",
|
||||
@ -510,8 +510,8 @@ static std::vector<std::string> s_Preset_printer_options {
|
||||
"single_extruder_multi_material", "start_gcode", "end_gcode", "before_layer_gcode", "layer_gcode", "toolchange_gcode",
|
||||
"color_change_gcode", "pause_print_gcode", "template_custom_gcode",
|
||||
"between_objects_gcode", "printer_vendor", "printer_model", "printer_variant", "printer_notes", "cooling_tube_retraction",
|
||||
"cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "max_print_height",
|
||||
"default_print_profile", "inherits",
|
||||
"cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "multimaterial_purging",
|
||||
"max_print_height", "default_print_profile", "inherits",
|
||||
"remaining_times", "silent_mode",
|
||||
"machine_limits_usage", "thumbnails", "thumbnails_format"
|
||||
};
|
||||
|
@ -38,8 +38,8 @@ namespace Slic3r {
|
||||
|
||||
static std::vector<std::string> s_project_options {
|
||||
"colorprint_heights",
|
||||
"wiping_volumes_extruders",
|
||||
"wiping_volumes_matrix"
|
||||
"wiping_volumes_matrix",
|
||||
"wiping_volumes_use_custom_matrix"
|
||||
};
|
||||
|
||||
const char *PresetBundle::PRUSA_BUNDLE = "PrusaResearch";
|
||||
@ -1711,6 +1711,8 @@ std::pair<PresetsConfigSubstitutions, size_t> PresetBundle::load_configbundle(
|
||||
return std::make_pair(std::move(substitutions), presets_loaded + ph_printers_loaded);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PresetBundle::update_multi_material_filament_presets()
|
||||
{
|
||||
if (printers.get_edited_preset().printer_technology() != ptFFF)
|
||||
@ -1732,27 +1734,22 @@ void PresetBundle::update_multi_material_filament_presets()
|
||||
|
||||
// Now verify if wiping_volumes_matrix has proper size (it is used to deduce number of extruders in wipe tower generator):
|
||||
std::vector<double> old_matrix = this->project_config.option<ConfigOptionFloats>("wiping_volumes_matrix")->values;
|
||||
size_t old_number_of_extruders = size_t(sqrt(old_matrix.size())+EPSILON);
|
||||
size_t old_number_of_extruders = size_t(std::sqrt(old_matrix.size())+EPSILON);
|
||||
if (num_extruders != old_number_of_extruders) {
|
||||
// First verify if purging volumes presets for each extruder matches number of extruders
|
||||
std::vector<double>& extruders = this->project_config.option<ConfigOptionFloats>("wiping_volumes_extruders")->values;
|
||||
while (extruders.size() < 2*num_extruders) {
|
||||
extruders.push_back(extruders.size()>1 ? extruders[0] : 50.); // copy the values from the first extruder
|
||||
extruders.push_back(extruders.size()>1 ? extruders[1] : 50.);
|
||||
}
|
||||
while (extruders.size() > 2*num_extruders) {
|
||||
extruders.pop_back();
|
||||
extruders.pop_back();
|
||||
}
|
||||
|
||||
// Extract the relevant config options, even values from possibly modified presets.
|
||||
const double default_purge = static_cast<const ConfigOptionFloat*>(this->printers.get_edited_preset().config.option("multimaterial_purging"))->value;
|
||||
const std::vector<double> filament_purging_multipliers = get_config_options_for_current_filaments<ConfigOptionPercents>("filament_purge_multiplier");
|
||||
|
||||
std::vector<double> new_matrix;
|
||||
for (unsigned int i=0;i<num_extruders;++i)
|
||||
for (unsigned int i=0;i<num_extruders;++i) {
|
||||
for (unsigned int j=0;j<num_extruders;++j) {
|
||||
// append the value for this pair from the old matrix (if it's there):
|
||||
if (i<old_number_of_extruders && j<old_number_of_extruders)
|
||||
new_matrix.push_back(old_matrix[i*old_number_of_extruders + j]);
|
||||
else
|
||||
new_matrix.push_back( i==j ? 0. : extruders[2*i]+extruders[2*j+1]); // so it matches new extruder volumes
|
||||
new_matrix.push_back( i==j ? 0. : default_purge * filament_purging_multipliers[j] / 100.);
|
||||
}
|
||||
}
|
||||
this->project_config.option<ConfigOptionFloats>("wiping_volumes_matrix")->values = new_matrix;
|
||||
}
|
||||
|
@ -63,6 +63,30 @@ public:
|
||||
void cache_extruder_filaments_names();
|
||||
void reset_extruder_filaments();
|
||||
|
||||
// Another hideous function related to current ExtruderFilaments hack. Returns a vector of values
|
||||
// of a given config option for all currently used filaments. Modified value is returned for modified preset.
|
||||
// Must be called with the vector ConfigOption type, e.g. ConfigOptionPercents.
|
||||
template <class T>
|
||||
auto get_config_options_for_current_filaments(const t_config_option_key& key)
|
||||
{
|
||||
decltype(T::values) out;
|
||||
const Preset& edited_preset = this->filaments.get_edited_preset();
|
||||
for (const ExtruderFilaments& extr_filament : this->extruders_filaments) {
|
||||
const Preset& selected_preset = *extr_filament.get_selected_preset();
|
||||
const Preset& preset = edited_preset.name == selected_preset.name ? edited_preset : selected_preset;
|
||||
const T* co = preset.config.opt<T>(key);
|
||||
if (co) {
|
||||
assert(co->values.size() == 1);
|
||||
out.push_back(co->values.back());
|
||||
} else {
|
||||
// Key is missing or type mismatch.
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PresetCollection& get_presets(Preset::Type preset_type);
|
||||
|
||||
// The project configuration values are kept separated from the print/filament/printer preset,
|
||||
|
@ -224,6 +224,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
||||
|| opt_key == "filament_minimal_purge_on_wipe_tower"
|
||||
|| opt_key == "filament_cooling_initial_speed"
|
||||
|| opt_key == "filament_cooling_final_speed"
|
||||
|| opt_key == "filament_purge_multiplier"
|
||||
|| opt_key == "filament_ramming_parameters"
|
||||
|| opt_key == "filament_multitool_ramming"
|
||||
|| opt_key == "filament_multitool_ramming_volume"
|
||||
@ -245,10 +246,12 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
||||
|| opt_key == "wipe_tower_no_sparse_layers"
|
||||
|| opt_key == "wipe_tower_extruder"
|
||||
|| opt_key == "wiping_volumes_matrix"
|
||||
|| opt_key == "wiping_volumes_use_custom_matrix"
|
||||
|| opt_key == "parking_pos_retraction"
|
||||
|| opt_key == "cooling_tube_retraction"
|
||||
|| opt_key == "cooling_tube_length"
|
||||
|| opt_key == "extra_loading_move"
|
||||
|| opt_key == "multimaterial_purging"
|
||||
|| opt_key == "travel_speed"
|
||||
|| opt_key == "travel_speed_z"
|
||||
|| opt_key == "first_layer_speed"
|
||||
|
@ -1144,6 +1144,16 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloats { 3.4 });
|
||||
|
||||
def = this->add("filament_purge_multiplier", coPercents);
|
||||
def->label = L("Purge volume multiplier");
|
||||
def->tooltip = L("Purging volume on the wipe tower is determined by 'multimaterial_purging' in Printer Settings. "
|
||||
"This option allows to modify the volume on filament level. "
|
||||
"Note that the project can override this by setting project-specific values.");
|
||||
def->sidetext = L("%");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionPercents { 100 });
|
||||
|
||||
def = this->add("filament_load_time", coFloats);
|
||||
def->label = L("Filament load time");
|
||||
def->tooltip = L("Time for the printer firmware (or the Multi Material Unit 2.0) to load a new filament during a tool change (when executing the T code). This time is added to the total print time by the G-code time estimator.");
|
||||
@ -2136,6 +2146,14 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(-2.));
|
||||
|
||||
def = this->add("multimaterial_purging", coFloat);
|
||||
def->label = L("Purging volume");
|
||||
def->tooltip = L("Determines purging volume on the wipe tower. This can be modified in Filament Settings "
|
||||
"('filament_purge_multiplier') or overridden using project-specific settings.");
|
||||
def->sidetext = L("mm³");
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(140.));
|
||||
|
||||
def = this->add("perimeter_acceleration", coFloat);
|
||||
def->label = L("Perimeters");
|
||||
def->tooltip = L("This is the acceleration your printer will use for perimeters. "
|
||||
@ -3285,13 +3303,6 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionBool(false));
|
||||
|
||||
def = this->add("wiping_volumes_extruders", coFloats);
|
||||
def->label = L("Purging volumes - load/unload volumes");
|
||||
def->tooltip = L("This vector saves required volumes to change from/to each tool used on the "
|
||||
"wipe tower. These values are used to simplify creation of the full purging "
|
||||
"volumes below.");
|
||||
def->set_default_value(new ConfigOptionFloats { 70., 70., 70., 70., 70., 70., 70., 70., 70., 70. });
|
||||
|
||||
def = this->add("wiping_volumes_matrix", coFloats);
|
||||
def->label = L("Purging volumes - matrix");
|
||||
def->tooltip = L("This matrix describes volumes (in cubic milimetres) required to purge the"
|
||||
@ -3302,6 +3313,11 @@ void PrintConfigDef::init_fff_params()
|
||||
140., 140., 140., 0., 140.,
|
||||
140., 140., 140., 140., 0. });
|
||||
|
||||
def = this->add("wiping_volumes_use_custom_matrix", coBool);
|
||||
def->label = L("");
|
||||
def->tooltip = L("");
|
||||
def->set_default_value(new ConfigOptionBool{ false });
|
||||
|
||||
def = this->add("wipe_tower_x", coFloat);
|
||||
def->label = L("Position X");
|
||||
def->tooltip = L("X coordinate of the left front corner of a wipe tower");
|
||||
@ -4385,7 +4401,8 @@ static std::set<std::string> PrintConfigDef_ignore = {
|
||||
"ensure_vertical_shell_thickness",
|
||||
// Disabled in 2.6.0-alpha6, this option is problematic
|
||||
"infill_only_where_needed",
|
||||
"gcode_binary" // Introduced in 2.7.0-alpha1, removed in 2.7.1 (replaced by binary_gcode).
|
||||
"gcode_binary", // Introduced in 2.7.0-alpha1, removed in 2.7.1 (replaced by binary_gcode).
|
||||
"wiping_volumes_extruders" // Removed in 2.7.3-alpha1.
|
||||
};
|
||||
|
||||
void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &value)
|
||||
@ -4517,6 +4534,26 @@ void PrintConfigDef::handle_legacy_composite(DynamicPrintConfig &config)
|
||||
config.set_key_value("thumbnails", new ConfigOptionString(thumbnails_str));
|
||||
}
|
||||
}
|
||||
|
||||
if (config.has("wiping_volumes_matrix") && !config.has("wiping_volumes_use_custom_matrix")) {
|
||||
// This is apparently some pre-2.7.3 config, where the wiping_volumes_matrix was always used.
|
||||
// The 2.7.3 introduced an option to use defaults derived from config. In case the matrix
|
||||
// contains only default values, switch it to default behaviour. The default values
|
||||
// were zeros on the diagonal and 140 otherwise.
|
||||
std::vector<double> matrix = config.opt<ConfigOptionFloats>("wiping_volumes_matrix")->values;
|
||||
int num_of_extruders = int(std::sqrt(matrix.size()) + 0.5);
|
||||
int i = -1;
|
||||
bool custom = false;
|
||||
for (int j = 0; j < int(matrix.size()); ++j) {
|
||||
if (j % num_of_extruders == 0)
|
||||
++i;
|
||||
if (i != j % num_of_extruders && !is_approx(matrix[j], 140.)) {
|
||||
custom = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
config.set_key_value("wiping_volumes_use_custom_matrix", new ConfigOptionBool(custom));
|
||||
}
|
||||
}
|
||||
|
||||
const PrintConfigDef print_config_def;
|
||||
|
@ -727,6 +727,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionFloats, filament_cooling_initial_speed))
|
||||
((ConfigOptionFloats, filament_minimal_purge_on_wipe_tower))
|
||||
((ConfigOptionFloats, filament_cooling_final_speed))
|
||||
((ConfigOptionPercents, filament_purge_multiplier))
|
||||
((ConfigOptionStrings, filament_ramming_parameters))
|
||||
((ConfigOptionBools, filament_multitool_ramming))
|
||||
((ConfigOptionFloats, filament_multitool_ramming_volume))
|
||||
@ -779,6 +780,7 @@ PRINT_CONFIG_CLASS_DEFINE(
|
||||
((ConfigOptionBool, remaining_times))
|
||||
((ConfigOptionBool, silent_mode))
|
||||
((ConfigOptionFloat, extra_loading_move))
|
||||
((ConfigOptionFloat, multimaterial_purging))
|
||||
((ConfigOptionString, color_change_gcode))
|
||||
((ConfigOptionString, pause_print_gcode))
|
||||
((ConfigOptionString, template_custom_gcode))
|
||||
@ -881,7 +883,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
||||
((ConfigOptionFloat, wipe_tower_bridging))
|
||||
((ConfigOptionInt, wipe_tower_extruder))
|
||||
((ConfigOptionFloats, wiping_volumes_matrix))
|
||||
((ConfigOptionFloats, wiping_volumes_extruders))
|
||||
((ConfigOptionBool, wiping_volumes_use_custom_matrix))
|
||||
((ConfigOptionFloat, z_offset))
|
||||
)
|
||||
|
||||
|
@ -518,19 +518,22 @@ FreqChangedParams::FreqChangedParams(wxWindow* parent) :
|
||||
sizer->Add(m_wiping_dialog_button, 0, wxALIGN_CENTER_VERTICAL);
|
||||
m_wiping_dialog_button->Bind(wxEVT_BUTTON, ([parent](wxCommandEvent& e)
|
||||
{
|
||||
auto &project_config = wxGetApp().preset_bundle->project_config;
|
||||
PresetBundle* preset_bundle = wxGetApp().preset_bundle;
|
||||
DynamicPrintConfig& project_config = preset_bundle->project_config;
|
||||
const bool use_custom_matrix = (project_config.option<ConfigOptionBool>("wiping_volumes_use_custom_matrix"))->value;
|
||||
const std::vector<double> &init_matrix = (project_config.option<ConfigOptionFloats>("wiping_volumes_matrix"))->values;
|
||||
const std::vector<double> &init_extruders = (project_config.option<ConfigOptionFloats>("wiping_volumes_extruders"))->values;
|
||||
|
||||
const std::vector<std::string> extruder_colours = wxGetApp().plater()->get_extruder_colors_from_plater_config();
|
||||
|
||||
WipingDialog dlg(parent, cast<float>(init_matrix), cast<float>(init_extruders), extruder_colours);
|
||||
// Extract the relevant config options, even values from possibly modified presets.
|
||||
const double default_purge = static_cast<const ConfigOptionFloat*>(preset_bundle->printers.get_edited_preset().config.option("multimaterial_purging"))->value;
|
||||
std::vector<double> filament_purging_multipliers = preset_bundle->get_config_options_for_current_filaments<ConfigOptionPercents>("filament_purge_multiplier");
|
||||
|
||||
WipingDialog dlg(parent, cast<float>(init_matrix), extruder_colours, default_purge, filament_purging_multipliers, use_custom_matrix);
|
||||
|
||||
if (dlg.ShowModal() == wxID_OK) {
|
||||
std::vector<float> matrix = dlg.get_matrix();
|
||||
std::vector<float> extruders = dlg.get_extruders();
|
||||
(project_config.option<ConfigOptionFloats>("wiping_volumes_matrix"))->values = std::vector<double>(matrix.begin(), matrix.end());
|
||||
(project_config.option<ConfigOptionFloats>("wiping_volumes_extruders"))->values = std::vector<double>(extruders.begin(), extruders.end());
|
||||
(project_config.option<ConfigOptionBool>("wiping_volumes_use_custom_matrix"))->value = dlg.get_use_custom_matrix();
|
||||
// Update Project dirty state, update application title bar.
|
||||
wxGetApp().plater()->update_project_dirty_from_presets();
|
||||
wxPostEvent(parent, SimpleEvent(EVT_SCHEDULE_BACKGROUND_PROCESS, parent));
|
||||
|
@ -2273,6 +2273,7 @@ void TabFilament::build()
|
||||
optgroup->append_single_option_line("filament_cooling_final_speed");
|
||||
optgroup->append_single_option_line("filament_stamping_loading_speed");
|
||||
optgroup->append_single_option_line("filament_stamping_distance");
|
||||
optgroup->append_single_option_line("filament_purge_multiplier");
|
||||
|
||||
create_line_with_widget(optgroup.get(), "filament_ramming_parameters", "", [this](wxWindow* parent) {
|
||||
auto ramming_dialog_btn = new wxButton(parent, wxID_ANY, _(L("Ramming settings"))+dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
|
||||
@ -3379,6 +3380,7 @@ void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/)
|
||||
optgroup->append_single_option_line("cooling_tube_length");
|
||||
optgroup->append_single_option_line("parking_pos_retraction");
|
||||
optgroup->append_single_option_line("extra_loading_move");
|
||||
optgroup->append_single_option_line("multimaterial_purging");
|
||||
optgroup->append_single_option_line("high_current_on_filament_swap");
|
||||
if (from_initial_build)
|
||||
page->clear();
|
||||
|
@ -72,14 +72,6 @@ RammingDialog::RammingDialog(wxWindow* parent,const std::string& parameters)
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#define style wxSP_ARROW_KEYS | wxBORDER_SIMPLE
|
||||
#else
|
||||
#define style wxSP_ARROW_KEYS
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
RammingPanel::RammingPanel(wxWindow* parent, const std::string& parameters)
|
||||
: wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize/*,wxPoint(50,50), wxSize(800,350),wxBORDER_RAISED*/)
|
||||
{
|
||||
@ -110,6 +102,12 @@ RammingPanel::RammingPanel(wxWindow* parent, const std::string& parameters)
|
||||
#endif
|
||||
sizer_chart->Add(m_chart, 0, wxALL, 5);
|
||||
|
||||
#ifdef _WIN32
|
||||
const long style = wxSP_ARROW_KEYS | wxBORDER_SIMPLE;
|
||||
#else
|
||||
const long style = wxSP_ARROW_KEYS;
|
||||
#endif
|
||||
|
||||
m_widget_time = new ::SpinInputDouble(this,"", wxEmptyString, wxDefaultPosition, wxSize(ITEM_WIDTH(), -1), style, 0., 5., 3., 0.25);
|
||||
m_widget_time->SetDigits(2);
|
||||
m_widget_volume = new ::SpinInput(this,"",wxEmptyString,wxDefaultPosition,wxSize(ITEM_WIDTH(), -1),style,0,10000,0);
|
||||
@ -190,25 +188,53 @@ std::string RammingPanel::get_parameters()
|
||||
}
|
||||
|
||||
|
||||
// Parent dialog for purging volume adjustments - it fathers WipingPanel widget (that contains all controls) and a button to toggle simple/advanced mode:
|
||||
WipingDialog::WipingDialog(wxWindow* parent, const std::vector<float>& matrix, const std::vector<float>& extruders, const std::vector<std::string>& extruder_colours)
|
||||
// Parent dialog for purging volume adjustments - it fathers WipingPanel widget (that contains all controls) and a button.
|
||||
WipingDialog::WipingDialog(wxWindow* parent, const std::vector<float>& matrix, const std::vector<std::string>& extruder_colours,
|
||||
double printer_purging_volume, const std::vector<double>& filament_purging_multipliers, bool use_custom_matrix)
|
||||
: wxDialog(parent, wxID_ANY, _(L("Wipe tower - Purging volume adjustment")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE/* | wxRESIZE_BORDER*/)
|
||||
{
|
||||
SetFont(wxGetApp().normal_font());
|
||||
update_ui(this);
|
||||
auto widget_button = new wxButton(this,wxID_ANY,"-",wxPoint(0,0),wxDefaultSize);
|
||||
update_ui(widget_button);
|
||||
wxGetApp().SetWindowVariantForButton(widget_button);
|
||||
m_panel_wiping = new WipingPanel(this,matrix,extruders, extruder_colours, widget_button);
|
||||
m_widget_button = new wxButton(this,wxID_ANY,_L("Set values from configuration"), wxPoint(0, 0), wxDefaultSize);
|
||||
update_ui(m_widget_button);
|
||||
wxGetApp().SetWindowVariantForButton(m_widget_button);
|
||||
|
||||
auto main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_radio_button1 = new wxRadioButton(this, wxID_ANY, _L("Use values from configuration"));
|
||||
m_radio_button2 = new wxRadioButton(this, wxID_ANY, _L("Use custom project-specific settings"));
|
||||
auto stb1 = new wxStaticBox(this, wxID_ANY, wxEmptyString);
|
||||
auto stb2 = new wxStaticBox(this, wxID_ANY, wxEmptyString);
|
||||
|
||||
m_panel_wiping = new WipingPanel(this, matrix, extruder_colours, filament_purging_multipliers, printer_purging_volume, m_widget_button);
|
||||
|
||||
update_ui(m_radio_button1);
|
||||
update_ui(m_radio_button2);
|
||||
update_ui(stb1);
|
||||
update_ui(stb2);
|
||||
|
||||
auto heading_text = new wxStaticText(this, wxID_ANY, _L("The project uses single-extruder multimaterial printer with the wipe tower.\nThe volume of material used for purging can be configured here.") ,wxDefaultPosition, wxDefaultSize);
|
||||
m_info_text1 = new wxStaticText(this, wxID_ANY, _L("Options 'multimaterial_purging' and 'filament_purge_multiplier' will be used.") ,wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
// set min sizer width according to extruders count
|
||||
const auto sizer_width = (int)((sqrt(matrix.size()) + 2.8)*ITEM_WIDTH());
|
||||
const auto sizer_width = (int)((std::sqrt(matrix.size()) + 2.8)*ITEM_WIDTH());
|
||||
auto main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
main_sizer->SetMinSize(wxSize(sizer_width, -1));
|
||||
|
||||
main_sizer->Add(m_panel_wiping, 0, wxEXPAND | wxALL, 5);
|
||||
main_sizer->Add(widget_button, 0, wxALIGN_CENTER_HORIZONTAL | wxCENTER | wxBOTTOM, 5);
|
||||
main_sizer->Add(heading_text, 0, wxALL, 10);
|
||||
|
||||
main_sizer->Add(m_radio_button1, 0, wxALL, 10);
|
||||
auto stb_sizer1 = new wxStaticBoxSizer(stb1, wxHORIZONTAL);
|
||||
stb_sizer1->Add(m_info_text1, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
|
||||
main_sizer->Add(stb_sizer1, 0, wxALIGN_CENTER_HORIZONTAL | wxEXPAND | wxLEFT | wxRIGHT, 20);
|
||||
|
||||
auto t = new wxStaticText(this, wxID_ANY, _L("(all values in mm³)"), wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
main_sizer->Add(m_radio_button2, 0, wxALL, 10);
|
||||
auto stb_sizer2 = new wxStaticBoxSizer(stb2, wxVERTICAL);
|
||||
stb_sizer2->Add(m_panel_wiping, 0, wxEXPAND | wxALL, 5);
|
||||
stb_sizer2->Add(t, 0, wxALIGN_CENTER_HORIZONTAL | wxCENTER | wxBOTTOM, 5);
|
||||
stb_sizer2->Add(m_widget_button, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 10);
|
||||
main_sizer->Add(stb_sizer2, 0, wxALIGN_CENTER_HORIZONTAL | wxEXPAND | wxBOTTOM | wxLEFT | wxRIGHT, 20);
|
||||
|
||||
auto buttons = CreateStdDialogButtonSizer(wxOK | wxCANCEL);
|
||||
wxGetApp().SetWindowVariantForButton(buttons->GetAffirmativeButton());
|
||||
wxGetApp().SetWindowVariantForButton(buttons->GetCancelButton());
|
||||
@ -223,32 +249,49 @@ WipingDialog::WipingDialog(wxWindow* parent, const std::vector<float>& matrix, c
|
||||
|
||||
this->Bind(wxEVT_BUTTON,[this](wxCommandEvent&) { // if OK button is clicked..
|
||||
m_output_matrix = m_panel_wiping->read_matrix_values(); // ..query wiping panel and save returned values
|
||||
m_output_extruders = m_panel_wiping->read_extruders_values(); // so they can be recovered later by calling get_...()
|
||||
EndModal(wxID_OK);
|
||||
},wxID_OK);
|
||||
|
||||
this->Bind(wxEVT_RADIOBUTTON, [this](wxCommandEvent&) {
|
||||
enable_or_disable_panel();
|
||||
});
|
||||
|
||||
m_radio_button1->SetValue(! use_custom_matrix);
|
||||
m_radio_button2->SetValue(use_custom_matrix);
|
||||
enable_or_disable_panel();
|
||||
|
||||
this->Show();
|
||||
|
||||
}
|
||||
|
||||
// This function allows to "play" with sizers parameters (like align or border)
|
||||
void WipingPanel::format_sizer(wxSizer* sizer, wxPanel* page, wxGridSizer* grid_sizer, const wxString& info, const wxString& table_title, int table_lshift/*=0*/)
|
||||
// This function allows to "play" with sizrs parameters (like align or border)
|
||||
void WipingPanel::format_sizer(wxSizer* sizer, wxPanel* page, wxGridSizer* grid_sizer, const wxString& table_title, int table_lshift/*=0*/)
|
||||
{
|
||||
wxSize text_size = GetTextExtent(info);
|
||||
auto info_str = new wxStaticText(page, wxID_ANY, info ,wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER);
|
||||
info_str->Wrap(int(0.6*text_size.x));
|
||||
sizer->Add( info_str, 0, wxEXPAND);
|
||||
auto table_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
sizer->Add(table_sizer, 0, wxALIGN_CENTER | wxCENTER, table_lshift);
|
||||
table_sizer->Add(new wxStaticText(page, wxID_ANY, table_title), 0, wxALIGN_CENTER | wxTOP, 50);
|
||||
table_sizer->Add(grid_sizer, 0, wxALIGN_CENTER | wxTOP, 10);
|
||||
table_sizer->Add(new wxStaticText(page, wxID_ANY, table_title), 0, wxALIGN_CENTER | wxTOP, 10);
|
||||
table_sizer->Add(grid_sizer, 0, wxALIGN_CENTER | wxTOP | wxLEFT, 15);
|
||||
}
|
||||
|
||||
// This panel contains all control widgets for both simple and advanced mode (these reside in separate sizers)
|
||||
WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, const std::vector<float>& extruders, const std::vector<std::string>& extruder_colours, wxButton* widget_button)
|
||||
|
||||
WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, const std::vector<std::string>& extruder_colours,
|
||||
const std::vector<double>& filament_purging_multipliers, double printer_purging_volume, wxButton* widget_button)
|
||||
: wxPanel(parent,wxID_ANY, wxDefaultPosition, wxDefaultSize/*,wxBORDER_RAISED*/)
|
||||
{
|
||||
m_filament_purging_multipliers = filament_purging_multipliers;
|
||||
m_printer_purging_volume = printer_purging_volume;
|
||||
m_widget_button = widget_button; // pointer to the button in parent dialog
|
||||
m_widget_button->Bind(wxEVT_BUTTON,[this](wxCommandEvent&){ toggle_advanced(true); });
|
||||
m_widget_button->Bind(wxEVT_BUTTON,[this](wxCommandEvent&){
|
||||
// Set the matrix to defaults.
|
||||
for (size_t i = 0; i < m_number_of_extruders; ++i) {
|
||||
for (size_t j = 0; j < m_number_of_extruders; ++j) {
|
||||
if (i != j) {
|
||||
double def_val = m_printer_purging_volume * m_filament_purging_multipliers[j] / 100.;
|
||||
edit_boxes[j][i]->SetValue(wxString("") << int(def_val));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
m_number_of_extruders = (int)(sqrt(matrix.size())+0.001);
|
||||
|
||||
@ -258,18 +301,12 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, con
|
||||
m_colours.push_back(wxColor(rgb.r_uchar(), rgb.g_uchar(), rgb.b_uchar()));
|
||||
}
|
||||
|
||||
// Create two switched panels with their own sizers
|
||||
m_sizer_simple = new wxBoxSizer(wxVERTICAL);
|
||||
m_sizer_advanced = new wxBoxSizer(wxVERTICAL);
|
||||
m_page_simple = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
|
||||
m_page_advanced = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
|
||||
m_page_simple->SetSizer(m_sizer_simple);
|
||||
m_page_advanced->SetSizer(m_sizer_advanced);
|
||||
|
||||
update_ui(m_page_simple);
|
||||
update_ui(m_page_advanced);
|
||||
|
||||
auto gridsizer_simple = new wxGridSizer(3, 5, 10);
|
||||
m_gridsizer_advanced = new wxGridSizer(m_number_of_extruders+1, 5, 1);
|
||||
|
||||
// First create controls for advanced mode and assign them to m_page_advanced:
|
||||
@ -322,57 +359,15 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, con
|
||||
}
|
||||
|
||||
// collect and format sizer
|
||||
format_sizer(m_sizer_advanced, m_page_advanced, m_gridsizer_advanced,
|
||||
_(L("Here you can adjust required purging volume (mm³) for any given pair of tools.")),
|
||||
_(L("Extruder changed to")));
|
||||
format_sizer(m_sizer_advanced, m_page_advanced, m_gridsizer_advanced, _(L("Extruder changed to")));
|
||||
|
||||
// Hide preview page before new page creating
|
||||
// It allows to do that from a beginning of the main panel
|
||||
m_page_advanced->Hide();
|
||||
|
||||
// Now the same for simple mode:
|
||||
gridsizer_simple->Add(new wxStaticText(m_page_simple, wxID_ANY, wxString("")), 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
|
||||
gridsizer_simple->Add(new wxStaticText(m_page_simple, wxID_ANY, wxString(_(L("unloaded")))), 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
|
||||
gridsizer_simple->Add(new wxStaticText(m_page_simple,wxID_ANY,wxString(_(L("loaded")))), 0, wxALIGN_CENTER | wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
auto add_spin_ctrl = [this](std::vector<::SpinInput*>& vec, float initial)
|
||||
{
|
||||
::SpinInput* spin_ctrl = new ::SpinInput(m_page_simple, "", wxEmptyString, wxDefaultPosition, wxSize(ITEM_WIDTH(), -1), style | wxALIGN_RIGHT, 0, 300, (int)initial);
|
||||
update_ui(spin_ctrl);
|
||||
vec.push_back(spin_ctrl);
|
||||
};
|
||||
|
||||
for (unsigned int i=0;i<m_number_of_extruders;++i) {
|
||||
add_spin_ctrl(m_old, extruders[2 * i]);
|
||||
add_spin_ctrl(m_new, extruders[2 * i+1]);
|
||||
|
||||
auto hsizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
wxWindow* w = new wxWindow(m_page_simple, wxID_ANY, wxDefaultPosition, icon_size, wxBORDER_SIMPLE);
|
||||
w->SetCanFocus(false);
|
||||
w->SetBackgroundColour(m_colours[i]);
|
||||
hsizer->Add(w, wxALIGN_CENTER_VERTICAL);
|
||||
hsizer->AddSpacer(10);
|
||||
hsizer->Add(new wxStaticText(m_page_simple, wxID_ANY, wxString(_(L("Tool #"))) << i + 1 << ": "), 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
gridsizer_simple->Add(hsizer, 1, wxEXPAND);
|
||||
gridsizer_simple->Add(m_old.back(),0);
|
||||
gridsizer_simple->Add(m_new.back(),0);
|
||||
}
|
||||
|
||||
// collect and format sizer
|
||||
format_sizer(m_sizer_simple, m_page_simple, gridsizer_simple,
|
||||
_(L("Total purging volume is calculated by summing two values below, depending on which tools are loaded/unloaded.")),
|
||||
_(L("Volume to purge (mm³) when the filament is being")), 50);
|
||||
|
||||
m_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_sizer->Add(m_page_simple, 0, wxEXPAND | wxALL, 25);
|
||||
m_sizer->Add(m_page_advanced, 0, wxEXPAND | wxALL, 25);
|
||||
m_sizer->Add(m_page_advanced, 0, wxEXPAND | wxALL, 5);
|
||||
|
||||
m_sizer->SetSizeHints(this);
|
||||
SetSizer(m_sizer);
|
||||
|
||||
toggle_advanced(); // to show/hide what is appropriate
|
||||
|
||||
m_page_advanced->Bind(wxEVT_PAINT,[this](wxPaintEvent&) {
|
||||
wxPaintDC dc(m_page_advanced);
|
||||
int y_pos = 0.5 * (edit_boxes[0][0]->GetPosition().y + edit_boxes[0][edit_boxes.size()-1]->GetPosition().y + edit_boxes[0][edit_boxes.size()-1]->GetSize().y);
|
||||
@ -380,7 +375,23 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, con
|
||||
int text_width = 0;
|
||||
int text_height = 0;
|
||||
dc.GetTextExtent(label,&text_width,&text_height);
|
||||
|
||||
int xpos = m_gridsizer_advanced->GetPosition().x;
|
||||
if (!m_page_advanced->IsEnabled()) {
|
||||
dc.SetTextForeground(wxSystemSettings::GetColour(
|
||||
#if defined (__linux__) && defined (__WXGTK2__)
|
||||
wxSYS_COLOUR_BTNTEXT
|
||||
#else
|
||||
wxSYS_COLOUR_GRAYTEXT
|
||||
#endif
|
||||
));
|
||||
dc.DrawRotatedText(label, xpos - text_height, y_pos + text_width / 2.f, 90);
|
||||
#ifdef _WIN32
|
||||
dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT));
|
||||
dc.DrawRotatedText(label, xpos - text_height-1, y_pos + text_width / 2.f+1, 90);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
dc.DrawRotatedText(label, xpos - text_height, y_pos + text_width / 2.f, 90);
|
||||
});
|
||||
}
|
||||
@ -390,8 +401,6 @@ WipingPanel::WipingPanel(wxWindow* parent, const std::vector<float>& matrix, con
|
||||
|
||||
// Reads values from the (advanced) wiping matrix:
|
||||
std::vector<float> WipingPanel::read_matrix_values() {
|
||||
if (!m_advanced)
|
||||
fill_in_matrix();
|
||||
std::vector<float> output;
|
||||
for (unsigned int i=0;i<m_number_of_extruders;++i) {
|
||||
for (unsigned int j=0;j<m_number_of_extruders;++j) {
|
||||
@ -403,60 +412,12 @@ std::vector<float> WipingPanel::read_matrix_values() {
|
||||
return output;
|
||||
}
|
||||
|
||||
// Reads values from simple mode to save them for next time:
|
||||
std::vector<float> WipingPanel::read_extruders_values() {
|
||||
std::vector<float> output;
|
||||
for (unsigned int i=0;i<m_number_of_extruders;++i) {
|
||||
output.push_back(m_old[i]->GetValue());
|
||||
output.push_back(m_new[i]->GetValue());
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
// This updates the "advanced" matrix based on values from "simple" mode
|
||||
void WipingPanel::fill_in_matrix() {
|
||||
for (unsigned i=0;i<m_number_of_extruders;++i) {
|
||||
for (unsigned j=0;j<m_number_of_extruders;++j) {
|
||||
if (i==j) continue;
|
||||
edit_boxes[j][i]->SetValue(wxString("")<< (m_old[i]->GetValue() + m_new[j]->GetValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Function to check if simple and advanced settings are matching
|
||||
bool WipingPanel::advanced_matches_simple() {
|
||||
for (unsigned i=0;i<m_number_of_extruders;++i) {
|
||||
for (unsigned j=0;j<m_number_of_extruders;++j) {
|
||||
if (i==j) continue;
|
||||
if (edit_boxes[j][i]->GetValue() != (wxString("")<< (m_old[i]->GetValue() + m_new[j]->GetValue())))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Switches the dialog from simple to advanced mode and vice versa
|
||||
void WipingPanel::toggle_advanced(bool user_action) {
|
||||
if (m_advanced && !advanced_matches_simple() && user_action) {
|
||||
if (MessageDialog(this, _L("Switching to simple settings will discard changes done in the advanced mode!\n\nDo you want to proceed?"),
|
||||
_L("Warning"),wxYES_NO|wxICON_EXCLAMATION).ShowModal() != wxID_YES)
|
||||
return;
|
||||
}
|
||||
if (user_action)
|
||||
m_advanced = !m_advanced; // user demands a change -> toggle
|
||||
else
|
||||
m_advanced = !advanced_matches_simple(); // if called from constructor, show what is appropriate
|
||||
|
||||
(m_advanced ? m_page_advanced : m_page_simple)->Show();
|
||||
(!m_advanced ? m_page_advanced : m_page_simple)->Hide();
|
||||
|
||||
m_widget_button->SetLabel(m_advanced ? _(L("Show simplified settings")) : _(L("Show advanced settings")));
|
||||
if (m_advanced)
|
||||
if (user_action) fill_in_matrix(); // otherwise keep values loaded from config
|
||||
|
||||
m_sizer->Layout();
|
||||
Refresh();
|
||||
void WipingDialog::enable_or_disable_panel()
|
||||
{
|
||||
bool enable = m_radio_button2->GetValue();
|
||||
m_info_text1->Enable(! enable);
|
||||
m_widget_button->Enable(enable);
|
||||
m_panel_wiping->Enable(enable);
|
||||
m_panel_wiping->Refresh();
|
||||
}
|
@ -51,29 +51,22 @@ private:
|
||||
|
||||
class WipingPanel : public wxPanel {
|
||||
public:
|
||||
WipingPanel(wxWindow* parent, const std::vector<float>& matrix, const std::vector<float>& extruders, const std::vector<std::string>& extruder_colours, wxButton* widget_button);
|
||||
WipingPanel(wxWindow* parent, const std::vector<float>& matrix, const std::vector<std::string>& extruder_colours,
|
||||
const std::vector<double>& filament_purging_multipliers, double printer_purging_volume, wxButton* widget_button);
|
||||
std::vector<float> read_matrix_values();
|
||||
std::vector<float> read_extruders_values();
|
||||
void toggle_advanced(bool user_action = false);
|
||||
void format_sizer(wxSizer* sizer, wxPanel* page, wxGridSizer* grid_sizer, const wxString& info, const wxString& table_title, int table_lshift=0);
|
||||
void format_sizer(wxSizer* sizer, wxPanel* page, wxGridSizer* grid_sizer, const wxString& table_title, int table_lshift=0);
|
||||
|
||||
private:
|
||||
void fill_in_matrix();
|
||||
bool advanced_matches_simple();
|
||||
|
||||
std::vector<::SpinInput*> m_old;
|
||||
std::vector<::SpinInput*> m_new;
|
||||
std::vector<std::vector<wxTextCtrl*>> edit_boxes;
|
||||
std::vector<wxColour> m_colours;
|
||||
unsigned int m_number_of_extruders = 0;
|
||||
bool m_advanced = false;
|
||||
wxPanel* m_page_simple = nullptr;
|
||||
wxPanel* m_page_advanced = nullptr;
|
||||
wxBoxSizer* m_sizer = nullptr;
|
||||
wxBoxSizer* m_sizer_simple = nullptr;
|
||||
wxBoxSizer* m_sizer_advanced = nullptr;
|
||||
wxGridSizer* m_gridsizer_advanced = nullptr;
|
||||
wxButton* m_widget_button = nullptr;
|
||||
double m_printer_purging_volume;
|
||||
std::vector<double> m_filament_purging_multipliers; // In percents !
|
||||
};
|
||||
|
||||
|
||||
@ -82,15 +75,21 @@ private:
|
||||
|
||||
class WipingDialog : public wxDialog {
|
||||
public:
|
||||
WipingDialog(wxWindow* parent, const std::vector<float>& matrix, const std::vector<float>& extruders, const std::vector<std::string>& extruder_colours);
|
||||
WipingDialog(wxWindow* parent, const std::vector<float>& matrix, const std::vector<std::string>& extruder_colours,
|
||||
double printer_purging_volume, const std::vector<double>& filament_purging_multipliers, bool use_custom_matrix);
|
||||
std::vector<float> get_matrix() const { return m_output_matrix; }
|
||||
std::vector<float> get_extruders() const { return m_output_extruders; }
|
||||
bool get_use_custom_matrix() const { return m_radio_button2->GetValue(); }
|
||||
|
||||
|
||||
private:
|
||||
void enable_or_disable_panel();
|
||||
|
||||
WipingPanel* m_panel_wiping = nullptr;
|
||||
std::vector<float> m_output_matrix;
|
||||
std::vector<float> m_output_extruders;
|
||||
wxRadioButton* m_radio_button1 = nullptr;
|
||||
wxRadioButton* m_radio_button2 = nullptr;
|
||||
wxButton* m_widget_button = nullptr;
|
||||
wxStaticText* m_info_text1 = nullptr;
|
||||
};
|
||||
|
||||
#endif // _WIPE_TOWER_DIALOG_H_
|
Loading…
x
Reference in New Issue
Block a user