Implemented coloration of multi-extruder print with color changes for separated extruder.

This commit is contained in:
YuSanka 2019-11-03 19:33:02 +01:00
parent 8d27cfd4a6
commit 674c6ce1c5
4 changed files with 142 additions and 16 deletions

View file

@ -2247,7 +2247,9 @@ void GLCanvas3D::load_sla_preview()
} }
} }
void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<double>& color_print_values) // #ys_FIXME_COLOR
// void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<double>& color_print_values)
void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<Model::CustomGCode>& color_print_values)
{ {
const Print *print = this->fff_print(); const Print *print = this->fff_print();
if (print == nullptr) if (print == nullptr)
@ -4675,7 +4677,9 @@ void GLCanvas3D::_load_print_toolpaths()
volume->indexed_vertex_array.finalize_geometry(m_initialized); volume->indexed_vertex_array.finalize_geometry(m_initialized);
} }
void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors, const std::vector<double>& color_print_values) // #ys_FIXME_COLOR
// void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors, const std::vector<double>& color_print_values)
void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors, const std::vector<Model::CustomGCode>& color_print_values)
{ {
std::vector<float> tool_colors = _parse_colors(str_tool_colors); std::vector<float> tool_colors = _parse_colors(str_tool_colors);
@ -4687,11 +4691,15 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
bool has_infill; bool has_infill;
bool has_support; bool has_support;
const std::vector<float>* tool_colors; const std::vector<float>* tool_colors;
const std::vector<double>* color_print_values; // #ys_FIXME_COLOR
// const std::vector<double>* color_print_values;
bool is_single_material_print;
const std::vector<Model::CustomGCode>* color_print_values;
static const float* color_perimeters() { static float color[4] = { 1.0f, 1.0f, 0.0f, 1.f }; return color; } // yellow static const float* color_perimeters() { static float color[4] = { 1.0f, 1.0f, 0.0f, 1.f }; return color; } // yellow
static const float* color_infill() { static float color[4] = { 1.0f, 0.5f, 0.5f, 1.f }; return color; } // redish static const float* color_infill() { static float color[4] = { 1.0f, 0.5f, 0.5f, 1.f }; return color; } // redish
static const float* color_support() { static float color[4] = { 0.5f, 1.0f, 0.5f, 1.f }; return color; } // greenish static const float* color_support() { static float color[4] = { 0.5f, 1.0f, 0.5f, 1.f }; return color; } // greenish
static const float* color_pause_or_custom_code() { static float color[4] = { 0.5f, 0.5f, 0.5f, 1.f }; return color; } // gray
// For cloring by a tool, return a parsed color. // For cloring by a tool, return a parsed color.
bool color_by_tool() const { return tool_colors != nullptr; } bool color_by_tool() const { return tool_colors != nullptr; }
@ -4701,9 +4709,26 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
// For coloring by a color_print(M600), return a parsed color. // For coloring by a color_print(M600), return a parsed color.
bool color_by_color_print() const { return color_print_values!=nullptr; } bool color_by_color_print() const { return color_print_values!=nullptr; }
const size_t color_print_color_idx_by_layer_idx(const size_t layer_idx) const { const size_t color_print_color_idx_by_layer_idx(const size_t layer_idx) const {
auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), layers[layer_idx]->print_z + EPSILON); // #ys_FIXME_COLOR
// auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), layers[layer_idx]->print_z + EPSILON);
const Model::CustomGCode value(layers[layer_idx]->print_z + EPSILON, "", 0);
auto it = std::lower_bound(color_print_values->begin(), color_print_values->end(), value);
return (it - color_print_values->begin()) % number_tools(); return (it - color_print_values->begin()) % number_tools();
} }
const bool pause_or_custom_code_layer(const size_t layer_idx) const
{
const coordf_t print_z = layers[layer_idx]->print_z;
auto it = std::find_if(color_print_values->begin(), color_print_values->end(),
[print_z](const Model::CustomGCode& code)
{ return fabs(code.height - print_z) < EPSILON; });
if (it == color_print_values->end())
return false;
const std::string& code = (*it).gcode;
return code == "M601" || (code != "M600" && code != "tool_change");
}
} ctxt; } ctxt;
ctxt.has_perimeters = print_object.is_step_done(posPerimeters); ctxt.has_perimeters = print_object.is_step_done(posPerimeters);
@ -4711,6 +4736,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
ctxt.has_support = print_object.is_step_done(posSupportMaterial); ctxt.has_support = print_object.is_step_done(posSupportMaterial);
ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors; ctxt.tool_colors = tool_colors.empty() ? nullptr : &tool_colors;
ctxt.color_print_values = color_print_values.empty() ? nullptr : &color_print_values; ctxt.color_print_values = color_print_values.empty() ? nullptr : &color_print_values;
ctxt.is_single_material_print = this->fff_print()->extruders().size()==1;
ctxt.shifted_copies = &print_object.copies(); ctxt.shifted_copies = &print_object.copies();
@ -4757,14 +4783,65 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
GLVolumePtrs vols; GLVolumePtrs vols;
std::vector<size_t> color_print_layer_to_glvolume; std::vector<size_t> color_print_layer_to_glvolume;
auto volume = [&ctxt, &vols, &color_print_layer_to_glvolume, &range](size_t layer_idx, int extruder, int feature) -> GLVolume& { auto volume = [&ctxt, &vols, &color_print_layer_to_glvolume, &range](size_t layer_idx, int extruder, int feature) -> GLVolume& {
return *vols[ctxt.color_by_color_print() ? if (ctxt.color_by_color_print() && !ctxt.is_single_material_print)
{
const coordf_t print_z = ctxt.layers[layer_idx]->print_z;
const std::vector<Model::CustomGCode>* cp_values = ctxt.color_print_values;
// pause print or custom Gcode
auto it = std::find_if(cp_values->begin(), cp_values->end(),
[print_z](const Model::CustomGCode& code)
{ return fabs(code.height - print_z) < EPSILON; });
if (it != cp_values->end())
{
const std::string& code = (*it).gcode;
if (code == "M601" || (code != "M600" && code != "tool_change"))
return *vols[ctxt.number_tools()];//*vols.back();
// change tool (extruder)
if (code == "tool_change")
return *vols[std::min<int>(ctxt.number_tools() - 1, std::max<int>(it->extruder - 1, 0))];
if (code == "M600" && it->extruder == extruder) {
int shift = 1;
while (it != cp_values->begin()) {
--it;
if (it->gcode == "M600")
shift++;
}
return *vols[ctxt.number_tools()+shift];
}
}
const Model::CustomGCode value(print_z + EPSILON, "", 0);
it = std::lower_bound(cp_values->begin(), cp_values->end(), value);
while (it != cp_values->begin())
{
--it;
const std::string& code = (*it).gcode;
if (code == "M600" && it->extruder == extruder) {
auto it_n = it;
int shift = 1;
while (it_n != cp_values->begin()) {
--it_n;
if (it_n->gcode == "M600")
shift++;
}
return *vols[ctxt.number_tools() + shift];
}
if (code == "tool_change")
return *vols[std::min<int>(ctxt.number_tools() - 1, std::max<int>((*it).extruder - 1, 0))];
}
return *vols[std::min<int>(ctxt.number_tools() - 1, std::max<int>(extruder - 1, 0))];
}
return *vols[ctxt.color_by_color_print() && ctxt.is_single_material_print ?
color_print_layer_to_glvolume[layer_idx - range.begin()] : color_print_layer_to_glvolume[layer_idx - range.begin()] :
ctxt.color_by_tool() ? ctxt.color_by_tool() ?
std::min<int>(ctxt.number_tools() - 1, std::max<int>(extruder - 1, 0)) : std::min<int>(ctxt.number_tools() - 1, std::max<int>(extruder - 1, 0)) :
feature feature
]; ];
}; };
if (ctxt.color_by_color_print()) { if (ctxt.color_by_color_print() && ctxt.is_single_material_print) {
// Create a map from the layer index to a GLVolume, which is initialized with the correct layer span color. // Create a map from the layer index to a GLVolume, which is initialized with the correct layer span color.
std::vector<int> color_print_tool_to_glvolume(ctxt.number_tools(), -1); std::vector<int> color_print_tool_to_glvolume(ctxt.number_tools(), -1);
color_print_layer_to_glvolume.reserve(range.end() - range.begin()); color_print_layer_to_glvolume.reserve(range.end() - range.begin());
@ -4778,6 +4855,25 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
color_print_layer_to_glvolume.emplace_back(color_print_tool_to_glvolume[idx_tool]); color_print_layer_to_glvolume.emplace_back(color_print_tool_to_glvolume[idx_tool]);
} }
} }
else if (ctxt.color_by_color_print() && !ctxt.is_single_material_print) {
for (size_t i = 0; i < ctxt.number_tools(); ++i)
vols.emplace_back(new_volume(ctxt.color_tool(i)));
vols.emplace_back(new_volume(ctxt.color_pause_or_custom_code()));
for ( auto it = ctxt.color_print_values->begin(); it < ctxt.color_print_values->end(); it++) {
if (it->gcode == "M600" && it->extruder != 0)
{
int cp_id = it - ctxt.color_print_values->begin() + 1;
float koef = fabs(1- cp_id * 0.1);
float color_f[4];
memcpy(color_f, ctxt.color_tool(it->extruder - 1), sizeof(float) * 4);
for (int i=0; i<3; i++)
color_f[i] = clamp(0.0f, 1.0f, koef * color_f[i]);
vols.emplace_back(new_volume(color_f));
}
}
}
else if (ctxt.color_by_tool()) { else if (ctxt.color_by_tool()) {
for (size_t i = 0; i < ctxt.number_tools(); ++i) for (size_t i = 0; i < ctxt.number_tools(); ++i)
vols.emplace_back(new_volume(ctxt.color_tool(i))); vols.emplace_back(new_volume(ctxt.color_tool(i)));

View file

@ -538,7 +538,9 @@ public:
void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector<std::string>& str_tool_colors); void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector<std::string>& str_tool_colors);
void load_sla_preview(); void load_sla_preview();
void load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<double>& color_print_values); // #ys_FIXME_COLOR
// void load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<double>& color_print_values);
void load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<Model::CustomGCode>& color_print_values);
void bind_event_handlers(); void bind_event_handlers();
void unbind_event_handlers(); void unbind_event_handlers();
@ -690,7 +692,10 @@ private:
// Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes, // Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes,
// one for perimeters, one for infill and one for supports. // one for perimeters, one for infill and one for supports.
void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors, void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors,
const std::vector<double>& color_print_values); const std::vector<Model::CustomGCode>& color_print_values);
// #ys_FIXME_COLOR
// void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors,
// const std::vector<double>& color_print_values);
// Create 3D thick extrusion lines for wipe tower extrusions // Create 3D thick extrusion lines for wipe tower extrusions
void _load_wipe_tower_toolpaths(const std::vector<std::string>& str_tool_colors); void _load_wipe_tower_toolpaths(const std::vector<std::string>& str_tool_colors);

