Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Slic3r::SpiralVase Class Reference

#include <src/libslic3r/GCode/SpiralVase.hpp>

+ Collaboration diagram for Slic3r::SpiralVase:

Public Member Functions

 SpiralVase (const PrintConfig &config)
 
void enable (bool en)
 
std::string process_layer (const std::string &gcode)
 

Private Attributes

const PrintConfig & m_config
 
GCodeReader m_reader
 
bool m_enabled = false
 
bool m_transition_layer = false
 

Detailed Description

Constructor & Destructor Documentation

◆ SpiralVase()

Slic3r::SpiralVase::SpiralVase ( const PrintConfig &  config)
inline
11 : m_config(config)
12 {
13 m_reader.z() = (float)m_config.z_offset;
15 };
float & z()
Definition GCodeReader.hpp:145
void apply_config(const GCodeConfig &config)
Definition GCodeReader.cpp:25
const PrintConfig & m_config
Definition SpiralVase.hpp:25
GCodeReader m_reader
Definition SpiralVase.hpp:26

References Slic3r::GCodeReader::apply_config(), m_config, m_reader, and Slic3r::GCodeReader::z().

+ Here is the call graph for this function:

Member Function Documentation

◆ enable()

void Slic3r::SpiralVase::enable ( bool  en)
inline
17 {
19 m_enabled = en;
20 }
bool m_enabled
Definition SpiralVase.hpp:28
bool m_transition_layer
Definition SpiralVase.hpp:30

References m_enabled, and m_transition_layer.

◆ process_layer()

std::string Slic3r::SpiralVase::process_layer ( const std::string &  gcode)
8{
9 /* This post-processor relies on several assumptions:
10 - all layers are processed through it, including those that are not supposed
11 to be transformed, in order to update the reader with the XY positions
12 - each call to this method includes a full layer, with a single Z move
13 at the beginning
14 - each layer is composed by suitable geometry (i.e. a single complete loop)
15 - loops were not clipped before calling this method */
16
17 // If we're not going to modify G-code, just feed it to the reader
18 // in order to update positions.
19 if (! m_enabled) {
21 return gcode;
22 }
23
24 // Get total XY length for this layer by summing all extrusion moves.
25 float total_layer_length = 0;
26 float layer_height = 0;
27 float z = 0.f;
28
29 {
30 //FIXME Performance warning: This copies the GCodeConfig of the reader.
31 GCodeReader r = m_reader; // clone
32 bool set_z = false;
33 r.parse_buffer(gcode, [&total_layer_length, &layer_height, &z, &set_z]
34 (GCodeReader &reader, const GCodeReader::GCodeLine &line) {
35 if (line.cmd_is("G1")) {
36 if (line.extruding(reader)) {
37 total_layer_length += line.dist_XY(reader);
38 } else if (line.has(Z)) {
39 layer_height += line.dist_Z(reader);
40 if (!set_z) {
41 z = line.new_Z(reader);
42 set_z = true;
43 }
44 }
45 }
46 });
47 }
48
49 // Remove layer height from initial Z.
50 z -= layer_height;
51
52 std::string new_gcode;
53 //FIXME Tapering of the transition layer only works reliably with relative extruder distances.
54 // For absolute extruder distances it will be switched off.
55 // Tapering the absolute extruder distances requires to process every extrusion value after the first transition
56 // layer.
57 bool transition = m_transition_layer && m_config.use_relative_e_distances.value;
58 float layer_height_factor = layer_height / total_layer_length;
59 float len = 0.f;
60 m_reader.parse_buffer(gcode, [&new_gcode, &z, total_layer_length, layer_height_factor, transition, &len]
61 (GCodeReader &reader, GCodeReader::GCodeLine line) {
62 if (line.cmd_is("G1")) {
63 if (line.has_z()) {
64 // If this is the initial Z move of the layer, replace it with a
65 // (redundant) move to the last Z of previous layer.
66 line.set(reader, Z, z);
67 new_gcode += line.raw() + '\n';
68 return;
69 } else {
70 float dist_XY = line.dist_XY(reader);
71 if (dist_XY > 0) {
72 // horizontal move
73 if (line.extruding(reader)) {
74 len += dist_XY;
75 line.set(reader, Z, z + len * layer_height_factor);
76 if (transition && line.has(E))
77 // Transition layer, modulate the amount of extrusion from zero to the final value.
78 line.set(reader, E, line.value(E) * len / total_layer_length);
79 new_gcode += line.raw() + '\n';
80 }
81 return;
82
83 /* Skip travel moves: the move to first perimeter point will
84 cause a visible seam when loops are not aligned in XY; by skipping
85 it we blend the first loop move in the XY plane (although the smoothness
86 of such blend depend on how long the first segment is; maybe we should
87 enforce some minimum length?). */
88 }
89 }
90 }
91 new_gcode += line.raw() + '\n';
92 });
93
94 return new_gcode;
95}
void parse_buffer(const std::string &buffer, Callback callback)
Definition GCodeReader.hpp:101
if(!(yy_init))
Definition lexer.c:1190
layer_height((ConfigOptionInt, faded_layers))((ConfigOptionFloat
@ Z
Definition libslic3r.h:100

References Slic3r::GCodeReader::GCodeLine::cmd_is(), Slic3r::GCodeReader::GCodeLine::has(), if(), Slic3r::layer_height(), m_enabled, m_reader, Slic3r::GCodeReader::parse_buffer(), and Slic3r::Z.

+ Here is the call graph for this function:

Member Data Documentation

◆ m_config

const PrintConfig& Slic3r::SpiralVase::m_config
private

Referenced by SpiralVase().

◆ m_enabled

bool Slic3r::SpiralVase::m_enabled = false
private

Referenced by enable(), and process_layer().

◆ m_reader

GCodeReader Slic3r::SpiralVase::m_reader
private

Referenced by SpiralVase(), and process_layer().

◆ m_transition_layer

bool Slic3r::SpiralVase::m_transition_layer = false
private

Referenced by enable().


The documentation for this class was generated from the following files: