2023-06-10 10:14:12 +08:00
# ifndef slic3r_GCode_hpp_
# define slic3r_GCode_hpp_
# include "GCode/ExtrusionProcessor.hpp"
# include "JumpPointSearch.hpp"
# include "libslic3r.h"
# include "ExPolygon.hpp"
# include "Layer.hpp"
# include "Point.hpp"
# include "PlaceholderParser.hpp"
# include "PrintConfig.hpp"
2023-12-27 18:02:35 +08:00
# include "Geometry/ArcWelder.hpp"
2023-06-10 10:14:12 +08:00
# include "GCode/AvoidCrossingPerimeters.hpp"
# include "GCode/CoolingBuffer.hpp"
# include "GCode/FindReplace.hpp"
2023-12-27 18:02:35 +08:00
# include "GCode/GCodeWriter.hpp"
# include "GCode/LabelObjects.hpp"
# include "GCode/PressureEqualizer.hpp"
2023-06-10 10:14:12 +08:00
# include "GCode/RetractWhenCrossingPerimeters.hpp"
2023-12-27 18:02:35 +08:00
# include "GCode/SmoothPath.hpp"
2023-06-10 10:14:12 +08:00
# include "GCode/SpiralVase.hpp"
# include "GCode/ToolOrdering.hpp"
2023-12-27 18:02:35 +08:00
# include "GCode/Wipe.hpp"
# include "GCode/WipeTowerIntegration.hpp"
2023-06-10 10:14:12 +08:00
# include "GCode/SeamPlacer.hpp"
# include "GCode/GCodeProcessor.hpp"
# include "EdgeGrid.hpp"
# include "GCode/ThumbnailData.hpp"
2023-12-27 18:02:35 +08:00
# include "tcbspan/span.hpp"
2023-06-10 10:14:12 +08:00
# include <memory>
# include <map>
# include <string>
2023-12-27 18:02:35 +08:00
//#include "GCode/PressureEqualizer.hpp"
2023-06-10 10:14:12 +08:00
namespace Slic3r {
// Forward declarations.
2023-12-27 18:02:35 +08:00
class GCodeGenerator ;
2023-06-10 10:14:12 +08:00
namespace { struct Item ; }
struct PrintInstance ;
class OozePrevention {
public :
bool enable ;
OozePrevention ( ) : enable ( false ) { }
2023-12-27 18:02:35 +08:00
std : : string pre_toolchange ( GCodeGenerator & gcodegen ) ;
std : : string post_toolchange ( GCodeGenerator & gcodegen ) ;
2023-06-10 10:14:12 +08:00
private :
2023-12-27 18:02:35 +08:00
int _get_temp ( const GCodeGenerator & gcodegen ) const ;
2023-06-10 10:14:12 +08:00
} ;
class ColorPrintColors
{
static const std : : vector < std : : string > Colors ;
public :
static const std : : vector < std : : string > & get ( ) { return Colors ; }
} ;
struct LayerResult {
std : : string gcode ;
size_t layer_id ;
// Is spiral vase post processing enabled for this layer?
bool spiral_vase_enable { false } ;
// Should the cooling buffer content be flushed at the end of this layer?
bool cooling_buffer_flush { false } ;
// Is indicating if this LayerResult should be processed, or it is just inserted artificial LayerResult.
// It is used for the pressure equalizer because it needs to buffer one layer back.
bool nop_layer_result { false } ;
static LayerResult make_nop_layer_result ( ) { return { " " , std : : numeric_limits < coord_t > : : max ( ) , false , false , true } ; }
} ;
2023-12-27 18:02:35 +08:00
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 2 D .
* @ 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 {
2023-06-10 10:14:12 +08:00
public :
2023-12-27 18:02:35 +08:00
GCodeGenerator ( ) :
2023-06-10 10:14:12 +08:00
m_origin ( Vec2d : : Zero ( ) ) ,
m_enable_loop_clipping ( true ) ,
m_enable_cooling_markers ( false ) ,
m_enable_extrusion_role_markers ( false ) ,
m_last_processor_extrusion_role ( GCodeExtrusionRole : : None ) ,
m_layer_count ( 0 ) ,
m_layer_index ( - 1 ) ,
m_layer ( nullptr ) ,
m_object_layer_over_raft ( false ) ,
m_volumetric_speed ( 0 ) ,
m_last_pos_defined ( false ) ,
m_last_extrusion_role ( GCodeExtrusionRole : : None ) ,
m_last_width ( 0.0f ) ,
# if ENABLE_GCODE_VIEWER_DATA_CHECKING
m_last_mm3_per_mm ( 0.0 ) ,
# endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
m_brim_done ( false ) ,
m_second_layer_things_done ( false ) ,
m_silent_time_estimator_enabled ( false ) ,
m_last_obj_copy ( nullptr , Point ( std : : numeric_limits < coord_t > : : max ( ) , std : : numeric_limits < coord_t > : : max ( ) ) )
{ }
2023-12-27 18:02:35 +08:00
~ GCodeGenerator ( ) = default ;
2023-06-10 10:14:12 +08:00
// throws std::runtime_exception on error,
// throws CanceledException through print->throw_if_canceled().
void do_export ( Print * print , const char * path , GCodeProcessorResult * result = nullptr , ThumbnailsGeneratorCallback thumbnail_cb = nullptr ) ;
// Exported for the helper classes (OozePrevention, Wipe) and for the Perl binding for unit tests.
const Vec2d & origin ( ) const { return m_origin ; }
void set_origin ( const Vec2d & pointf ) ;
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.
2023-12-27 18:02:35 +08:00
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 ( ) ) ;
}
2023-06-10 10:14:12 +08:00
// Convert coordinates of the active object to G-code coordinates, possibly adjusted for extruder offset and quantized to G-code resolution.
2023-12-27 18:02:35 +08:00
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 ( ) ) } ;
}
2023-06-10 10:14:12 +08:00
Point gcode_to_point ( const Vec2d & point ) const ;
const FullPrintConfig & config ( ) const { return m_config ; }
const Layer * layer ( ) const { return m_layer ; }
GCodeWriter & writer ( ) { return m_writer ; }
const GCodeWriter & writer ( ) const { return m_writer ; }
PlaceholderParser & placeholder_parser ( ) { return m_placeholder_parser_integration . parser ; }
const PlaceholderParser & placeholder_parser ( ) const { return m_placeholder_parser_integration . parser ; }
// Process a template through the placeholder parser, collect error messages to be reported
// inside the generated string and after the G-code export finishes.
std : : string placeholder_parser_process ( const std : : string & name , const std : : string & templ , unsigned int current_extruder_id , const DynamicConfig * config_override = nullptr ) ;
bool enable_cooling_markers ( ) const { return m_enable_cooling_markers ; }
// For Perl bindings, to be used exclusively by unit tests.
unsigned int layer_count ( ) const { return m_layer_count ; }
void set_layer_count ( unsigned int value ) { m_layer_count = value ; }
void apply_print_config ( const PrintConfig & print_config ) ;
// append full config to the given string
static void append_full_config ( const Print & print , std : : string & str ) ;
2023-12-27 18:02:35 +08:00
// 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 ) ;
2023-06-10 10:14:12 +08:00
// 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
struct ObjectLayerToPrint
{
ObjectLayerToPrint ( ) : object_layer ( nullptr ) , support_layer ( nullptr ) { }
const Layer * object_layer ;
const SupportLayer * support_layer ;
const Layer * layer ( ) const { return ( object_layer ! = nullptr ) ? object_layer : support_layer ; }
const PrintObject * object ( ) const { return ( this - > layer ( ) ! = nullptr ) ? this - > layer ( ) - > object ( ) : nullptr ; }
coordf_t print_z ( ) const { return ( object_layer ! = nullptr & & support_layer ! = nullptr ) ? 0.5 * ( object_layer - > print_z + support_layer - > print_z ) : this - > layer ( ) - > print_z ; }
} ;
using ObjectsLayerToPrint = std : : vector < ObjectLayerToPrint > ;
private :
class GCodeOutputStream {
public :
GCodeOutputStream ( FILE * f , GCodeProcessor & processor ) : f ( f ) , m_processor ( processor ) { }
~ GCodeOutputStream ( ) { this - > close ( ) ; }
// Set a find-replace post-processor to modify the G-code before GCodePostProcessor.
// It is being set to null inside process_layers(), because the find-replace process
// is being called on a secondary thread to improve performance.
void set_find_replace ( GCodeFindReplace * find_replace , bool enabled ) { m_find_replace_backup = find_replace ; m_find_replace = enabled ? find_replace : nullptr ; }
void find_replace_enable ( ) { m_find_replace = m_find_replace_backup ; }
void find_replace_supress ( ) { m_find_replace = nullptr ; }
bool is_open ( ) const { return f ; }
bool is_error ( ) const ;
void flush ( ) ;
void close ( ) ;
// Write a string into a file.
void write ( const std : : string & what ) { this - > write ( what . c_str ( ) ) ; }
void write ( const char * what ) ;
// Write a string into a file.
// Add a newline, if the string does not end with a newline already.
// Used to export a custom G-code section processed by the PlaceholderParser.
void writeln ( const std : : string & what ) ;
// Formats and write into a file the given data.
void write_format ( const char * format , . . . ) ;
private :
FILE * f { nullptr } ;
// Find-replace post-processor to be called before GCodePostProcessor.
GCodeFindReplace * m_find_replace { nullptr } ;
// If suppressed, the backoup holds m_find_replace.
GCodeFindReplace * m_find_replace_backup { nullptr } ;
GCodeProcessor & m_processor ;
} ;
void _do_export ( Print & print , GCodeOutputStream & file , ThumbnailsGeneratorCallback thumbnail_cb ) ;
static ObjectsLayerToPrint collect_layers_to_print ( const PrintObject & object ) ;
static std : : vector < std : : pair < coordf_t , ObjectsLayerToPrint > > collect_layers_to_print ( const Print & print ) ;
LayerResult process_layer (
const Print & print ,
// Set of object & print layers of the same PrintObject and with the same print_z.
const ObjectsLayerToPrint & layers ,
const LayerTools & layer_tools ,
2023-12-27 18:02:35 +08:00
const GCode : : SmoothPathCaches & smooth_path_caches ,
2023-06-10 10:14:12 +08:00
const bool last_layer ,
// Pairs of PrintObject index and its instance index.
const std : : vector < const PrintInstance * > * ordering ,
// If set to size_t(-1), then print all copies of all objects.
// Otherwise print a single copy of a single object.
const size_t single_object_idx = size_t ( - 1 ) ) ;
// Process all layers of all objects (non-sequential mode) with a parallel pipeline:
// Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser
// and export G-code into file.
void process_layers (
const Print & print ,
const ToolOrdering & tool_ordering ,
const std : : vector < const PrintInstance * > & print_object_instances_ordering ,
const std : : vector < std : : pair < coordf_t , ObjectsLayerToPrint > > & layers_to_print ,
2023-12-27 18:02:35 +08:00
const GCode : : SmoothPathCache & smooth_path_cache_global ,
2023-06-10 10:14:12 +08:00
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
// and export G-code into file.
void process_layers (
const Print & print ,
const ToolOrdering & tool_ordering ,
ObjectsLayerToPrint layers_to_print ,
const size_t single_object_idx ,
2023-12-27 18:02:35 +08:00
const GCode : : SmoothPathCache & smooth_path_cache_global ,
2023-06-10 10:14:12 +08:00
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 ( ) ;
2023-12-27 18:02:35 +08:00
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. ) ;
2023-06-10 10:14:12 +08:00
struct InstanceToPrint
{
InstanceToPrint ( size_t object_layer_to_print_id , const PrintObject & print_object , size_t instance_id ) :
object_layer_to_print_id ( object_layer_to_print_id ) , print_object ( print_object ) , instance_id ( instance_id ) { }
// Index into std::vector<ObjectLayerToPrint>, which contains Object and Support layers for the current print_z, collected for a single object, or for possibly multiple objects with multiple instances.
const size_t object_layer_to_print_id ;
const PrintObject & print_object ;
// Instance idx of the copy of a print object.
const size_t instance_id ;
} ;
std : : vector < InstanceToPrint > sort_print_object_instances (
// Object and Support layers for the current print_z, collected for a single object, or for possibly multiple objects with multiple instances.
const std : : vector < ObjectLayerToPrint > & layers ,
// Ordering must be defined for normal (non-sequential print).
const std : : vector < const PrintInstance * > * ordering ,
// For sequential print, the instance of the object to be printing has to be defined.
const size_t single_object_instance_idx ) ;
// This function will be called for each printing extruder, possibly twice: First for wiping extrusions, second for normal extrusions.
void process_layer_single_object (
// output
std : : string & gcode ,
// Index of the extruder currently active.
const unsigned int extruder_id ,
// What object and instance is going to be printed.
const InstanceToPrint & print_instance ,
// and the object & support layer of the above.
const ObjectLayerToPrint & layer_to_print ,
// Container for extruder overrides (when wiping into object or infill).
const LayerTools & layer_tools ,
2023-12-27 18:02:35 +08:00
// Optional smooth path interpolating extrusion polylines.
const GCode : : SmoothPathCache & smooth_path_cache ,
2023-06-10 10:14:12 +08:00
// 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 ) ;
2023-12-27 18:02:35 +08:00
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
) ;
2023-06-10 10:14:12 +08:00
std : : string travel_to ( const Point & point , ExtrusionRole role , std : : string comment ) ;
bool needs_retraction ( const Polyline & travel , ExtrusionRole role = ExtrusionRole : : None ) ;
2023-10-04 15:23:05 +08:00
//B41
std : : string set_object_range ( Print & print ) ;
2023-10-27 14:31:34 +08:00
struct LabelData
{
std : : string name ;
int unique_id ;
} ;
std : : unordered_map < const PrintInstance * , LabelData > m_label_data ;
2023-12-27 18:02:35 +08:00
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 ) ;
2023-06-10 10:14:12 +08:00
// Cache for custom seam enforcers/blockers for each layer.
SeamPlacer m_seam_placer ;
/* Origin of print coordinates expressed in unscaled G-code coordinates.
This affects the input arguments supplied to the extrude * ( ) and travel_to ( )
methods . */
Vec2d m_origin ;
FullPrintConfig m_config ;
// scaled G-code resolution
double m_scaled_resolution ;
GCodeWriter m_writer ;
struct PlaceholderParserIntegration {
void reset ( ) ;
void init ( const GCodeWriter & config ) ;
void update_from_gcodewriter ( const GCodeWriter & writer ) ;
void validate_output_vector_variables ( ) ;
PlaceholderParser parser ;
// For random number generator etc.
PlaceholderParser : : ContextData context ;
// Collection of templates, on which the placeholder substitution failed.
std : : map < std : : string , std : : string > failed_templates ;
// Input/output from/to custom G-code block, for returning position, retraction etc.
DynamicConfig output_config ;
ConfigOptionFloats * opt_position { nullptr } ;
ConfigOptionFloats * opt_e_position { nullptr } ;
2023-12-27 18:02:35 +08:00
ConfigOptionFloat * opt_zhop { nullptr } ;
2023-06-10 10:14:12 +08:00
ConfigOptionFloats * opt_e_retracted { nullptr } ;
ConfigOptionFloats * opt_e_restart_extra { nullptr } ;
ConfigOptionFloats * opt_extruded_volume { nullptr } ;
ConfigOptionFloats * opt_extruded_weight { nullptr } ;
ConfigOptionFloat * opt_extruded_volume_total { nullptr } ;
ConfigOptionFloat * opt_extruded_weight_total { nullptr } ;
// Caches of the data passed to the script.
size_t num_extruders ;
std : : vector < double > position ;
std : : vector < double > e_position ;
std : : vector < double > e_retracted ;
std : : vector < double > e_restart_extra ;
} m_placeholder_parser_integration ;
OozePrevention m_ooze_prevention ;
2023-12-27 18:02:35 +08:00
GCode : : Wipe m_wipe ;
GCode : : LabelObjects m_label_objects ;
2023-06-10 10:14:12 +08:00
AvoidCrossingPerimeters m_avoid_crossing_perimeters ;
JPSPathFinder m_avoid_crossing_curled_overhangs ;
RetractWhenCrossingPerimeters m_retract_when_crossing_perimeters ;
bool m_enable_loop_clipping ;
// If enabled, the G-code generator will put following comments at the ends
// of the G-code lines: _EXTRUDE_SET_SPEED, _WIPE, _BRIDGE_FAN_START, _BRIDGE_FAN_END
// Those comments are received and consumed (removed from the G-code) by the CoolingBuffer.pm Perl module.
bool m_enable_cooling_markers ;
// Markers for the Pressure Equalizer to recognize the extrusion type.
// The Pressure Equalizer removes the markers from the final G-code.
bool m_enable_extrusion_role_markers ;
// Keeps track of the last extrusion role passed to the processor
GCodeExtrusionRole m_last_processor_extrusion_role ;
// How many times will change_layer() be called?
// change_layer() will update the progress bar.
unsigned int m_layer_count ;
// Progress bar indicator. Increments from -1 up to layer_count.
int m_layer_index ;
// Current layer processed. In sequential printing mode, only a single copy will be printed.
// 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.
2023-12-27 18:02:35 +08:00
std : : optional < AABBTreeLines : : LinesDistancer < Linef > > m_previous_layer_distancer ;
2023-06-10 10:14:12 +08:00
bool m_object_layer_over_raft ;
double m_volumetric_speed ;
// Support for the extrusion role markers. Which marker is active?
GCodeExtrusionRole m_last_extrusion_role ;
// Support for G-Code Processor
float m_last_height { 0.0f } ;
float m_last_layer_z { 0.0f } ;
float m_max_layer_z { 0.0f } ;
float m_last_width { 0.0f } ;
# if ENABLE_GCODE_VIEWER_DATA_CHECKING
double m_last_mm3_per_mm ;
# endif // ENABLE_GCODE_VIEWER_DATA_CHECKING
Point m_last_pos ;
bool m_last_pos_defined ;
std : : unique_ptr < CoolingBuffer > m_cooling_buffer ;
std : : unique_ptr < SpiralVase > m_spiral_vase ;
std : : unique_ptr < GCodeFindReplace > m_find_replace ;
std : : unique_ptr < PressureEqualizer > m_pressure_equalizer ;
2023-12-27 18:02:35 +08:00
std : : unique_ptr < GCode : : WipeTowerIntegration > m_wipe_tower ;
2023-06-10 10:14:12 +08:00
// Heights (print_z) at which the skirt has already been extruded.
std : : vector < coordf_t > m_skirt_done ;
// Has the brim been extruded already? Brim is being extruded only for the first object of a multi-object print.
bool m_brim_done ;
// Flag indicating whether the nozzle temperature changes from 1st to 2nd layer were performed.
bool m_second_layer_things_done ;
// Index of a last object copy extruded.
std : : pair < const PrintObject * , Point > m_last_obj_copy ;
bool m_silent_time_estimator_enabled ;
// Processor
GCodeProcessor m_processor ;
2023-12-27 18:02:35 +08:00
std : : string _extrude (
const ExtrusionAttributes & attribs , const Geometry : : ArcWelder : : Path & path , const std : : string_view description , double speed = - 1 ) ;
2023-06-10 10:14:12 +08:00
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 ) ;
// On the first printing layer. This flag triggers first layer speeds.
bool on_first_layer ( ) const { return m_layer ! = nullptr & & m_layer - > id ( ) = = 0 ; }
// To control print speed of 1st object layer over raft interface.
bool object_layer_over_raft ( ) const { return m_object_layer_over_raft ; }
2023-12-27 18:02:35 +08:00
// 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 ;
2023-06-10 10:14:12 +08:00
friend class PressureEqualizer ;
} ;
std : : vector < const PrintInstance * > sort_object_instances_by_model_order ( const Print & print ) ;
}
# endif