View file

@ -878,19 +878,46 @@ void Preview::load_print_as_fff(bool keep_z_range)
bool gcode_preview_data_valid = print->is_step_done(psGCodeExport) && ! m_gcode_preview_data->empty(); bool gcode_preview_data_valid = print->is_step_done(psGCodeExport) && ! m_gcode_preview_data->empty();
// Collect colors per extruder. // Collect colors per extruder.
std::vector<std::string> colors; std::vector<std::string> colors;
std::vector<double> color_print_values = {}; // #ys_FIXME_COLOR
// std::vector<double> color_print_values = {};
std::vector<Model::CustomGCode> color_print_values = {};
// set color print values, if it si selected "ColorPrint" view type // set color print values, if it si selected "ColorPrint" view type
if (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint) if (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint)
{ {
colors = GCodePreviewData::ColorPrintColors(); unsigned int number_extruders = (unsigned int)print->extruders().size();
if (number_extruders == 1) // use GCodePreviewData::ColorPrintColors() just for Single-extruder printing
colors = GCodePreviewData::ColorPrintColors();
else
{
const ConfigOptionStrings* extruders_opt = dynamic_cast<const ConfigOptionStrings*>(m_config->option("extruder_colour"));
const ConfigOptionStrings* filamemts_opt = dynamic_cast<const ConfigOptionStrings*>(m_config->option("filament_colour"));
unsigned int colors_count = std::max((unsigned int)extruders_opt->values.size(), (unsigned int)filamemts_opt->values.size());
unsigned char rgb[3];
for (unsigned int i = 0; i < colors_count; ++i)
{
std::string color = m_config->opt_string("extruder_colour", i);
if (!PresetBundle::parse_color(color, rgb))
{
color = m_config->opt_string("filament_colour", i);
if (!PresetBundle::parse_color(color, rgb))
color = "#FFFFFF";
}
colors.emplace_back(color);
}
}
if (! gcode_preview_data_valid) { if (! gcode_preview_data_valid) {
// #ys_FIXME_COLOR // #ys_FIXME_COLOR
// const auto& config = wxGetApp().preset_bundle->project_config; // const auto& config = wxGetApp().preset_bundle->project_config;
// color_print_values = config.option<ConfigOptionFloats>("colorprint_heights")->values; // color_print_values = config.option<ConfigOptionFloats>("colorprint_heights")->values;
/*
const std::vector<Model::CustomGCode>& custom_codes = wxGetApp().plater()->model().custom_gcode_per_height; const std::vector<Model::CustomGCode>& custom_codes = wxGetApp().plater()->model().custom_gcode_per_height;
color_print_values.reserve(custom_codes.size()); color_print_values.reserve(custom_codes.size());
for (const Model::CustomGCode& code : custom_codes) for (const Model::CustomGCode& code : custom_codes)
color_print_values.push_back(code.height); color_print_values.push_back(code.height);
*/
color_print_values = wxGetApp().plater()->model().custom_gcode_per_height;
} }
} }
else if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool) ) else if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool) )

