mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-10 08:17:51 -06:00
Random extruder sequence for MMU.
Related to https://github.com/prusa3d/PrusaSlicer/issues/1866
This commit is contained in:
parent
a2788f3a73
commit
0b5ea8f429
4 changed files with 65 additions and 13 deletions
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <boost/algorithm/string/replace.hpp>
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
|
#include <random>
|
||||||
#include "Field.hpp"
|
#include "Field.hpp"
|
||||||
#include "format.hpp"
|
#include "format.hpp"
|
||||||
#include "NotificationManager.hpp"
|
#include "NotificationManager.hpp"
|
||||||
|
@ -2394,22 +2395,42 @@ void Control::edit_extruder_sequence()
|
||||||
|
|
||||||
m_ticks.erase_all_ticks_with_code(ToolChange);
|
m_ticks.erase_all_ticks_with_code(ToolChange);
|
||||||
|
|
||||||
|
const int extr_cnt = m_extruders_sequence.extruders.size();
|
||||||
|
if (extr_cnt == 1)
|
||||||
|
return;
|
||||||
|
|
||||||
int tick = 0;
|
int tick = 0;
|
||||||
double value = 0.0;
|
double value = 0.0;
|
||||||
int extruder = 0;
|
int extruder = -1;
|
||||||
const int extr_cnt = m_extruders_sequence.extruders.size();
|
|
||||||
|
std::random_device rd; //Will be used to obtain a seed for the random number engine
|
||||||
|
std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd()
|
||||||
|
std::uniform_int_distribution<> distrib(0, extr_cnt-1);
|
||||||
|
|
||||||
while (tick <= m_max_value)
|
while (tick <= m_max_value)
|
||||||
{
|
{
|
||||||
|
bool color_repetition = false;
|
||||||
|
if (m_extruders_sequence.random_sequence) {
|
||||||
|
int rand_extr = distrib(gen);
|
||||||
|
if (m_extruders_sequence.color_repetition)
|
||||||
|
color_repetition = rand_extr == extruder;
|
||||||
|
else
|
||||||
|
while (rand_extr == extruder)
|
||||||
|
rand_extr = distrib(gen);
|
||||||
|
extruder = rand_extr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
extruder++;
|
||||||
|
if (extruder == extr_cnt)
|
||||||
|
extruder = 0;
|
||||||
|
}
|
||||||
|
|
||||||
const int cur_extruder = m_extruders_sequence.extruders[extruder];
|
const int cur_extruder = m_extruders_sequence.extruders[extruder];
|
||||||
|
|
||||||
bool meaningless_tick = tick == 0.0 && cur_extruder == extruder;
|
bool meaningless_tick = tick == 0.0 && cur_extruder == extruder;
|
||||||
if (!meaningless_tick)
|
if (!meaningless_tick && !color_repetition)
|
||||||
m_ticks.ticks.emplace(TickCode{tick, ToolChange,cur_extruder + 1, m_extruder_colors[cur_extruder]});
|
m_ticks.ticks.emplace(TickCode{tick, ToolChange,cur_extruder + 1, m_extruder_colors[cur_extruder]});
|
||||||
|
|
||||||
extruder++;
|
|
||||||
if (extruder == extr_cnt)
|
|
||||||
extruder = 0;
|
|
||||||
if (m_extruders_sequence.is_mm_intervals) {
|
if (m_extruders_sequence.is_mm_intervals) {
|
||||||
value += m_extruders_sequence.interval_by_mm;
|
value += m_extruders_sequence.interval_by_mm;
|
||||||
tick = get_tick_from_value(value, true);
|
tick = get_tick_from_value(value, true);
|
||||||
|
|
|
@ -146,6 +146,8 @@ struct ExtrudersSequence
|
||||||
bool is_mm_intervals = true;
|
bool is_mm_intervals = true;
|
||||||
double interval_by_mm = 3.0;
|
double interval_by_mm = 3.0;
|
||||||
int interval_by_layers = 10;
|
int interval_by_layers = 10;
|
||||||
|
bool random_sequence { true };
|
||||||
|
bool color_repetition { false };
|
||||||
std::vector<size_t> extruders = { 0 };
|
std::vector<size_t> extruders = { 0 };
|
||||||
|
|
||||||
bool operator==(const ExtrudersSequence& other) const
|
bool operator==(const ExtrudersSequence& other) const
|
||||||
|
@ -153,19 +155,23 @@ struct ExtrudersSequence
|
||||||
return (other.is_mm_intervals == this->is_mm_intervals ) &&
|
return (other.is_mm_intervals == this->is_mm_intervals ) &&
|
||||||
(other.interval_by_mm == this->interval_by_mm ) &&
|
(other.interval_by_mm == this->interval_by_mm ) &&
|
||||||
(other.interval_by_layers == this->interval_by_layers ) &&
|
(other.interval_by_layers == this->interval_by_layers ) &&
|
||||||
|
(other.random_sequence == this->random_sequence ) &&
|
||||||
|
(other.color_repetition == this->color_repetition ) &&
|
||||||
(other.extruders == this->extruders ) ;
|
(other.extruders == this->extruders ) ;
|
||||||
}
|
}
|
||||||
bool operator!=(const ExtrudersSequence& other) const
|
bool operator!=(const ExtrudersSequence& other) const
|
||||||
{
|
{
|
||||||
return (other.is_mm_intervals != this->is_mm_intervals ) &&
|
return (other.is_mm_intervals != this->is_mm_intervals ) ||
|
||||||
(other.interval_by_mm != this->interval_by_mm ) &&
|
(other.interval_by_mm != this->interval_by_mm ) ||
|
||||||
(other.interval_by_layers != this->interval_by_layers ) &&
|
(other.interval_by_layers != this->interval_by_layers ) ||
|
||||||
|
(other.random_sequence != this->random_sequence ) ||
|
||||||
|
(other.color_repetition != this->color_repetition ) ||
|
||||||
(other.extruders != this->extruders ) ;
|
(other.extruders != this->extruders ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_extruder(size_t pos)
|
void add_extruder(size_t pos, size_t extruder_id = size_t(0))
|
||||||
{
|
{
|
||||||
extruders.insert(extruders.begin() + pos+1, size_t(0));
|
extruders.insert(extruders.begin() + pos+1, extruder_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void delete_extruder(size_t pos)
|
void delete_extruder(size_t pos)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <wx/dialog.h>
|
#include <wx/dialog.h>
|
||||||
#include <wx/sizer.h>
|
#include <wx/sizer.h>
|
||||||
#include <wx/bmpcbox.h>
|
#include <wx/bmpcbox.h>
|
||||||
|
#include <wx/checkbox.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
@ -138,6 +139,18 @@ ExtruderSequenceDialog::ExtruderSequenceDialog(const DoubleSlider::ExtrudersSequ
|
||||||
intervals_box_sizer->Add(m_intervals_grid_sizer, 0, wxLEFT, em);
|
intervals_box_sizer->Add(m_intervals_grid_sizer, 0, wxLEFT, em);
|
||||||
option_sizer->Add(intervals_box_sizer, 0, wxEXPAND);
|
option_sizer->Add(intervals_box_sizer, 0, wxEXPAND);
|
||||||
|
|
||||||
|
m_random_sequence = new wxCheckBox(this, wxID_ANY, "Random sequence");
|
||||||
|
m_random_sequence->SetValue(m_sequence.random_sequence);
|
||||||
|
m_random_sequence->SetToolTip(_L("If enabled, random sequence of the selected extruders will be used."));
|
||||||
|
m_random_sequence->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& e) {
|
||||||
|
m_sequence.random_sequence = e.IsChecked();
|
||||||
|
m_color_repetition->Enable(m_sequence.random_sequence);
|
||||||
|
});
|
||||||
|
|
||||||
|
m_color_repetition = new wxCheckBox(this, wxID_ANY, "Allow next color repetition");
|
||||||
|
m_color_repetition->SetValue(m_sequence.color_repetition);
|
||||||
|
m_color_repetition->SetToolTip(_L("If enabled, a repetition of the next random color will be allowed."));
|
||||||
|
m_color_repetition->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& e) {m_sequence.color_repetition = e.IsChecked(); });
|
||||||
|
|
||||||
auto extruders_box = new wxStaticBox(this, wxID_ANY, _(L("Set extruder(tool) sequence"))+ ": ");
|
auto extruders_box = new wxStaticBox(this, wxID_ANY, _(L("Set extruder(tool) sequence"))+ ": ");
|
||||||
auto extruders_box_sizer = new wxStaticBoxSizer(extruders_box, wxVERTICAL);
|
auto extruders_box_sizer = new wxStaticBoxSizer(extruders_box, wxVERTICAL);
|
||||||
|
@ -147,6 +160,8 @@ ExtruderSequenceDialog::ExtruderSequenceDialog(const DoubleSlider::ExtrudersSequ
|
||||||
apply_extruder_sequence();
|
apply_extruder_sequence();
|
||||||
|
|
||||||
extruders_box_sizer->Add(m_extruders_grid_sizer, 0, wxALL, em);
|
extruders_box_sizer->Add(m_extruders_grid_sizer, 0, wxALL, em);
|
||||||
|
extruders_box_sizer->Add(m_random_sequence, 0, wxLEFT | wxBOTTOM, em);
|
||||||
|
extruders_box_sizer->Add(m_color_repetition, 0, wxLEFT | wxBOTTOM, em);
|
||||||
option_sizer->Add(extruders_box_sizer, 0, wxEXPAND | wxTOP, em);
|
option_sizer->Add(extruders_box_sizer, 0, wxEXPAND | wxTOP, em);
|
||||||
|
|
||||||
main_sizer->Add(option_sizer, 0, wxEXPAND | wxALL, em);
|
main_sizer->Add(option_sizer, 0, wxEXPAND | wxALL, em);
|
||||||
|
@ -197,8 +212,11 @@ void ExtruderSequenceDialog::apply_extruder_sequence()
|
||||||
auto add_btn = new ScalableButton(this, wxID_ANY, m_bmp_add);
|
auto add_btn = new ScalableButton(this, wxID_ANY, m_bmp_add);
|
||||||
add_btn->SetToolTip(_(L("Add extruder to sequence")));
|
add_btn->SetToolTip(_(L("Add extruder to sequence")));
|
||||||
|
|
||||||
add_btn->Bind(wxEVT_BUTTON, [this, extruder](wxEvent&) {
|
add_btn->Bind(wxEVT_BUTTON, [this, extruder, extruder_selector](wxEvent&) {
|
||||||
m_sequence.add_extruder(extruder);
|
size_t extr_cnt = (size_t)extruder_selector->GetCount();
|
||||||
|
size_t seq_extr_cnt = m_sequence.extruders.size();
|
||||||
|
size_t extr_id = seq_extr_cnt - size_t(seq_extr_cnt / extr_cnt) * extr_cnt;
|
||||||
|
m_sequence.add_extruder(extruder, std::min(extr_id, extr_cnt-1));
|
||||||
apply_extruder_sequence();
|
apply_extruder_sequence();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -208,6 +226,10 @@ void ExtruderSequenceDialog::apply_extruder_sequence()
|
||||||
}
|
}
|
||||||
m_extruders_grid_sizer->ShowItems(true); // show items hidden in apply_extruder_selector()
|
m_extruders_grid_sizer->ShowItems(true); // show items hidden in apply_extruder_selector()
|
||||||
|
|
||||||
|
bool show_checkboxes = m_sequence.extruders.size() > 1;
|
||||||
|
m_random_sequence->Enable(show_checkboxes);
|
||||||
|
m_color_repetition->Enable(show_checkboxes && m_sequence.random_sequence);
|
||||||
|
|
||||||
Fit();
|
Fit();
|
||||||
Refresh();
|
Refresh();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
class wxTextCtrl;
|
class wxTextCtrl;
|
||||||
class wxFlexGridSizer;
|
class wxFlexGridSizer;
|
||||||
|
class wxCheckBox;
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
@ -22,6 +23,8 @@ class ExtruderSequenceDialog: public DPIDialog
|
||||||
|
|
||||||
wxTextCtrl* m_interval_by_layers {nullptr};
|
wxTextCtrl* m_interval_by_layers {nullptr};
|
||||||
wxTextCtrl* m_interval_by_mm {nullptr};
|
wxTextCtrl* m_interval_by_mm {nullptr};
|
||||||
|
wxCheckBox* m_random_sequence {nullptr};
|
||||||
|
wxCheckBox* m_color_repetition{nullptr};
|
||||||
|
|
||||||
wxFlexGridSizer* m_intervals_grid_sizer {nullptr};
|
wxFlexGridSizer* m_intervals_grid_sizer {nullptr};
|
||||||
wxFlexGridSizer* m_extruders_grid_sizer {nullptr};
|
wxFlexGridSizer* m_extruders_grid_sizer {nullptr};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue