diff --git a/src/libslic3r/ExtrusionEntity.hpp b/src/libslic3r/ExtrusionEntity.hpp index f5ac72def..b22d85b65 100644 --- a/src/libslic3r/ExtrusionEntity.hpp +++ b/src/libslic3r/ExtrusionEntity.hpp @@ -14,7 +14,7 @@ class ExtrusionEntityCollection; class Extruder; // Each ExtrusionRole value identifies a distinct set of { extruder, speed } -enum ExtrusionRole { +enum ExtrusionRole : uint8_t { erNone, erPerimeter, erExternalPerimeter, @@ -117,25 +117,16 @@ public: float width; // Height of the extrusion, used for visualization purposes. float height; - // Feedrate of the extrusion, used for visualization purposes. - float feedrate; - // Id of the extruder, used for visualization purposes. - unsigned int extruder_id; - // Id of the color, used for visualization purposes in the color printing case. - unsigned int cp_color_id; - // Fan speed for the extrusion, used for visualization purposes. - float fan_speed; - ExtrusionPath(ExtrusionRole role) : mm3_per_mm(-1), width(-1), height(-1), feedrate(0.0f), extruder_id(0), cp_color_id(0), fan_speed(0.0f), m_role(role) {}; - ExtrusionPath(ExtrusionRole role, double mm3_per_mm, float width, float height) : mm3_per_mm(mm3_per_mm), width(width), height(height), feedrate(0.0f), extruder_id(0), cp_color_id(0), fan_speed(0.0f), m_role(role) {}; - ExtrusionPath(const ExtrusionPath& rhs) : polyline(rhs.polyline), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), feedrate(rhs.feedrate), extruder_id(rhs.extruder_id), cp_color_id(rhs.cp_color_id), fan_speed(rhs.fan_speed), m_role(rhs.m_role) {} - ExtrusionPath(ExtrusionPath&& rhs) : polyline(std::move(rhs.polyline)), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), feedrate(rhs.feedrate), extruder_id(rhs.extruder_id), cp_color_id(rhs.cp_color_id), fan_speed(rhs.fan_speed), m_role(rhs.m_role) {} - ExtrusionPath(const Polyline &polyline, const ExtrusionPath &rhs) : polyline(polyline), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), feedrate(rhs.feedrate), extruder_id(rhs.extruder_id), cp_color_id(rhs.cp_color_id), fan_speed(rhs.fan_speed), m_role(rhs.m_role) {} - ExtrusionPath(Polyline &&polyline, const ExtrusionPath &rhs) : polyline(std::move(polyline)), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), feedrate(rhs.feedrate), extruder_id(rhs.extruder_id), cp_color_id(rhs.cp_color_id), fan_speed(rhs.fan_speed), m_role(rhs.m_role) {} -// ExtrusionPath(ExtrusionRole role, const Flow &flow) : m_role(role), mm3_per_mm(flow.mm3_per_mm()), width(flow.width), height(flow.height), feedrate(0.0f), extruder_id(0) {}; + ExtrusionPath(ExtrusionRole role) : mm3_per_mm(-1), width(-1), height(-1), m_role(role) {}; + ExtrusionPath(ExtrusionRole role, double mm3_per_mm, float width, float height) : mm3_per_mm(mm3_per_mm), width(width), height(height), m_role(role) {}; + ExtrusionPath(const ExtrusionPath& rhs) : polyline(rhs.polyline), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), m_role(rhs.m_role) {} + ExtrusionPath(ExtrusionPath&& rhs) : polyline(std::move(rhs.polyline)), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), m_role(rhs.m_role) {} + ExtrusionPath(const Polyline &polyline, const ExtrusionPath &rhs) : polyline(polyline), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), m_role(rhs.m_role) {} + ExtrusionPath(Polyline &&polyline, const ExtrusionPath &rhs) : polyline(std::move(polyline)), mm3_per_mm(rhs.mm3_per_mm), width(rhs.width), height(rhs.height), m_role(rhs.m_role) {} - ExtrusionPath& operator=(const ExtrusionPath& rhs) { m_role = rhs.m_role; this->mm3_per_mm = rhs.mm3_per_mm; this->width = rhs.width; this->height = rhs.height; this->feedrate = rhs.feedrate, this->extruder_id = rhs.extruder_id, this->cp_color_id = rhs.cp_color_id, this->fan_speed = rhs.fan_speed, this->polyline = rhs.polyline; return *this; } - ExtrusionPath& operator=(ExtrusionPath&& rhs) { m_role = rhs.m_role; this->mm3_per_mm = rhs.mm3_per_mm; this->width = rhs.width; this->height = rhs.height; this->feedrate = rhs.feedrate, this->extruder_id = rhs.extruder_id, this->cp_color_id = rhs.cp_color_id, this->fan_speed = rhs.fan_speed, this->polyline = std::move(rhs.polyline); return *this; } + ExtrusionPath& operator=(const ExtrusionPath& rhs) { m_role = rhs.m_role; this->mm3_per_mm = rhs.mm3_per_mm; this->width = rhs.width; this->height = rhs.height; this->polyline = rhs.polyline; return *this; } + ExtrusionPath& operator=(ExtrusionPath&& rhs) { m_role = rhs.m_role; this->mm3_per_mm = rhs.mm3_per_mm; this->width = rhs.width; this->height = rhs.height; this->polyline = std::move(rhs.polyline); return *this; } ExtrusionEntity* clone() const override { return new ExtrusionPath(*this); } // Create a new object, initialize it with this object using the move semantics. diff --git a/src/libslic3r/GCode/Analyzer.cpp b/src/libslic3r/GCode/Analyzer.cpp index fa4414da9..136959d71 100644 --- a/src/libslic3r/GCode/Analyzer.cpp +++ b/src/libslic3r/GCode/Analyzer.cpp @@ -866,7 +866,7 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ } // if layer not found, create and return it - layers.emplace_back(z, ExtrusionPaths()); + layers.emplace_back(z, GCodePreviewData::Extrusion::Paths()); return layers.back(); } @@ -875,14 +875,18 @@ void GCodeAnalyzer::_calc_gcode_preview_extrusion_layers(GCodePreviewData& previ // if the polyline is valid, create the extrusion path from it and store it if (polyline.is_valid()) { - ExtrusionPath path(data.extrusion_role, data.mm3_per_mm, data.width, data.height); + auto& paths = get_layer_at_z(preview_data.extrusion.layers, z).paths; + paths.emplace_back(GCodePreviewData::Extrusion::Path()); + GCodePreviewData::Extrusion::Path &path = paths.back(); path.polyline = polyline; + path.extrusion_role = data.extrusion_role; + path.mm3_per_mm = data.mm3_per_mm; + path.width = data.width; + path.height = data.height; path.feedrate = data.feedrate; path.extruder_id = data.extruder_id; - path.fan_speed = data.fan_speed; path.cp_color_id = data.cp_color_id; - - get_layer_at_z(preview_data.extrusion.layers, z).paths.push_back(path); + path.fan_speed = data.fan_speed; } } }; diff --git a/src/libslic3r/GCode/PreviewData.cpp b/src/libslic3r/GCode/PreviewData.cpp index c6cfcc8af..53c13a2f2 100644 --- a/src/libslic3r/GCode/PreviewData.cpp +++ b/src/libslic3r/GCode/PreviewData.cpp @@ -23,7 +23,7 @@ std::vector GCodePreviewData::Color::as_bytes() const return ret; } -GCodePreviewData::Extrusion::Layer::Layer(float z, const ExtrusionPaths& paths) +GCodePreviewData::Extrusion::Layer::Layer(float z, const Paths& paths) : z(z) , paths(paths) { @@ -171,8 +171,8 @@ size_t GCodePreviewData::Extrusion::memory_used() const size_t out = sizeof(*this); out += SLIC3R_STDVEC_MEMSIZE(this->layers, Layer); for (const Layer &layer : this->layers) { - out += SLIC3R_STDVEC_MEMSIZE(layer.paths, ExtrusionPath); - for (const ExtrusionPath &path : layer.paths) + out += SLIC3R_STDVEC_MEMSIZE(layer.paths, Path); + for (const Path &path : layer.paths) out += SLIC3R_STDVEC_MEMSIZE(path.polyline.points, Point); } return out; diff --git a/src/libslic3r/GCode/PreviewData.hpp b/src/libslic3r/GCode/PreviewData.hpp index 7f5b691e1..70b6edffd 100644 --- a/src/libslic3r/GCode/PreviewData.hpp +++ b/src/libslic3r/GCode/PreviewData.hpp @@ -87,12 +87,34 @@ public: static const std::string Default_Extrusion_Role_Names[erCount]; static const EViewType Default_View_Type; + class Path + { + public: + Polyline polyline; + ExtrusionRole extrusion_role; + // Volumetric velocity. mm^3 of plastic per mm of linear head motion. Used by the G-code generator. + float mm3_per_mm; + // Width of the extrusion, used for visualization purposes. + float width; + // Height of the extrusion, used for visualization purposes. + float height; + // Feedrate of the extrusion, used for visualization purposes. + float feedrate; + // Id of the extruder, used for visualization purposes. + uint32_t extruder_id; + // Id of the color, used for visualization purposes in the color printing case. + uint32_t cp_color_id; + // Fan speed for the extrusion, used for visualization purposes. + float fan_speed; + }; + using Paths = std::vector; + struct Layer { float z; - ExtrusionPaths paths; + Paths paths; - Layer(float z, const ExtrusionPaths& paths); + Layer(float z, const Paths& paths); }; typedef std::vector LayersList; diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 8094cdde1..0e127a868 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1717,13 +1717,18 @@ static void thick_point_to_verts(const Vec3crd& point, point_to_indexed_vertex_array(point, width, height, volume.indexed_vertex_array); } +void _3DScene::extrusionentity_to_verts(const Polyline &polyline, float width, float height, float print_z, GLVolume& volume) +{ + if (polyline.size() >= 2) { + size_t num_segments = polyline.size() - 1; + thick_lines_to_verts(polyline.lines(), std::vector(num_segments, width), std::vector(num_segments, height), false, print_z, volume); + } +} + // Fill in the qverts and tverts with quads and triangles for the extrusion_path. void _3DScene::extrusionentity_to_verts(const ExtrusionPath &extrusion_path, float print_z, GLVolume &volume) { - Lines lines = extrusion_path.polyline.lines(); - std::vector widths(lines.size(), extrusion_path.width); - std::vector heights(lines.size(), extrusion_path.height); - thick_lines_to_verts(lines, widths, heights, false, print_z, volume); + extrusionentity_to_verts(extrusion_path.polyline, extrusion_path.width, extrusion_path.height, print_z, volume); } // Fill in the qverts and tverts with quads and triangles for the extrusion_path. diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 8c1d68f77..8c5040eee 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -656,6 +656,7 @@ public: static void thick_lines_to_verts(const Lines& lines, const std::vector& widths, const std::vector& heights, bool closed, double top_z, GLVolume& volume); static void thick_lines_to_verts(const Lines3& lines, const std::vector& widths, const std::vector& heights, bool closed, GLVolume& volume); + static void extrusionentity_to_verts(const Polyline &polyline, float width, float height, float print_z, GLVolume& volume); static void extrusionentity_to_verts(const ExtrusionPath& extrusion_path, float print_z, GLVolume& volume); static void extrusionentity_to_verts(const ExtrusionPath& extrusion_path, float print_z, const Point& copy, GLVolume& volume); static void extrusionentity_to_verts(const ExtrusionLoop& extrusion_loop, float print_z, const Point& copy, GLVolume& volume); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 9f5dd16e7..ff70fd451 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -4987,13 +4987,13 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat // helper functions to select data in dependence of the extrusion view type struct Helper { - static float path_filter(GCodePreviewData::Extrusion::EViewType type, const ExtrusionPath& path) + static float path_filter(GCodePreviewData::Extrusion::EViewType type, const GCodePreviewData::Extrusion::Path& path) { switch (type) { case GCodePreviewData::Extrusion::FeatureType: // The role here is used for coloring. - return (float)path.role(); + return (float)path.extrusion_role; case GCodePreviewData::Extrusion::Height: return path.height; case GCodePreviewData::Extrusion::Width: @@ -5071,15 +5071,15 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat { std::vector num_paths_per_role(size_t(erCount), 0); for (const GCodePreviewData::Extrusion::Layer &layer : preview_data.extrusion.layers) - for (const ExtrusionPath &path : layer.paths) - ++ num_paths_per_role[size_t(path.role())]; + for (const GCodePreviewData::Extrusion::Path &path : layer.paths) + ++ num_paths_per_role[size_t(path.extrusion_role)]; std::vector> roles_values; roles_values.assign(size_t(erCount), std::vector()); for (size_t i = 0; i < roles_values.size(); ++ i) roles_values[i].reserve(num_paths_per_role[i]); for (const GCodePreviewData::Extrusion::Layer& layer : preview_data.extrusion.layers) - for (const ExtrusionPath& path : layer.paths) - roles_values[size_t(path.role())].emplace_back(Helper::path_filter(preview_data.extrusion.view_type, path)); + for (const GCodePreviewData::Extrusion::Path &path : layer.paths) + roles_values[size_t(path.extrusion_role)].emplace_back(Helper::path_filter(preview_data.extrusion.view_type, path)); roles_filters.reserve(size_t(erCount)); size_t num_buffers = 0; for (std::vector &values : roles_values) { @@ -5107,9 +5107,9 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat // populates volumes for (const GCodePreviewData::Extrusion::Layer& layer : preview_data.extrusion.layers) { - for (const ExtrusionPath& path : layer.paths) + for (const GCodePreviewData::Extrusion::Path& path : layer.paths) { - std::vector> &filters = roles_filters[size_t(path.role())]; + std::vector> &filters = roles_filters[size_t(path.extrusion_role)]; auto key = std::make_pair(Helper::path_filter(preview_data.extrusion.view_type, path), nullptr); auto it_filter = std::lower_bound(filters.begin(), filters.end(), key); assert(it_filter != filters.end() && key.first == it_filter->first); @@ -5119,7 +5119,7 @@ void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_dat vol.offsets.push_back(vol.indexed_vertex_array.quad_indices.size()); vol.offsets.push_back(vol.indexed_vertex_array.triangle_indices.size()); - _3DScene::extrusionentity_to_verts(path, layer.z, vol); + _3DScene::extrusionentity_to_verts(path.polyline, path.width, path.height, layer.z, vol); } // Ensure that no volume grows over the limits. If the volume is too large, allocate a new one. for (std::vector> &filters : roles_filters) {