Implemented "Color Print" for preview mode (without re-slicing)

This commit is contained in:
YuSanka 2019-01-29 15:11:29 +01:00
parent b0ecf07e9b
commit e291172e24
6 changed files with 102 additions and 31 deletions

View File

@ -479,14 +479,17 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std::
} }
case Extrusion::ColorPrint: case Extrusion::ColorPrint:
{ {
const auto color_print_cnt = cp_values.size(); const size_t color_cnt = tool_colors.size()/4;
for (int i = color_print_cnt; i >= 0 ; --i)
{
int val = i;
while (val >= GCodePreviewData::Range::Colors_Count)
val -= GCodePreviewData::Range::Colors_Count;
GCodePreviewData::Color color = Range::Default_Colors[val];
const auto color_print_cnt = cp_values.size();
for (size_t i = color_print_cnt; i >= 0 ; --i)
{
size_t val = i;
while (val >= color_cnt)
val -= color_cnt;
GCodePreviewData::Color color;
::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + val * 4), 4 * sizeof(float));
if (color_print_cnt == 0) { if (color_print_cnt == 0) {
items.emplace_back(Slic3r::I18N::translate(L("Default print color")), color); items.emplace_back(Slic3r::I18N::translate(L("Default print color")), color);
break; break;
@ -521,6 +524,12 @@ size_t GCodePreviewData::memory_used() const
sizeof(shell) + sizeof(ranges); sizeof(shell) + sizeof(ranges);
} }
const std::vector<std::string>& GCodePreviewData::ColorPrintColors()
{
static std::vector<std::string> color_print = {"#C0392B", "#E67E22", "#F1C40F", "#27AE60", "#1ABC9C", "#2980B9", "#9B59B6"};
return color_print;
}
GCodePreviewData::Color operator + (const GCodePreviewData::Color& c1, const GCodePreviewData::Color& c2) GCodePreviewData::Color operator + (const GCodePreviewData::Color& c1, const GCodePreviewData::Color& c2)
{ {
return GCodePreviewData::Color(clamp(0.0f, 1.0f, c1.rgba[0] + c2.rgba[0]), return GCodePreviewData::Color(clamp(0.0f, 1.0f, c1.rgba[0] + c2.rgba[0]),

View File

@ -216,6 +216,8 @@ public:
// Return an estimate of the memory consumed by the time estimator. // Return an estimate of the memory consumed by the time estimator.
size_t memory_used() const; size_t memory_used() const;
static const std::vector<std::string>& ColorPrintColors();
}; };
GCodePreviewData::Color operator + (const GCodePreviewData::Color& c1, const GCodePreviewData::Color& c2); GCodePreviewData::Color operator + (const GCodePreviewData::Color& c1, const GCodePreviewData::Color& c2);

View File

@ -3742,14 +3742,9 @@ GLCanvas3D::LegendTexture::LegendTexture()
{ {
} }
bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors, const GLCanvas3D& canvas, bool use_error_colors) void GLCanvas3D::LegendTexture::fill_color_print_legend_values(const GCodePreviewData& preview_data, const GLCanvas3D& canvas,
std::vector<std::pair<double, double>>& cp_legend_values)
{ {
reset();
// collects items to render
auto title = _(preview_data.get_legend_title());
std::vector<std::pair<double, double>> cp_legend_values;
if (preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint) if (preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint)
{ {
const auto& config = wxGetApp().preset_bundle->full_config(); const auto& config = wxGetApp().preset_bundle->full_config();
@ -3773,7 +3768,19 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c
} }
} }
} }
const GCodePreviewData::LegendItemsList& items = preview_data.get_legend_items(tool_colors, /*color_print_values*/cp_legend_values); }
bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors, const GLCanvas3D& canvas, bool use_error_colors)
{
reset();
// collects items to render
auto title = _(preview_data.get_legend_title());
std::vector<std::pair<double, double>> cp_legend_values;
fill_color_print_legend_values(preview_data, canvas, cp_legend_values);
const GCodePreviewData::LegendItemsList& items = preview_data.get_legend_items(tool_colors, cp_legend_values);
unsigned int items_count = (unsigned int)items.size(); unsigned int items_count = (unsigned int)items.size();
if (items_count == 0) if (items_count == 0)
@ -4961,7 +4968,7 @@ void GLCanvas3D::load_sla_preview()
} }
} }
void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors) void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<double>& color_print_values)
{ {
const Print *print = this->fff_print(); const Print *print = this->fff_print();
if (print == nullptr) if (print == nullptr)
@ -4972,7 +4979,7 @@ void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors)
for (const PrintObject* object : print->objects()) for (const PrintObject* object : print->objects())
{ {
if (object != nullptr) if (object != nullptr)
_load_print_object_toolpaths(*object, str_tool_colors); _load_print_object_toolpaths(*object, str_tool_colors, color_print_values);
} }
for (GLVolume* volume : m_volumes.volumes) for (GLVolume* volume : m_volumes.volumes)
@ -4982,7 +4989,14 @@ void GLCanvas3D::load_preview(const std::vector<std::string>& str_tool_colors)
_update_toolpath_volumes_outside_state(); _update_toolpath_volumes_outside_state();
_show_warning_texture_if_needed(); _show_warning_texture_if_needed();
reset_legend_texture(); if (color_print_values.empty())
reset_legend_texture();
else {
auto preview_data = GCodePreviewData();
preview_data.extrusion.view_type = GCodePreviewData::Extrusion::ColorPrint;
const std::vector<float> tool_colors = _parse_colors(str_tool_colors);
_generate_legend_texture(preview_data, tool_colors);
}
} }
void GLCanvas3D::bind_event_handlers() void GLCanvas3D::bind_event_handlers()
@ -7235,7 +7249,7 @@ void GLCanvas3D::_load_print_toolpaths()
volume.indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized); volume.indexed_vertex_array.finalize_geometry(m_use_VBOs && m_initialized);
} }
void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector<std::string>& str_tool_colors) 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)
{ {
std::vector<float> tool_colors = _parse_colors(str_tool_colors); std::vector<float> tool_colors = _parse_colors(str_tool_colors);
@ -7247,6 +7261,7 @@ 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;
// Number of vertices (each vertex is 6x4=24 bytes long) // Number of vertices (each vertex is 6x4=24 bytes long)
static const size_t alloc_size_max() { return 131072; } // 3.15MB static const size_t alloc_size_max() { return 131072; } // 3.15MB
@ -7266,12 +7281,37 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
{ {
return this->color_by_tool() ? std::min<int>(this->number_tools() - 1, std::max<int>(extruder - 1, 0)) : feature; return this->color_by_tool() ? std::min<int>(this->number_tools() - 1, std::max<int>(extruder - 1, 0)) : feature;
} }
// For coloring by a color_print(M600), return a parsed color.
bool color_by_color_print() const { return color_print_values!=nullptr; }
const float* color_print_by_layer_idx(const size_t layer_idx) const
{
double z = layers[layer_idx]->print_z;
size_t layer = 0;
const size_t clr_change_cnt = color_print_values->size();
for (size_t i = 0; i < clr_change_cnt; i++)
{
if (z < (*color_print_values)[i]-EPSILON) {
layer = i;
break;
}
if (layer == 0 && i == clr_change_cnt - 1)
layer = clr_change_cnt;
}
const size_t clr_cnt = number_tools();
while (layer >= clr_cnt)
layer -= clr_cnt;
return color_tool(layer);
}
} ctxt; } ctxt;
ctxt.has_perimeters = print_object.is_step_done(posPerimeters); ctxt.has_perimeters = print_object.is_step_done(posPerimeters);
ctxt.has_infill = print_object.is_step_done(posInfill); ctxt.has_infill = print_object.is_step_done(posInfill);
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.shifted_copies = &print_object.copies(); ctxt.shifted_copies = &print_object.copies();
@ -7296,7 +7336,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - start"; BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - start";
//FIXME Improve the heuristics for a grain size. //FIXME Improve the heuristics for a grain size.
size_t grain_size = std::max(ctxt.layers.size() / 16, size_t(1)); size_t grain_size = ctxt.color_by_color_print() ? size_t(1) : std::max(ctxt.layers.size() / 16, size_t(1));
tbb::spin_mutex new_volume_mutex; tbb::spin_mutex new_volume_mutex;
auto new_volume = [this, &new_volume_mutex](const float *color) -> GLVolume* { auto new_volume = [this, &new_volume_mutex](const float *color) -> GLVolume* {
auto *volume = new GLVolume(color); auto *volume = new GLVolume(color);
@ -7311,7 +7351,9 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
tbb::blocked_range<size_t>(0, ctxt.layers.size(), grain_size), tbb::blocked_range<size_t>(0, ctxt.layers.size(), grain_size),
[&ctxt, &new_volume](const tbb::blocked_range<size_t>& range) { [&ctxt, &new_volume](const tbb::blocked_range<size_t>& range) {
GLVolumePtrs vols; GLVolumePtrs vols;
if (ctxt.color_by_tool()) { if (ctxt.color_by_color_print())
vols.emplace_back(new_volume(ctxt.color_print_by_layer_idx(range.begin())));
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)));
} }
@ -7629,11 +7671,15 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat
} }
case GCodePreviewData::Extrusion::ColorPrint: case GCodePreviewData::Extrusion::ColorPrint:
{ {
const size_t color_cnt = tool_colors.size() / 4;
int val = int(value); int val = int(value);
while (val >= GCodePreviewData::Range::Colors_Count) while (val >= color_cnt)
val -= GCodePreviewData::Range::Colors_Count; val -= color_cnt;
GCodePreviewData::Color color = GCodePreviewData::Range::Default_Colors[val]; GCodePreviewData::Color color;
::memcpy((void*)color.rgba, (const void*)(tool_colors.data() + val * 4), 4 * sizeof(float));
return color; return color;
} }
default: default:

View File

@ -857,6 +857,8 @@ private:
public: public:
LegendTexture(); LegendTexture();
void fill_color_print_legend_values(const GCodePreviewData& preview_data, const GLCanvas3D& canvas,
std::vector<std::pair<double, double>>& cp_legend_values);
bool generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors, const GLCanvas3D& canvas, bool use_error_colors); bool generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors, const GLCanvas3D& canvas, bool use_error_colors);
@ -1027,8 +1029,7 @@ 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); void load_preview(const std::vector<std::string>& str_tool_colors, const std::vector<double>& color_print_values);
void bind_event_handlers(); void bind_event_handlers();
void unbind_event_handlers(); void unbind_event_handlers();
@ -1133,7 +1134,8 @@ private:
// Create 3D thick extrusion lines for object forming extrusions. // Create 3D thick extrusion lines for object forming extrusions.
// 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);
// 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

@ -558,6 +558,7 @@ void Preview::create_double_slider()
m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type; m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type;
m_preferred_color_mode = "feature"; m_preferred_color_mode = "feature";
} }
reload_print();
}); });
} }
@ -728,10 +729,19 @@ void Preview::load_print_as_fff()
m_preferred_color_mode = "tool_or_feature"; m_preferred_color_mode = "tool_or_feature";
} }
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;
bool gcode_preview_data_valid = print->is_step_done(psGCodeExport) && ! m_gcode_preview_data->empty(); std::vector<double> color_print_values = {};
if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool)) // set color print values, if it si selected "ColorPrint" view type
if (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint)
{
colors = GCodePreviewData::ColorPrintColors();
const auto& config = wxGetApp().preset_bundle->full_config();
color_print_values = config.option<ConfigOptionFloats>("colorprint_heights")->values;
}
else if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool) )
{ {
const ConfigOptionStrings* extruders_opt = dynamic_cast<const ConfigOptionStrings*>(m_config->option("extruder_colour")); 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")); const ConfigOptionStrings* filamemts_opt = dynamic_cast<const ConfigOptionStrings*>(m_config->option("filament_colour"));
@ -750,6 +760,8 @@ void Preview::load_print_as_fff()
colors.push_back(color); colors.push_back(color);
} }
if (!color_print_values.empty())
color_print_values.clear();
} }
if (IsShown()) if (IsShown())
@ -759,7 +771,7 @@ void Preview::load_print_as_fff()
m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); m_canvas->load_gcode_preview(*m_gcode_preview_data, colors);
else else
// Load the initial preview based on slices, not the final G-code. // Load the initial preview based on slices, not the final G-code.
m_canvas->load_preview(colors); m_canvas->load_preview(colors, color_print_values);
show_hide_ui_elements(gcode_preview_data_valid ? "full" : "simple"); show_hide_ui_elements(gcode_preview_data_valid ? "full" : "simple");
// recalculates zs and update sliders accordingly // recalculates zs and update sliders accordingly
std::vector<double> zs = m_canvas->get_current_print_zs(true); std::vector<double> zs = m_canvas->get_current_print_zs(true);

View File

@ -1668,7 +1668,7 @@ void PrusaDoubleSlider::render()
// draw colored band on the background of a scroll line // draw colored band on the background of a scroll line
// and only in a case of no-empty m_values // and only in a case of no-empty m_values
draw_colored_band(dc); // draw_colored_band(dc);
// draw line // draw line
draw_scroll_line(dc, lower_pos, higher_pos); draw_scroll_line(dc, lower_pos, higher_pos);