View file

@ -3241,13 +3241,11 @@ void DoubleSlider::OnLeftUp(wxMouseEvent& event)
const int extruders_cnt = Slic3r::GUI::wxGetApp().extruders_edited_cnt(); const int extruders_cnt = Slic3r::GUI::wxGetApp().extruders_edited_cnt();
if (extruders_cnt > 1) if (extruders_cnt > 1)
{ {
const int initial_extruder = get_extruder_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value);
wxMenu* add_color_change_menu = new wxMenu(); wxMenu* add_color_change_menu = new wxMenu();
for (int i = 1; i <= extruders_cnt; i++) for (int i = 1; i <= extruders_cnt; i++)
append_menu_radio_item(add_color_change_menu, wxID_ANY, wxString::Format(_(L("Extruder %d")), i), "", append_menu_item(add_color_change_menu, wxID_ANY, wxString::Format(_(L("Extruder %d")), i), "",
[this, i](wxCommandEvent&) { add_code("M600", i); }, &menu)->Check(i == initial_extruder); [this, i](wxCommandEvent&) { add_code("M600", i); }, "", &menu);
const wxString menu_name = from_u8((boost::format(_utf8(L("Add color change (%1%) for:"))) % "M600").str()); const wxString menu_name = from_u8((boost::format(_utf8(L("Add color change (%1%) for:"))) % "M600").str());
wxMenuItem* add_color_change_menu_item = menu.AppendSubMenu(add_color_change_menu, menu_name, ""); wxMenuItem* add_color_change_menu_item = menu.AppendSubMenu(add_color_change_menu, menu_name, "");
@ -3494,8 +3492,8 @@ void DoubleSlider::OnRightUp(wxMouseEvent& event)
if (i==0) // don't use M600 for default extruder, if multimaterial print is selected if (i==0) // don't use M600 for default extruder, if multimaterial print is selected
continue; continue;
append_menu_radio_item(add_color_change_menu, wxID_ANY, /*i == 0 ? _(L("current extruder")) : */item_name, "", append_menu_item(add_color_change_menu, wxID_ANY, item_name, "",
[this, i](wxCommandEvent&) { add_code("M600", i); }, &menu)->Check(i == initial_extruder); [this, i](wxCommandEvent&) { add_code("M600", i); }, "", &menu);
} }
wxMenuItem* change_extruder_menu_item = menu.AppendSubMenu(change_extruder_menu, _(L("Change extruder")), _(L("Use another extruder"))); wxMenuItem* change_extruder_menu_item = menu.AppendSubMenu(change_extruder_menu, _(L("Change extruder")), _(L("Use another extruder")));