diff --git a/src/libslic3r/GCode/PreviewData.cpp b/src/libslic3r/GCode/PreviewData.cpp index e99eeac02..cd6be3db1 100644 --- a/src/libslic3r/GCode/PreviewData.cpp +++ b/src/libslic3r/GCode/PreviewData.cpp @@ -479,14 +479,17 @@ GCodePreviewData::LegendItemsList GCodePreviewData::get_legend_items(const std:: } case Extrusion::ColorPrint: { - const auto color_print_cnt = cp_values.size(); - 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 size_t color_cnt = tool_colors.size()/4; + 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) { items.emplace_back(Slic3r::I18N::translate(L("Default print color")), color); break; @@ -521,6 +524,12 @@ size_t GCodePreviewData::memory_used() const sizeof(shell) + sizeof(ranges); } +const std::vector& GCodePreviewData::ColorPrintColors() +{ + static std::vector color_print = {"#C0392B", "#E67E22", "#F1C40F", "#27AE60", "#1ABC9C", "#2980B9", "#9B59B6"}; + return color_print; +} + 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]), diff --git a/src/libslic3r/GCode/PreviewData.hpp b/src/libslic3r/GCode/PreviewData.hpp index 4ca579d9a..e934dc80a 100644 --- a/src/libslic3r/GCode/PreviewData.hpp +++ b/src/libslic3r/GCode/PreviewData.hpp @@ -216,6 +216,8 @@ public: // Return an estimate of the memory consumed by the time estimator. size_t memory_used() const; + + static const std::vector& ColorPrintColors(); }; GCodePreviewData::Color operator + (const GCodePreviewData::Color& c1, const GCodePreviewData::Color& c2); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 7366516d1..97462ef86 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3742,14 +3742,9 @@ GLCanvas3D::LegendTexture::LegendTexture() { } -bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, const std::vector& 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>& cp_legend_values) { - reset(); - - // collects items to render - auto title = _(preview_data.get_legend_title()); - - std::vector> cp_legend_values; if (preview_data.extrusion.view_type == GCodePreviewData::Extrusion::ColorPrint) { 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& tool_colors, const GLCanvas3D& canvas, bool use_error_colors) +{ + reset(); + + // collects items to render + auto title = _(preview_data.get_legend_title()); + + std::vector> 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(); if (items_count == 0) @@ -4961,7 +4968,7 @@ void GLCanvas3D::load_sla_preview() } } -void GLCanvas3D::load_preview(const std::vector& str_tool_colors) +void GLCanvas3D::load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values) { const Print *print = this->fff_print(); if (print == nullptr) @@ -4972,7 +4979,7 @@ void GLCanvas3D::load_preview(const std::vector& str_tool_colors) for (const PrintObject* object : print->objects()) { 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) @@ -4982,7 +4989,14 @@ void GLCanvas3D::load_preview(const std::vector& str_tool_colors) _update_toolpath_volumes_outside_state(); _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 tool_colors = _parse_colors(str_tool_colors); + _generate_legend_texture(preview_data, tool_colors); + } } 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); } -void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors) +void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, const std::vector& color_print_values) { std::vector 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_support; const std::vector* tool_colors; + const std::vector* color_print_values; // Number of vertices (each vertex is 6x4=24 bytes long) 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(this->number_tools() - 1, std::max(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.has_perimeters = print_object.is_step_done(posPerimeters); ctxt.has_infill = print_object.is_step_done(posInfill); ctxt.has_support = print_object.is_step_done(posSupportMaterial); 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(); @@ -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"; //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; auto new_volume = [this, &new_volume_mutex](const float *color) -> GLVolume* { auto *volume = new GLVolume(color); @@ -7311,7 +7351,9 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c tbb::blocked_range(0, ctxt.layers.size(), grain_size), [&ctxt, &new_volume](const tbb::blocked_range& range) { 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) 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: { + const size_t color_cnt = tool_colors.size() / 4; + int val = int(value); - while (val >= GCodePreviewData::Range::Colors_Count) - val -= GCodePreviewData::Range::Colors_Count; + while (val >= color_cnt) + 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; } default: diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 8bdbf89b0..7d38e5128 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -857,6 +857,8 @@ private: public: LegendTexture(); + void fill_color_print_legend_values(const GCodePreviewData& preview_data, const GLCanvas3D& canvas, + std::vector>& cp_legend_values); bool generate(const GCodePreviewData& preview_data, const std::vector& 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& str_tool_colors); void load_sla_preview(); - void load_preview(const std::vector& str_tool_colors); - + void load_preview(const std::vector& str_tool_colors, const std::vector& color_print_values); void bind_event_handlers(); void unbind_event_handlers(); @@ -1133,7 +1134,8 @@ private: // Create 3D thick extrusion lines for object forming extrusions. // Adds a new Slic3r::GUI::3DScene::Volume to $self->volumes, // one for perimeters, one for infill and one for supports. - void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors); + void _load_print_object_toolpaths(const PrintObject& print_object, const std::vector& str_tool_colors, + const std::vector& color_print_values); // Create 3D thick extrusion lines for wipe tower extrusions void _load_wipe_tower_toolpaths(const std::vector& str_tool_colors); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 53ca52cb6..eb35aa61e 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -558,6 +558,7 @@ void Preview::create_double_slider() m_gcode_preview_data->extrusion.view_type = (GCodePreviewData::Extrusion::EViewType)type; m_preferred_color_mode = "feature"; } + reload_print(); }); } @@ -728,10 +729,19 @@ void Preview::load_print_as_fff() 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. std::vector colors; - bool gcode_preview_data_valid = print->is_step_done(psGCodeExport) && ! m_gcode_preview_data->empty(); - if (gcode_preview_data_valid || (m_gcode_preview_data->extrusion.view_type == GCodePreviewData::Extrusion::Tool)) + std::vector color_print_values = {}; + // 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("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(m_config->option("extruder_colour")); const ConfigOptionStrings* filamemts_opt = dynamic_cast(m_config->option("filament_colour")); @@ -750,6 +760,8 @@ void Preview::load_print_as_fff() colors.push_back(color); } + if (!color_print_values.empty()) + color_print_values.clear(); } if (IsShown()) @@ -759,7 +771,7 @@ void Preview::load_print_as_fff() m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); else // 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"); // recalculates zs and update sliders accordingly std::vector zs = m_canvas->get_current_print_zs(true); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 827dcc696..238a36c74 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -1668,7 +1668,7 @@ void PrusaDoubleSlider::render() // draw colored band on the background of a scroll line // and only in a case of no-empty m_values - draw_colored_band(dc); +// draw_colored_band(dc); // draw line draw_scroll_line(dc, lower_pos, higher_pos);