PRUSA 2.7.0

This commit is contained in:
sunsets
2023-12-27 18:02:35 +08:00
parent b33112327f
commit 0a3c63dcb1
488 changed files with 92371 additions and 29443 deletions

View File

@@ -5,33 +5,39 @@
#include "JumpPointSearch.hpp"
#include "libslic3r.h"
#include "ExPolygon.hpp"
#include "GCodeWriter.hpp"
#include "Layer.hpp"
#include "Point.hpp"
#include "PlaceholderParser.hpp"
#include "PrintConfig.hpp"
#include "Geometry/ArcWelder.hpp"
#include "GCode/AvoidCrossingPerimeters.hpp"
#include "GCode/CoolingBuffer.hpp"
#include "GCode/FindReplace.hpp"
#include "GCode/GCodeWriter.hpp"
#include "GCode/LabelObjects.hpp"
#include "GCode/PressureEqualizer.hpp"
#include "GCode/RetractWhenCrossingPerimeters.hpp"
#include "GCode/SmoothPath.hpp"
#include "GCode/SpiralVase.hpp"
#include "GCode/ToolOrdering.hpp"
#include "GCode/WipeTower.hpp"
#include "GCode/Wipe.hpp"
#include "GCode/WipeTowerIntegration.hpp"
#include "GCode/SeamPlacer.hpp"
#include "GCode/GCodeProcessor.hpp"
#include "EdgeGrid.hpp"
#include "GCode/ThumbnailData.hpp"
#include "tcbspan/span.hpp"
#include <memory>
#include <map>
#include <string>
#include "GCode/PressureEqualizer.hpp"
//#include "GCode/PressureEqualizer.hpp"
namespace Slic3r {
// Forward declarations.
class GCode;
class GCodeGenerator;
namespace { struct Item; }
struct PrintInstance;
@@ -41,71 +47,11 @@ public:
bool enable;
OozePrevention() : enable(false) {}
std::string pre_toolchange(GCode &gcodegen);
std::string post_toolchange(GCode &gcodegen);
private:
int _get_temp(const GCode &gcodegen) const;
};
class Wipe {
public:
bool enable;
Polyline path;
Wipe() : enable(false) {}
bool has_path() const { return ! this->path.empty(); }
void reset_path() { this->path.clear(); }
std::string wipe(GCode &gcodegen, bool toolchange);
};
class WipeTowerIntegration {
public:
WipeTowerIntegration(
const PrintConfig &print_config,
const std::vector<WipeTower::ToolChangeResult> &priming,
const std::vector<std::vector<WipeTower::ToolChangeResult>> &tool_changes,
const WipeTower::ToolChangeResult &final_purge) :
m_left(/*float(print_config.wipe_tower_x.value)*/ 0.f),
m_right(float(/*print_config.wipe_tower_x.value +*/ print_config.wipe_tower_width.value)),
m_wipe_tower_pos(float(print_config.wipe_tower_x.value), float(print_config.wipe_tower_y.value)),
m_wipe_tower_rotation(float(print_config.wipe_tower_rotation_angle)),
m_extruder_offsets(print_config.extruder_offset.values),
m_priming(priming),
m_tool_changes(tool_changes),
m_final_purge(final_purge),
m_layer_idx(-1),
m_tool_change_idx(0)
{}
std::string prime(GCode &gcodegen);
void next_layer() { ++ m_layer_idx; m_tool_change_idx = 0; }
std::string tool_change(GCode &gcodegen, int extruder_id, bool finish_layer);
std::string finalize(GCode &gcodegen);
std::vector<float> used_filament_length() const;
std::string pre_toolchange(GCodeGenerator &gcodegen);
std::string post_toolchange(GCodeGenerator &gcodegen);
private:
WipeTowerIntegration& operator=(const WipeTowerIntegration&);
std::string append_tcr(GCode &gcodegen, const WipeTower::ToolChangeResult &tcr, int new_extruder_id, double z = -1.) const;
// Postprocesses gcode: rotates and moves G1 extrusions and returns result
std::string post_process_wipe_tower_moves(const WipeTower::ToolChangeResult& tcr, const Vec2f& translation, float angle) const;
// Left / right edges of the wipe tower, for the planning of wipe moves.
const float m_left;
const float m_right;
const Vec2f m_wipe_tower_pos;
const float m_wipe_tower_rotation;
const std::vector<Vec2d> m_extruder_offsets;
// Reference to cached values at the Printer class.
const std::vector<WipeTower::ToolChangeResult> &m_priming;
const std::vector<std::vector<WipeTower::ToolChangeResult>> &m_tool_changes;
const WipeTower::ToolChangeResult &m_final_purge;
// Current layer index.
int m_layer_idx;
int m_tool_change_idx;
double m_last_wipe_tower_print_z = 0.f;
int _get_temp(const GCodeGenerator &gcodegen) const;
};
class ColorPrintColors
@@ -129,9 +75,115 @@ struct LayerResult {
static LayerResult make_nop_layer_result() { return {"", std::numeric_limits<coord_t>::max(), false, false, true}; }
};
class GCode {
namespace GCode::Impl {
struct DistancedPoint {
Point point;
double distance_from_start;
};
/**
* @brief Takes a path described as a list of points and adds points to it.
*
* @param xy_path A list of points describing a path in xy.
* @param sorted_distances A sorted list of distances along the path.
* @return Sliced path.
*
* The algorithm travels along the path segments and adds points to
* the segments in such a way that the points have specified distances
* from the xy_path start. **Any distances over the xy_path end will
* be simply ignored.**
*
* Example usage - simplified for clarity:
* @code
* std::vector<double> distances{0.5, 1.5};
* std::vector<Points> xy_path{{0, 0}, {1, 0}};
* // produces
* {{0, 0}, {0, 0.5}, {1, 0}}
* // notice that 1.5 is omitted
* @endcode
*/
std::vector<DistancedPoint> slice_xy_path(tcb::span<const Point> xy_path, tcb::span<const double> sorted_distances);
/**
* @brief Take xy_path and genrate a travel acording to elevation.
*
* @param xy_path A list of points describing a path in xy.
* @param ensure_points_at_distances See slice_xy_path sorted_distances.
* @param elevation A function taking current distance in mm as input and returning elevation in mm as output.
*
* **Be aweare** that the elevation function operates in mm, while xy_path and returned travel are in
* scaled coordinates.
*/
Points3 generate_elevated_travel(
const tcb::span<const Point> xy_path,
const std::vector<double>& ensure_points_at_distances,
const double initial_elevation,
const std::function<double(double)>& elevation
);
/**
* @brief Takes a list o polygons and builds a AABBTree over all unscaled lines.
*
* @param polygons A list of polygons.
* @return AABB Tree over all lines of the polygons.
*
* Unscales the lines in the process!
*/
AABBTreeLines::LinesDistancer<Linef> get_expolygons_distancer(const ExPolygons& polygons);
/**
* @brief Given a AABB tree over lines find intersection with xy_path closest to the xy_path start.
*
* @param xy_path A path in 2D.
* @param distancer AABB Tree over lines.
* @return Distance to the first intersection if there is one.
*
* **Ignores intersection with xy_path starting point.**
*/
std::optional<double> get_first_crossed_line_distance(
tcb::span<const Line> xy_path,
const AABBTreeLines::LinesDistancer<Linef>& distancer
);
/**
* Generates a regular polygon - all angles are the same (e.g. typical hexagon).
*
* @param centroid Central point.
* @param start_point The polygon point are ordered. This is the first point.
* @param points_count Amount of nodes of the polygon (e.g. 6 for haxagon).
*
* Distance between centroid and start point sets the scale of the polygon.
*/
Polygon generate_regular_polygon(
const Point& centroid,
const Point& start_point,
const unsigned points_count
);
class Bed {
private:
Polygon inner_offset;
static Polygon get_inner_offset(const std::vector<Vec2d>& shape, const double padding);
public:
/**
* Bed shape with inner padding.
*/
Bed(const std::vector<Vec2d>& shape, const double padding);
Vec2d centroid;
/**
* Returns true if the point is within the bed shape including inner padding.
*/
bool contains_within_padding(const Vec2d& point) const;
};
}
class GCodeGenerator {
public:
GCode() :
GCodeGenerator() :
m_origin(Vec2d::Zero()),
m_enable_loop_clipping(true),
m_enable_cooling_markers(false),
@@ -153,7 +205,7 @@ public:
m_silent_time_estimator_enabled(false),
m_last_obj_copy(nullptr, Point(std::numeric_limits<coord_t>::max(), std::numeric_limits<coord_t>::max()))
{}
~GCode() = default;
~GCodeGenerator() = default;
// throws std::runtime_exception on error,
// throws CanceledException through print->throw_if_canceled().
@@ -165,9 +217,19 @@ public:
void set_origin(const coordf_t x, const coordf_t y) { this->set_origin(Vec2d(x, y)); }
const Point& last_pos() const { return m_last_pos; }
// Convert coordinates of the active object to G-code coordinates, possibly adjusted for extruder offset.
Vec2d point_to_gcode(const Point &point) const;
template<typename Derived>
Vec2d point_to_gcode(const Eigen::MatrixBase<Derived> &point) const {
static_assert(Derived::IsVectorAtCompileTime && int(Derived::SizeAtCompileTime) == 2, "GCodeGenerator::point_to_gcode(): first parameter is not a 2D vector");
return Vec2d(unscaled<double>(point.x()), unscaled<double>(point.y())) + m_origin
- m_config.extruder_offset.get_at(m_writer.extruder()->id());
}
// Convert coordinates of the active object to G-code coordinates, possibly adjusted for extruder offset and quantized to G-code resolution.
Vec2d point_to_gcode_quantized(const Point &point) const;
template<typename Derived>
Vec2d point_to_gcode_quantized(const Eigen::MatrixBase<Derived> &point) const {
static_assert(Derived::IsVectorAtCompileTime && int(Derived::SizeAtCompileTime) == 2, "GCodeGenerator::point_to_gcode_quantized(): first parameter is not a 2D vector");
Vec2d p = this->point_to_gcode(point);
return { GCodeFormatter::quantize_xyzf(p.x()), GCodeFormatter::quantize_xyzf(p.y()) };
}
Point gcode_to_point(const Vec2d &point) const;
const FullPrintConfig &config() const { return m_config; }
const Layer* layer() const { return m_layer; }
@@ -187,6 +249,8 @@ public:
// append full config to the given string
static void append_full_config(const Print& print, std::string& str);
// translate full config into a list of <key, value> items
static void encode_full_config(const Print& print, std::vector<std::pair<std::string, std::string>>& config);
// Object and support extrusions of the same PrintObject at the same print_z.
// public, so that it could be accessed by free helper functions from GCode.cpp
@@ -250,6 +314,7 @@ private:
// Set of object & print layers of the same PrintObject and with the same print_z.
const ObjectsLayerToPrint &layers,
const LayerTools &layer_tools,
const GCode::SmoothPathCaches &smooth_path_caches,
const bool last_layer,
// Pairs of PrintObject index and its instance index.
const std::vector<const PrintInstance*> *ordering,
@@ -264,6 +329,7 @@ private:
const ToolOrdering &tool_ordering,
const std::vector<const PrintInstance*> &print_object_instances_ordering,
const std::vector<std::pair<coordf_t, ObjectsLayerToPrint>> &layers_to_print,
const GCode::SmoothPathCache &smooth_path_cache_global,
GCodeOutputStream &output_stream);
// Process all layers of a single object instance (sequential mode) with a parallel pipeline:
// Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
@@ -273,17 +339,26 @@ private:
const ToolOrdering &tool_ordering,
ObjectsLayerToPrint layers_to_print,
const size_t single_object_idx,
const GCode::SmoothPathCache &smooth_path_cache_global,
GCodeOutputStream &output_stream);
void set_last_pos(const Point &pos) { m_last_pos = pos; m_last_pos_defined = true; }
bool last_pos_defined() const { return m_last_pos_defined; }
void set_extruders(const std::vector<unsigned int> &extruder_ids);
std::string preamble();
std::string change_layer(coordf_t print_z);
std::string extrude_entity(const ExtrusionEntity &entity, const std::string_view description, double speed = -1.);
std::string extrude_loop(ExtrusionLoop loop, const std::string_view description, double speed = -1.);
std::string extrude_multi_path(ExtrusionMultiPath multipath, const std::string_view description, double speed = -1.);
std::string extrude_path(ExtrusionPath path, const std::string_view description, double speed = -1.);
std::optional<std::string> get_helical_layer_change_gcode(
const coordf_t previous_layer_z,
const coordf_t print_z,
const std::string& comment
);
std::string change_layer(coordf_t previous_layer_z, coordf_t print_z);
std::string extrude_entity(const ExtrusionEntityReference &entity, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed = -1.);
std::string extrude_loop(const ExtrusionLoop &loop, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed = -1.);
std::string extrude_skirt(const ExtrusionLoop &loop_src, const ExtrusionFlow &extrusion_flow_override,
const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed);
std::string extrude_multi_path(const ExtrusionMultiPath &multipath, bool reverse, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed = -1.);
std::string extrude_path(const ExtrusionPath &path, bool reverse, const GCode::SmoothPathCache &smooth_path_cache, const std::string_view description, double speed = -1.);
struct InstanceToPrint
{
@@ -317,18 +392,27 @@ private:
const ObjectLayerToPrint &layer_to_print,
// Container for extruder overrides (when wiping into object or infill).
const LayerTools &layer_tools,
// Optional smooth path interpolating extrusion polylines.
const GCode::SmoothPathCache &smooth_path_cache,
// Is any extrusion possibly marked as wiping extrusion?
const bool is_anything_overridden,
// Round 1 (wiping into object or infill) or round 2 (normal extrusions).
const bool print_wipe_extrusions);
std::string extrude_support(const ExtrusionEntityCollection &support_fills);
std::string extrude_support(const ExtrusionEntityReferences &support_fills, const GCode::SmoothPathCache &smooth_path_cache);
std::string generate_travel_gcode(
const Points3& travel,
const std::string& comment
);
Polyline generate_travel_xy_path(
const Point& start,
const Point& end,
const bool needs_retraction,
bool& could_be_wipe_disabled
);
std::string travel_to(const Point &point, ExtrusionRole role, std::string comment);
bool needs_retraction(const Polyline &travel, ExtrusionRole role = ExtrusionRole::None);
std::string retract(bool toolchange = false);
std::string unretract() { return m_writer.unlift() + m_writer.unretract(); }
std::string set_extruder(unsigned int extruder_id, double print_z);
//B41
std::string set_object_range(Print &print);
@@ -338,11 +422,13 @@ private:
int unique_id;
};
std::unordered_map<const PrintInstance *, LabelData> m_label_data;
std::string retract_and_wipe(bool toolchange = false);
std::string unretract() { return m_writer.unretract(); }
std::string set_extruder(unsigned int extruder_id, double print_z);
bool line_distancer_is_required(const std::vector<unsigned int>& extruder_ids);
// Cache for custom seam enforcers/blockers for each layer.
SeamPlacer m_seam_placer;
ExtrusionQualityEstimator m_extrusion_quality_estimator;
/* Origin of print coordinates expressed in unscaled G-code coordinates.
This affects the input arguments supplied to the extrude*() and travel_to()
@@ -367,8 +453,8 @@ private:
// Input/output from/to custom G-code block, for returning position, retraction etc.
DynamicConfig output_config;
ConfigOptionFloats *opt_position { nullptr };
ConfigOptionFloat *opt_zhop { nullptr };
ConfigOptionFloats *opt_e_position { nullptr };
ConfigOptionFloat *opt_zhop { nullptr };
ConfigOptionFloats *opt_e_retracted { nullptr };
ConfigOptionFloats *opt_e_restart_extra { nullptr };
ConfigOptionFloats *opt_extruded_volume { nullptr };
@@ -384,7 +470,8 @@ private:
} m_placeholder_parser_integration;
OozePrevention m_ooze_prevention;
Wipe m_wipe;
GCode::Wipe m_wipe;
GCode::LabelObjects m_label_objects;
AvoidCrossingPerimeters m_avoid_crossing_perimeters;
JPSPathFinder m_avoid_crossing_curled_overhangs;
RetractWhenCrossingPerimeters m_retract_when_crossing_perimeters;
@@ -407,6 +494,7 @@ private:
// In non-sequential mode, all its copies will be printed.
const Layer* m_layer;
// m_layer is an object layer and it is being printed over raft surface.
std::optional<AABBTreeLines::LinesDistancer<Linef>> m_previous_layer_distancer;
bool m_object_layer_over_raft;
double m_volumetric_speed;
// Support for the extrusion role markers. Which marker is active?
@@ -427,7 +515,7 @@ private:
std::unique_ptr<SpiralVase> m_spiral_vase;
std::unique_ptr<GCodeFindReplace> m_find_replace;
std::unique_ptr<PressureEqualizer> m_pressure_equalizer;
std::unique_ptr<WipeTowerIntegration> m_wipe_tower;
std::unique_ptr<GCode::WipeTowerIntegration> m_wipe_tower;
// Heights (print_z) at which the skirt has already been extruded.
std::vector<coordf_t> m_skirt_done;
@@ -443,7 +531,8 @@ private:
// Processor
GCodeProcessor m_processor;
std::string _extrude(const ExtrusionPath &path, const std::string_view description, double speed = -1);
std::string _extrude(
const ExtrusionAttributes &attribs, const Geometry::ArcWelder::Path &path, const std::string_view description, double speed = -1);
void print_machine_envelope(GCodeOutputStream &file, Print &print);
void _print_first_layer_bed_temperature(GCodeOutputStream &file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait);
void _print_first_layer_extruder_temperatures(GCodeOutputStream &file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait);
@@ -453,8 +542,12 @@ private:
// To control print speed of 1st object layer over raft interface.
bool object_layer_over_raft() const { return m_object_layer_over_raft; }
friend class Wipe;
friend class WipeTowerIntegration;
// Fill in cache of smooth paths for perimeters, fills and supports of the given object layers.
// Based on params, the paths are either decimated to sparser polylines, or interpolated with circular arches.
static void smooth_path_interpolate(const ObjectLayerToPrint &layers, const GCode::SmoothPathCache::InterpolationParameters &params, GCode::SmoothPathCache &out);
friend class GCode::Wipe;
friend class GCode::WipeTowerIntegration;
friend class PressureEqualizer;
};