From 160d9b018706d5d5cabc7e444125440def9614bc Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 12 Dec 2023 08:18:57 +0100 Subject: [PATCH] New gcode visualization integration - Modify pre-gcode preview to use the new toolpaths renderer, objects WIP --- src/libslic3r/BuildVolume.cpp | 8 +- src/libslic3r/BuildVolume.hpp | 6 + src/slic3r/GUI/GCodeViewer.cpp | 4 + src/slic3r/GUI/GLCanvas3D.cpp | 44 +-- src/slic3r/GUI/GLCanvas3D.hpp | 8 +- src/slic3r/GUI/GUI_Preview.cpp | 8 + src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.cpp | 308 +++++++++++++++--- src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.hpp | 3 +- .../GUI/LibVGCode/include/ColorRange.hpp | 2 +- 9 files changed, 301 insertions(+), 90 deletions(-) diff --git a/src/libslic3r/BuildVolume.cpp b/src/libslic3r/BuildVolume.cpp index 8df3161288..1de66561a1 100644 --- a/src/libslic3r/BuildVolume.cpp +++ b/src/libslic3r/BuildVolume.cpp @@ -343,7 +343,7 @@ bool BuildVolume::all_paths_inside(const GCodeProcessorResult& paths, const Boun const Vec2f c = unscaled(m_circle.center); const float r = unscaled(m_circle.radius) + epsilon; const float r2 = sqr(r); - return m_max_print_height == 0.0 ? + return m_max_print_height == 0.0 ? std::all_of(paths.moves.begin(), paths.moves.end(), [move_valid, c, r2](const GCodeProcessorResult::MoveVertex &move) { return ! move_valid(move) || (to_2d(move.position) - c).squaredNorm() <= r2; }) : std::all_of(paths.moves.begin(), paths.moves.end(), [move_valid, c, r2, z = m_max_print_height + epsilon](const GCodeProcessorResult::MoveVertex& move) @@ -374,6 +374,9 @@ inline bool all_inside_vertices_normals_interleaved(const std::vector &pa return true; } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ bool BuildVolume::all_paths_inside_vertices_and_normals_interleaved(const std::vector& paths, const Eigen::AlignedBox& paths_bbox, bool ignore_bottom) const { assert(paths.size() % 6 == 0); @@ -407,6 +410,9 @@ bool BuildVolume::all_paths_inside_vertices_and_normals_interleaved(const std::v return true; } } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::string_view BuildVolume::type_name(Type type) { diff --git a/src/libslic3r/BuildVolume.hpp b/src/libslic3r/BuildVolume.hpp index c02165ce79..ab5d390b03 100644 --- a/src/libslic3r/BuildVolume.hpp +++ b/src/libslic3r/BuildVolume.hpp @@ -95,8 +95,14 @@ public: // Called on final G-code paths. //FIXME The test does not take the thickness of the extrudates into account! bool all_paths_inside(const GCodeProcessorResult& paths, const BoundingBoxf3& paths_bbox, bool ignore_bottom = true) const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Called on initial G-code preview on OpenGL vertex buffer interleaved normals and vertices. bool all_paths_inside_vertices_and_normals_interleaved(const std::vector& paths, const Eigen::AlignedBox& bbox, bool ignore_bottom = true) const; +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ const std::pair, std::vector>& top_bottom_convex_hull_decomposition_scene() const { return m_top_bottom_convex_hull_decomposition_scene; } diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index e8082e1d21..8212efd867 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1346,6 +1346,10 @@ void GCodeViewer::load_as_preview(libvgcode::GCodeInputData&& data, const std::v m_new_viewer.set_tool_colors(colors); } m_new_viewer.load(std::move(data)); + + const libvgcode::AABox bbox = m_new_viewer.get_bounding_box(libvgcode::EBBoxType::Extrusion); + const BoundingBoxf3 paths_bounding_box(libvgcode::convert(bbox[0]).cast(), libvgcode::convert(bbox[1]).cast()); + m_contained_in_bed = wxGetApp().plater()->build_volume().all_paths_inside(GCodeProcessorResult(), paths_bounding_box); } #else //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 41dd3574f0..333d537b99 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2157,14 +2157,14 @@ const std::vector& GLCanvas3D::get_gcode_layers_zs() const return m_gcode_viewer.get_layers_zs(); } +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if !ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ std::vector GLCanvas3D::get_volumes_print_zs(bool active_only) const { return m_volumes.get_current_print_zs(active_only); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if !ENABLE_NEW_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GLCanvas3D::set_gcode_options_visibility_from_flags(unsigned int flags) { m_gcode_viewer.set_options_visibility_from_flags(flags); @@ -2764,27 +2764,21 @@ void GLCanvas3D::load_preview(const std::vector& str_tool_colors, c // Release OpenGL data before generating new data. this->reset_volumes(); - const BuildVolume &build_volume = m_bed.build_volume(); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if !ENABLE_NEW_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - _load_print_toolpaths(build_volume); - _load_wipe_tower_toolpaths(build_volume, str_tool_colors); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#endif // !ENABLE_NEW_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - for (const PrintObject* object : print->objects()) - _load_print_object_toolpaths(*object, build_volume, str_tool_colors, color_print_values); - //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #if ENABLE_NEW_GCODE_VIEWER - libvgcode::GCodeInputData data = libvgcode::convert(*print, str_tool_colors); - + libvgcode::GCodeInputData data = libvgcode::convert(*print, str_tool_colors, color_print_values, static_cast(wxGetApp().extruders_edited_cnt())); + // send data to the viewer m_gcode_viewer.enable_legend(false); m_gcode_viewer.load_as_preview(std::move(data), str_tool_colors); - - // TODO check build_volume <<<<<<<<<<<<<< +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + const BuildVolume& build_volume = m_bed.build_volume(); + _load_print_toolpaths(build_volume); + _load_wipe_tower_toolpaths(build_volume, str_tool_colors); + for (const PrintObject* object : print->objects()) + _load_print_object_toolpaths(*object, build_volume, str_tool_colors, color_print_values); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_NEW_GCODE_VIEWER //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ -6826,9 +6820,6 @@ void GLCanvas3D::_load_print_toolpaths(const BuildVolume &build_volume) volume->is_outside = !contains(build_volume, volume->model); } } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#endif // !ENABLE_NEW_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, const BuildVolume& build_volume, const std::vector& str_tool_colors, const std::vector& color_print_values) { @@ -6997,13 +6988,13 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c tbb::spin_mutex new_volume_mutex; auto new_volume = [this, &new_volume_mutex](const ColorRGBA& color) { // Allocate the volume before locking. - GLVolume *volume = new GLVolume(color); - volume->is_extrusion_path = true; + GLVolume *volume = new GLVolume(color); + volume->is_extrusion_path = true; // to prevent sending data to gpu (in the main thread) while // editing the model geometry volume->model.disable_render(); tbb::spin_mutex::scoped_lock lock; - // Lock by ROII, so if the emplace_back() fails, the lock will be released. + // Lock by ROII, so if the emplace_back() fails, the lock will be released. lock.acquire(new_volume_mutex); m_volumes.volumes.emplace_back(volume); lock.release(); @@ -7144,9 +7135,6 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c BOOST_LOG_TRIVIAL(debug) << "Loading print object toolpaths in parallel - end" << m_volumes.log_memory_info() << log_memory_info(); } -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if !ENABLE_NEW_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ void GLCanvas3D::_load_wipe_tower_toolpaths(const BuildVolume& build_volume, const std::vector& str_tool_colors) { const Print *print = this->fff_print(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index b0dcf2d7b4..b03c4938f8 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -857,10 +857,10 @@ public: unsigned int get_toolpath_role_visibility_flags() const { return m_gcode_viewer.get_toolpath_role_visibility_flags(); } void set_toolpath_role_visibility_flags(unsigned int flags); void set_toolpath_view_type(GCodeViewer::EViewType type); + std::vector get_volumes_print_zs(bool active_only) const; //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #endif // ENABLE_NEW_GCODE_VIEWER //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - std::vector get_volumes_print_zs(bool active_only) const; void set_volumes_z_range(const std::array& range); void set_toolpaths_z_range(const std::array& range); std::vector& get_custom_gcode_per_print_z() { return m_gcode_viewer.get_custom_gcode_per_print_z(); } @@ -1139,17 +1139,11 @@ private: // Create 3D thick extrusion lines for a skirt and brim. // Adds a new Slic3r::GUI::3DScene::Volume to volumes, updates collision with the build_volume. void _load_print_toolpaths(const BuildVolume &build_volume); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#endif // !ENABLE_NEW_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // 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, updates collision with the build_volume. void _load_print_object_toolpaths(const PrintObject& print_object, const BuildVolume &build_volume, const std::vector& str_tool_colors, const std::vector& color_print_values); -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -#if !ENABLE_NEW_GCODE_VIEWER -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // Create 3D thick extrusion lines for wipe tower extrusions, updates collision with the build_volume. void _load_wipe_tower_toolpaths(const BuildVolume &build_volume, const std::vector& str_tool_colors); //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 239eda5be3..364651c053 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -929,7 +929,15 @@ void Preview::load_print_as_fff(bool keep_z_range) m_left_sizer->Hide(m_bottom_toolbar_panel); m_left_sizer->Layout(); Refresh(); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#if ENABLE_NEW_GCODE_VIEWER + zs = m_canvas->get_gcode_layers_zs(); +#else +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ zs = m_canvas->get_volumes_print_zs(true); +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#endif // ENABLE_NEW_GCODE_VIEWER +//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } else { m_left_sizer->Hide(m_bottom_toolbar_panel); diff --git a/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.cpp b/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.cpp index 937114df42..eb09c4026a 100644 --- a/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.cpp +++ b/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.cpp @@ -236,8 +236,8 @@ GCodeInputData convert(const Slic3r::GCodeProcessorResult& result, float travels return ret; } -static void thick_lines_to_geometry(const Slic3r::Lines& lines, const std::vector& widths, const std::vector& heights, - float top_z, size_t layer_id, size_t extruder_id, size_t color_id, EGCodeExtrusionRole extrusion_role, bool closed, GCodeInputData& data) +static void convert_lines_to_vertices(const Slic3r::Lines& lines, const std::vector& widths, const std::vector& heights, + float top_z, size_t layer_id, size_t extruder_id, size_t color_id, EGCodeExtrusionRole extrusion_role, bool closed, std::vector& vertices) { if (lines.empty()) return; @@ -254,30 +254,22 @@ static void thick_lines_to_geometry(const Slic3r::Lines& lines, const std::vecto libvgcode::PathVertex vertex = { convert(Slic3r::Vec3f(a.x(), a.y(), top_z)), heights[i], widths[i], 0.0f, 0.0f, 0.0f, 0.0f, extrusion_role, EMoveType::Noop, 0, static_cast(layer_id), static_cast(extruder_id), static_cast(color_id), { 0.0f, 0.0f } }; - data.vertices.emplace_back(vertex); + vertices.emplace_back(vertex); // add the starting vertex of the segment vertex.type = EMoveType::Extrude; - data.vertices.emplace_back(vertex); - data.vertices.emplace_back(vertex); + vertices.emplace_back(vertex); } // add the ending vertex of the segment const Slic3r::Vec2f b = unscale(line.b).cast(); const libvgcode::PathVertex vertex = { convert(Slic3r::Vec3f(b.x(), b.y(), top_z)), heights[i], widths[i], 0.0f, 0.0f, 0.0f, 0.0f, extrusion_role, EMoveType::Extrude, 0, static_cast(layer_id), static_cast(extruder_id), static_cast(color_id), { 0.0f, 0.0f } }; - data.vertices.emplace_back(vertex); + vertices.emplace_back(vertex); } } -//static void thick_lines_to_verts(const Slic3r::Lines& lines, const std::vector& widths, const std::vector& heights, bool closed, -// double top_z, GCodeInputData& data) -//{ -// thick_lines_to_geometry(lines, widths, heights, closed, top_z, data); -//} - - -static void convert(const Slic3r::ExtrusionPath& extrusion_path, float print_z, size_t layer_id, size_t extruder_id, size_t color_id, - EGCodeExtrusionRole extrusion_role, const Slic3r::Point& shift, GCodeInputData& data) +static void convert_to_vertices(const Slic3r::ExtrusionPath& extrusion_path, float print_z, size_t layer_id, size_t extruder_id, size_t color_id, + EGCodeExtrusionRole extrusion_role, const Slic3r::Point& shift, std::vector& vertices) { Slic3r::Polyline polyline = extrusion_path.polyline; polyline.remove_duplicate_points(); @@ -285,11 +277,11 @@ static void convert(const Slic3r::ExtrusionPath& extrusion_path, float print_z, const Slic3r::Lines lines = polyline.lines(); std::vector widths(lines.size(), extrusion_path.width()); std::vector heights(lines.size(), extrusion_path.height()); - thick_lines_to_geometry(lines, widths, heights, print_z, layer_id, extruder_id, color_id, extrusion_role, false, data); + convert_lines_to_vertices(lines, widths, heights, print_z, layer_id, extruder_id, color_id, extrusion_role, false, vertices); } -static void convert(const Slic3r::ExtrusionMultiPath& extrusion_multi_path, float print_z, size_t layer_id, size_t extruder_id, - size_t color_id, EGCodeExtrusionRole extrusion_role, const Slic3r::Point& shift, GCodeInputData& data) +static void convert_to_vertices(const Slic3r::ExtrusionMultiPath& extrusion_multi_path, float print_z, size_t layer_id, size_t extruder_id, + size_t color_id, EGCodeExtrusionRole extrusion_role, const Slic3r::Point& shift, std::vector& vertices) { Slic3r::Lines lines; std::vector widths; @@ -303,11 +295,11 @@ static void convert(const Slic3r::ExtrusionMultiPath& extrusion_multi_path, floa widths.insert(widths.end(), lines_this.size(), extrusion_path.width()); heights.insert(heights.end(), lines_this.size(), extrusion_path.height()); } - thick_lines_to_geometry(lines, widths, heights, print_z, layer_id, extruder_id, color_id, extrusion_role, false, data); + convert_lines_to_vertices(lines, widths, heights, print_z, layer_id, extruder_id, color_id, extrusion_role, false, vertices); } -static void convert(const Slic3r::ExtrusionLoop& extrusion_loop, float print_z, size_t layer_id, size_t extruder_id, size_t color_id, - EGCodeExtrusionRole extrusion_role, const Slic3r::Point& shift, GCodeInputData& data) +static void convert_to_vertices(const Slic3r::ExtrusionLoop& extrusion_loop, float print_z, size_t layer_id, size_t extruder_id, size_t color_id, + EGCodeExtrusionRole extrusion_role, const Slic3r::Point& shift, std::vector& vertices) { Slic3r::Lines lines; std::vector widths; @@ -321,31 +313,31 @@ static void convert(const Slic3r::ExtrusionLoop& extrusion_loop, float print_z, widths.insert(widths.end(), lines_this.size(), extrusion_path.width()); heights.insert(heights.end(), lines_this.size(), extrusion_path.height()); } - thick_lines_to_geometry(lines, widths, heights, print_z, layer_id, extruder_id, color_id, extrusion_role, true, data); + convert_lines_to_vertices(lines, widths, heights, print_z, layer_id, extruder_id, color_id, extrusion_role, true, vertices); } // forward declaration -static void convert(const Slic3r::ExtrusionEntityCollection& extrusion_entity_collection, float print_z, size_t layer_id, - EGCodeExtrusionRole extrusion_role, const Slic3r::Point& shift, GCodeInputData& data); +static void convert_to_vertices(const Slic3r::ExtrusionEntityCollection& extrusion_entity_collection, float print_z, size_t layer_id, + size_t extruder_id, size_t color_id, EGCodeExtrusionRole extrusion_role, const Slic3r::Point& shift, std::vector& vertices); -static void convert(const Slic3r::ExtrusionEntity& extrusion_entity, float print_z, size_t layer_id, size_t extruder_id, size_t color_id, - EGCodeExtrusionRole extrusion_role, const Slic3r::Point& shift, GCodeInputData& data) +static void convert_to_vertices(const Slic3r::ExtrusionEntity& extrusion_entity, float print_z, size_t layer_id, size_t extruder_id, size_t color_id, + EGCodeExtrusionRole extrusion_role, const Slic3r::Point& shift, std::vector& vertices) { auto* extrusion_path = dynamic_cast(&extrusion_entity); if (extrusion_path != nullptr) - convert(*extrusion_path, print_z, layer_id, extruder_id, color_id, extrusion_role, shift, data); + convert_to_vertices(*extrusion_path, print_z, layer_id, extruder_id, color_id, extrusion_role, shift, vertices); else { auto* extrusion_loop = dynamic_cast(&extrusion_entity); if (extrusion_loop != nullptr) - convert(*extrusion_loop, print_z, layer_id, extruder_id, color_id, extrusion_role, shift, data); + convert_to_vertices(*extrusion_loop, print_z, layer_id, extruder_id, color_id, extrusion_role, shift, vertices); else { auto* extrusion_multi_path = dynamic_cast(&extrusion_entity); if (extrusion_multi_path != nullptr) - convert(*extrusion_multi_path, print_z, layer_id, extruder_id, color_id, extrusion_role, shift, data); + convert_to_vertices(*extrusion_multi_path, print_z, layer_id, extruder_id, color_id, extrusion_role, shift, vertices); else { auto* extrusion_entity_collection = dynamic_cast(&extrusion_entity); if (extrusion_entity_collection != nullptr) - convert(*extrusion_entity_collection, print_z, layer_id, extruder_id, color_id, extrusion_role, shift, data); + convert_to_vertices(*extrusion_entity_collection, print_z, layer_id, extruder_id, color_id, extrusion_role, shift, vertices); else throw Slic3r::RuntimeError("Found unexpected extrusion_entity type"); } @@ -353,16 +345,16 @@ static void convert(const Slic3r::ExtrusionEntity& extrusion_entity, float print } } -static void convert(const Slic3r::ExtrusionEntityCollection& extrusion_entity_collection, float print_z, size_t layer_id, - size_t extruder_id, size_t color_id, EGCodeExtrusionRole extrusion_role, const Slic3r::Point& shift, GCodeInputData& data) +static void convert_to_vertices(const Slic3r::ExtrusionEntityCollection& extrusion_entity_collection, float print_z, size_t layer_id, + size_t extruder_id, size_t color_id, EGCodeExtrusionRole extrusion_role, const Slic3r::Point& shift, std::vector& vertices) { for (const Slic3r::ExtrusionEntity* extrusion_entity : extrusion_entity_collection.entities) { if (extrusion_entity != nullptr) - convert(*extrusion_entity, print_z, layer_id, extruder_id, color_id, extrusion_role, shift, data); + convert_to_vertices(*extrusion_entity, print_z, layer_id, extruder_id, color_id, extrusion_role, shift, vertices); } } -static void convert_brim_skirt(const Slic3r::Print& print, GCodeInputData& data) +static void convert_brim_skirt_to_vertices(const Slic3r::Print& print, std::vector& vertices) { // auto start_time = std::chrono::high_resolution_clock::now(); @@ -395,8 +387,8 @@ static void convert_brim_skirt(const Slic3r::Print& print, GCodeInputData& data) for (size_t i = 0; i < skirt_height; ++i) { if (i == 0) - convert(print.brim(), print_zs[i], i, 0, 0, EGCodeExtrusionRole::Skirt, Slic3r::Point(0, 0), data); - convert(print.skirt(), print_zs[i], i, 0, 0, EGCodeExtrusionRole::Skirt, Slic3r::Point(0, 0), data); + convert_to_vertices(print.brim(), print_zs[i], i, 0, 0, EGCodeExtrusionRole::Skirt, Slic3r::Point(0, 0), vertices); + convert_to_vertices(print.skirt(), print_zs[i], i, 0, 0, EGCodeExtrusionRole::Skirt, Slic3r::Point(0, 0), vertices); } // auto end_time = std::chrono::high_resolution_clock::now(); @@ -444,16 +436,16 @@ private: size_t m_layers_count{ 0 }; }; -static void convert_wipe_tower(const Slic3r::Print& print, const std::vector& str_tool_colors, GCodeInputData& data) +static void convert_wipe_tower_to_vertices(const Slic3r::Print& print, const std::vector& str_tool_colors, std::vector& vertices) { // auto start_time = std::chrono::high_resolution_clock::now(); - WipeTowerHelper wipe_tower(print); - const float angle = wipe_tower.get_angle(); - const Slic3r::Vec2f& position = wipe_tower.get_position(); + WipeTowerHelper wipe_tower_helper(print); + const float angle = wipe_tower_helper.get_angle(); + const Slic3r::Vec2f& position = wipe_tower_helper.get_position(); - for (size_t item = 0; item < wipe_tower.get_layers_count(); ++item) { - const std::vector& layer = wipe_tower.tool_change(item); + for (size_t item = 0; item < wipe_tower_helper.get_layers_count(); ++item) { + const std::vector& layer = wipe_tower_helper.tool_change(item); for (const Slic3r::WipeTower::ToolChangeResult& extrusions : layer) { for (size_t i = 1; i < extrusions.extrusions.size(); /*no increment*/) { const Slic3r::WipeTower::Extrusion& e = extrusions.extrusions[i]; @@ -493,8 +485,8 @@ static void convert_wipe_tower(const Slic3r::Print& print, const std::vector(e.tool), 0, - EGCodeExtrusionRole::WipeTower, lines.front().a == lines.back().b, data); + convert_lines_to_vertices(lines, widths, heights, extrusions.print_z, item, static_cast(e.tool), 0, + EGCodeExtrusionRole::WipeTower, lines.front().a == lines.back().b, vertices); } } } @@ -503,28 +495,240 @@ static void convert_wipe_tower(const Slic3r::Print& print, const std::vector(end_time - start_time).count() << "ms\n"; } -static void convert_object(const Slic3r::PrintObject& object, GCodeInputData& data) +class ObjectHelper +{ +public: + ObjectHelper(const std::vector& color_print_values, size_t tool_colors_count, size_t extruders_count) + : m_color_print_values(color_print_values) + , m_tool_colors_count(tool_colors_count) + , m_extruders_count(extruders_count) + { + } + + uint8_t color_id(size_t layer_id, size_t extruder_id) const + { + return !m_color_print_values.empty() ? color_print_color_id(layer_id, extruder_id) : + (m_tool_colors_count > 0) ? std::min(m_tool_colors_count - 1, std::max(extruder_id - 1, 0)) : 0; + } + +private: + const std::vector& m_color_print_values; + size_t m_tool_colors_count; + size_t m_extruders_count; + + uint8_t color_print_color_id(double print_z, size_t extruder_id) const + { + auto it = std::find_if(m_color_print_values.begin(), m_color_print_values.end(), + [print_z](const Slic3r::CustomGCode::Item& code) { + return std::fabs(code.print_z - print_z) < EPSILON; + }); + if (it != m_color_print_values.end()) { + Slic3r::CustomGCode::Type type = it->type; + // pause print or custom Gcode + if (type == Slic3r::CustomGCode::PausePrint || + (type != Slic3r::CustomGCode::ColorChange && type != Slic3r::CustomGCode::ToolChange)) + return static_cast(m_tool_colors_count - 1); // last color item is a gray color for pause print or custom G-code + + switch (it->type) { + // change color for current extruder + case Slic3r::CustomGCode::ColorChange: { return color_change_color_id(it, extruder_id); } + // change tool (extruder) + case Slic3r::CustomGCode::ToolChange: { return tool_change_color_id(it, extruder_id); } + } + } + + const Slic3r::CustomGCode::Item value{ print_z + EPSILON, Slic3r::CustomGCode::Custom, 0, "" }; + it = std::lower_bound(m_color_print_values.begin(), m_color_print_values.end(), value); + while (it != m_color_print_values.begin()) { + --it; + switch (it->type) { + // change color for current extruder + case Slic3r::CustomGCode::ColorChange: { return color_change_color_id(it, extruder_id); } + // change tool (extruder) + case Slic3r::CustomGCode::ToolChange: { return tool_change_color_id(it, extruder_id); } + } + } + + return std::min(m_extruders_count - 1, std::max(extruder_id - 1, 0)); + } + + uint8_t color_change_color_id(std::vector::const_iterator it, size_t extruder_id) const + { + if (m_extruders_count == 1) + return m600_color_id(it); + + auto it_n = it; + bool is_tool_change = false; + while (it_n != m_color_print_values.begin()) { + --it_n; + if (it_n->type == Slic3r::CustomGCode::ToolChange) { + is_tool_change = true; + if (it_n->extruder == it->extruder || (it_n->extruder == 0 && it->extruder == extruder_id)) + return m600_color_id(it); + break; + } + } + if (!is_tool_change && it->extruder == extruder_id) + return m600_color_id(it); + + assert(false); + return 0; + } + + uint8_t tool_change_color_id(std::vector::const_iterator it, size_t extruder_id) const + { + const int current_extruder = it->extruder == 0 ? static_cast(extruder_id) : it->extruder; + if (m_tool_colors_count == m_extruders_count + 1) // there is no one "M600" + return std::min(m_extruders_count - 1, std::max(current_extruder - 1, 0)); + + auto it_n = it; + while (it_n != m_color_print_values.begin()) { + --it_n; + if (it_n->type == Slic3r::CustomGCode::ColorChange && it_n->extruder == current_extruder) + return m600_color_id(it_n); + } + + return std::min(m_extruders_count - 1, std::max(current_extruder - 1, 0)); + } + + uint8_t m600_color_id(std::vector::const_iterator it) const + { + uint8_t shift = 0; + while (it != m_color_print_values.begin()) { + --it; + if (it->type == Slic3r::CustomGCode::ColorChange) + ++shift; + } + return m_extruders_count + shift; + } +}; + +struct ObjectData +{ + std::vector vertices; + std::vector layers_zs; +}; + +static void convert_object_to_vertices(const Slic3r::PrintObject& object, const std::vector& str_tool_colors, + const std::vector& color_print_values, size_t extruders_count, ObjectData& data) +{ + const bool has_perimeters = object.is_step_done(Slic3r::posPerimeters); + const bool has_infill = object.is_step_done(Slic3r::posInfill); + const bool has_support = object.is_step_done(Slic3r::posSupportMaterial); + + // order layers by print_z + std::vector layers; + if (has_perimeters || has_infill) { + layers.reserve(layers.size() + object.layers().size()); + std::copy(object.layers().begin(), object.layers().end(), std::back_inserter(layers)); + } + if (has_support) { + layers.reserve(layers.size() + object.support_layers().size()); + std::copy(object.support_layers().begin(), object.support_layers().end(), std::back_inserter(layers)); + } + std::sort(layers.begin(), layers.end(), [](const Slic3r::Layer* l1, const Slic3r::Layer* l2) { return l1->print_z < l2->print_z; }); + + ObjectHelper object_helper(color_print_values, str_tool_colors.size(), extruders_count); + + data.layers_zs.reserve(layers.size()); + for (const Slic3r::Layer* layer : layers) { + data.layers_zs.emplace_back(static_cast(layer->print_z)); + } + + for (size_t i = 0; i < layers.size(); ++i) { + const Slic3r::Layer* layer = layers[i]; + for (const Slic3r::PrintInstance& instance : object.instances()) { + const Slic3r::Point& copy = instance.shift; + for (const Slic3r::LayerRegion* layerm : layer->regions()) { + if (layerm->slices().empty()) + continue; + const Slic3r::PrintRegionConfig& cfg = layerm->region().config(); + if (has_perimeters) { + const size_t extruder_id = static_cast(cfg.perimeter_extruder.value); + convert_to_vertices(layerm->perimeters(), static_cast(layer->print_z), i, extruder_id, object_helper.color_id(layer->print_z, extruder_id), + EGCodeExtrusionRole::ExternalPerimeter, copy, data.vertices); + } + if (has_infill) { + for (const Slic3r::ExtrusionEntity* ee : layerm->fills()) { + // fill represents infill extrusions of a single island. + const auto& fill = *dynamic_cast(ee); + if (!fill.entities.empty()) { + const bool is_solid_infill = fill.entities.front()->role().is_solid_infill(); + const size_t extruder_id = is_solid_infill ? + static_cast(cfg.solid_infill_extruder.value) : static_cast(cfg.infill_extruder.value); + convert_to_vertices(fill, static_cast(layer->print_z), i, extruder_id, object_helper.color_id(layer->print_z, extruder_id), + is_solid_infill ? EGCodeExtrusionRole::SolidInfill : EGCodeExtrusionRole::InternalInfill, + copy, data.vertices); + } + } + } + } + if (has_support) { + const Slic3r::SupportLayer* support_layer = dynamic_cast(layer); + if (support_layer == nullptr) + continue; + const Slic3r::PrintObjectConfig& cfg = support_layer->object()->config(); + for (const Slic3r::ExtrusionEntity* extrusion_entity : support_layer->support_fills.entities) { + const bool is_support_material = extrusion_entity->role() == Slic3r::ExtrusionRole::SupportMaterial; + const size_t extruder_id = is_support_material ? + static_cast(cfg.support_material_extruder.value) : static_cast(cfg.support_material_interface_extruder.value); + convert_to_vertices(*extrusion_entity, static_cast(layer->print_z), i, + extruder_id, object_helper.color_id(layer->print_z, extruder_id), + is_support_material ? EGCodeExtrusionRole::SupportMaterial : EGCodeExtrusionRole::SupportMaterialInterface, + copy, data.vertices); + } + } + } + } +} + +static void convert_objects_to_vertices(const Slic3r::SpanOfConstPtrs& objects, const std::vector& str_tool_colors, + const std::vector& color_print_values, size_t extruders_count, std::vector& vertices) { // auto start_time = std::chrono::high_resolution_clock::now(); + // extract vertices and layers zs object by object + std::vector objects_data(objects.size()); + for (size_t i = 0; i < objects.size(); ++i) { + convert_object_to_vertices(*objects[i], str_tool_colors, color_print_values, extruders_count, objects_data[i]); + } + + // collect layers zs + std::vector layers; + for (const ObjectData& data : objects_data) { + layers.reserve(layers.size() + data.layers_zs.size()); + std::copy(data.layers_zs.begin(), data.layers_zs.end(), std::back_inserter(layers)); + } + std::sort(layers.begin(), layers.end(), [](float z1, float z2) { return z1 < z2; }); + layers.erase(std::unique(layers.begin(), layers.end(), [](float z1, float z2) { return z1 == z2; }), layers.end()); + + // collect extracted vertices layer by layer + float min_z = 0.0f; + for (float z : layers) { + for (ObjectData& data : objects_data) { + std::copy_if(data.vertices.begin(), data.vertices.end(), std::back_inserter(vertices), + [min_z, z](const PathVertex& v) { return min_z < v.position[2] && v.position[2] <= z; }); + } + min_z = z; + } + // auto end_time = std::chrono::high_resolution_clock::now(); -// std::cout << "convert_object: " << std::chrono::duration_cast(end_time - start_time).count() << "ms\n"; +// std::cout << "convert_objects: " << std::chrono::duration_cast(end_time - start_time).count() << "ms\n"; } // mapping from Slic3r::Print to libvgcode::GCodeInputData -GCodeInputData convert(const Slic3r::Print& print, const std::vector& str_tool_colors) +GCodeInputData convert(const Slic3r::Print& print, const std::vector& str_tool_colors, + const std::vector& color_print_values, size_t extruders_count) { GCodeInputData ret; if (print.is_step_done(Slic3r::psSkirtBrim) && (print.has_skirt() || print.has_brim())) - convert_brim_skirt(print, ret); + convert_brim_skirt_to_vertices(print, ret.vertices); if (!print.wipe_tower_data().tool_changes.empty() && print.is_step_done(Slic3r::psWipeTower)) - convert_wipe_tower(print, str_tool_colors, ret); + convert_wipe_tower_to_vertices(print, str_tool_colors, ret.vertices); - for (const Slic3r::PrintObject* object : print.objects()) { - convert_object(*object, ret); - } + convert_objects_to_vertices(print.objects(), str_tool_colors, color_print_values, extruders_count, ret.vertices); return ret; } diff --git a/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.hpp b/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.hpp index 88c656c0c9..17f4e8c552 100644 --- a/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.hpp +++ b/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.hpp @@ -60,7 +60,8 @@ extern GCodeInputData convert(const Slic3r::GCodeProcessorResult& result, float float wipes_radius = Default_Wipes_Radius); // mapping from Slic3r::Print to libvgcode::GCodeInputData -extern GCodeInputData convert(const Slic3r::Print& print, const std::vector& str_tool_colors); +extern GCodeInputData convert(const Slic3r::Print& print, const std::vector& str_tool_colors, + const std::vector& color_print_values, size_t extruders_count); } // namespace libvgcode diff --git a/src/slic3r/GUI/LibVGCode/include/ColorRange.hpp b/src/slic3r/GUI/LibVGCode/include/ColorRange.hpp index 9f176d3683..39f9359810 100644 --- a/src/slic3r/GUI/LibVGCode/include/ColorRange.hpp +++ b/src/slic3r/GUI/LibVGCode/include/ColorRange.hpp @@ -18,7 +18,7 @@ namespace libvgcode { // Helper class to interpolate between colors defined in Ranges_Colors palette. // Interpolation can be done linearly or logarithmically. // Usage: -// 1) Define an instance of ColorRange of the desired type +// 1) Define an instance of ColorRange of the desired interpolation type // ColorRange range(EColorRangeType::Linear); // 2) Pass to the instance all the values needed to setup the range: // for (size_t i = 0; i < my_data.size(); ++i) {