Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jalapeno/snapmaker z skip #14060

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 9 additions & 12 deletions src/libslic3r/GCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1276,7 +1276,7 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail
file.write(this->retract_and_wipe());
file.write(m_label_objects.maybe_stop_instance());
const double last_z{this->writer().get_position().z()};
file.write(this->writer().get_travel_to_z_gcode(last_z, "ensure z position"));
file.write(this->writer().travel_to_z_force(last_z, "ensure z position"));
const Vec3crd from{to_3d(*this->last_position, scaled(this->m_last_layer_z))};
const Vec3crd to{0, 0, scaled(this->m_last_layer_z)};
file.write(this->travel_to(from, to, ExtrusionRole::None, "move to origin position for next object", [](){return "";}));
Expand Down Expand Up @@ -2245,7 +2245,7 @@ std::string GCodeGenerator::generate_ramping_layer_change_gcode(
const Polyline &xy_path,
const double initial_elevation,
const GCode::Impl::Travels::ElevatedTravelParams &elevation_params
) const {
) {
using namespace GCode::Impl::Travels;

const std::vector<double> ensure_points_at_distances = linspace(
Expand All @@ -2263,7 +2263,7 @@ std::string GCodeGenerator::generate_ramping_layer_change_gcode(
for (const Vec3crd &point : travel) {
const Vec3d gcode_point{this->point_to_gcode(point)};
travel_gcode += this->m_writer
.get_travel_to_xyz_gcode(gcode_point, "layer change");
.travel_to_xyz_force(gcode_point, "layer change");
}
return travel_gcode;
}
Expand Down Expand Up @@ -2970,11 +2970,8 @@ std::string GCodeGenerator::change_layer(
gcode += this->retract_and_wipe();
}
if (!first_layer) {
// travel_to_z is not used as it may not generate the travel if the writter z == print_z.
gcode += this->writer().get_travel_to_z_gcode(print_z, "simple layer change");
Vec3d position{this->writer().get_position()};
position.z() = print_z;
this->writer().update_position(position);
// travel_to_z is not used as it may not generate the travel if the writer z == print_z.
gcode += this->writer().travel_to_z_force(print_z, "simple layer change");
}
}

Expand Down Expand Up @@ -3229,15 +3226,15 @@ std::string GCodeGenerator::travel_to_first_position(const Vec3crd& point, const
if (EXTRUDER_CONFIG(retract_length) > 0 && !this->last_position) {
if (!this->last_position || EXTRUDER_CONFIG(retract_before_travel) < (this->point_to_gcode(*this->last_position) - gcode_point.head<2>()).norm()) {
gcode += this->writer().retract();
gcode += this->writer().get_travel_to_z_gcode(from_z + lift, "lift");
gcode += this->writer().travel_to_z_force(from_z + lift, "lift");
}
}

const std::string comment{"move to first layer point"};

gcode += insert_gcode();
gcode += this->writer().get_travel_to_xy_gcode(gcode_point.head<2>(), comment);
gcode += this->writer().get_travel_to_z_gcode(gcode_point.z(), comment);
gcode += this->writer().travel_to_xy_force(gcode_point.head<2>(), comment);
gcode += this->writer().travel_to_z_force(gcode_point.z(), comment);

this->m_avoid_crossing_perimeters.reset_once_modifiers();
this->last_position = point.head<2>();
Expand Down Expand Up @@ -3293,7 +3290,7 @@ std::string GCodeGenerator::_extrude(
gcode += this->retract_and_wipe();
gcode += m_writer.multiple_extruders ? "" : m_label_objects.maybe_change_instance(m_writer);
gcode += this->m_writer.travel_to_xy(this->point_to_gcode(path.front().point), comment);
gcode += this->m_writer.get_travel_to_z_gcode(z, comment);
gcode += this->m_writer.travel_to_z_force(z, comment);
} else if ( this->last_position != path.front().point) {
std::string comment = "move to first ";
comment += description;
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/GCode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ class GCodeGenerator {
const Polyline &xy_path,
const double initial_elevation,
const GCode::Impl::Travels::ElevatedTravelParams &elevation_params
) const;
);

std::vector<GCode::ExtrusionOrder::ExtruderExtrusions> get_sorted_extrusions(
const Print &print,
Expand Down
72 changes: 44 additions & 28 deletions src/libslic3r/GCode/GCodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,19 +295,25 @@ std::string GCodeWriter::set_speed(double F, const std::string_view comment, con
return w.string();
}

std::string GCodeWriter::get_travel_to_xy_gcode(const Vec2d &point, const std::string_view comment) const
std::string GCodeWriter::travel_to_xy_force(const Vec2d &point, const std::string_view comment)
{
GCodeG1Formatter w;
w.emit_xy(point);
w.emit_f(this->config.travel_speed.value * 60.0);
w.emit_comment(this->config.gcode_comments, comment);
m_pos.head<2>() = point.head<2>();
return w.string();
}

std::string GCodeWriter::travel_to_xy(const Vec2d &point, const std::string_view comment)
{
m_pos.head<2>() = point.head<2>();
return this->get_travel_to_xy_gcode(point, comment);
if (std::abs(point.x() - m_pos.x()) < GCodeFormatter::XYZ_EPSILON
&& std::abs(point.y() - m_pos.y()) < GCodeFormatter::XYZ_EPSILON)
{
return "";
} else {
return this->travel_to_xy_force(point, comment);
}
}

std::string GCodeWriter::travel_to_xy_G2G3IJ(const Vec2d &point, const Vec2d &ij, const bool ccw, const std::string_view comment)
Expand All @@ -329,51 +335,60 @@ std::string GCodeWriter::travel_to_xy_G2G3IJ(const Vec2d &point, const Vec2d &ij

std::string GCodeWriter::travel_to_xyz(const Vec3d &to, const std::string_view comment)
{
if (std::abs(to.x() - m_pos.x()) < EPSILON && std::abs(to.y() - m_pos.y()) < EPSILON) {
return this->travel_to_z(to.z(), comment);
} else if (std::abs(to.z() - m_pos.z()) < EPSILON) {
return this->travel_to_xy(to.head<2>(), comment);
if (std::abs(to.x() - m_pos.x()) < GCodeFormatter::XYZ_EPSILON
&& std::abs(to.y() - m_pos.y()) < GCodeFormatter::XYZ_EPSILON
&& std::abs(to.z() - m_pos.z()) < GCodeFormatter::XYZ_EPSILON)
{
return "";
} else if (
std::abs(to.x() - m_pos.x()) < GCodeFormatter::XYZ_EPSILON
&& std::abs(to.y() - m_pos.y()) < GCodeFormatter::XYZ_EPSILON)
{
return this->travel_to_z_force(to.z(), comment);
} else if (
std::abs(to.z() - m_pos.z()) < GCodeFormatter::XYZ_EPSILON)
{
return this->travel_to_xy_force(to.head<2>(), comment);
} else {
std::string result{this->get_travel_to_xyz_gcode(to, comment)};
m_pos = to;
return result;
return this->travel_to_xyz_force(to, comment);
}
}

std::string GCodeWriter::get_travel_to_xyz_gcode(const Vec3d &to, const std::string_view comment) const {
std::string GCodeWriter::travel_to_xyz_force(const Vec3d &to, const std::string_view comment) {
GCodeG1Formatter w;
w.emit_xyz(to);

double speed_z = this->config.travel_speed_z.value;
if (speed_z == 0.)
speed_z = this->config.travel_speed.value;

const double distance_xy{(to.head<2>() - m_pos.head<2>()).norm()};
const double distnace_z{std::abs(to.z() - m_pos.z())};
const double time_z = distnace_z / speed_z;
const double time_xy = distance_xy / this->config.travel_speed.value;
const double factor = time_z > 0 ? time_xy / time_z : 1;
if (factor < 1) {
w.emit_f(std::floor((this->config.travel_speed.value * factor + (1 - factor) * speed_z) * 60.0));
} else {
w.emit_f(this->config.travel_speed.value * 60.0);
double speed = this->config.travel_speed.value;
const double speed_z = this->config.travel_speed_z.value;

if (speed_z) {
const Vec3d move{to - m_pos};
const double distance{move.norm()};
const double abs_unit_vector_z{std::abs(move.z())/distance};
// De-compose speed into z vector component according to the movement unit vector.
const double speed_vector_z{abs_unit_vector_z * speed};
if (speed_vector_z > speed_z) {
// Re-compute speed so that the z component is exactly speed_z.
speed = speed_z / abs_unit_vector_z;
}
}
w.emit_f(speed * 60.0);

w.emit_comment(this->config.gcode_comments, comment);
m_pos = to;
return w.string();
}

std::string GCodeWriter::travel_to_z(double z, const std::string_view comment)
{
if (std::abs(m_pos.z() - z) < EPSILON) {
if (std::abs(m_pos.z() - z) < GCodeFormatter::XYZ_EPSILON) {
return "";
} else {
m_pos.z() = z;
return this->get_travel_to_z_gcode(z, comment);
return this->travel_to_z_force(z, comment);
}
}

std::string GCodeWriter::get_travel_to_z_gcode(double z, const std::string_view comment) const
std::string GCodeWriter::travel_to_z_force(double z, const std::string_view comment)
{
double speed = this->config.travel_speed_z.value;
if (speed == 0.)
Expand All @@ -383,6 +398,7 @@ std::string GCodeWriter::get_travel_to_z_gcode(double z, const std::string_view
w.emit_z(z);
w.emit_f(speed * 60.0);
w.emit_comment(this->config.gcode_comments, comment);
m_pos.z() = z;
return w.string();
}

Expand Down
44 changes: 33 additions & 11 deletions src/libslic3r/GCode/GCodeWriter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,27 +74,46 @@ class GCodeWriter {
std::string toolchange(unsigned int extruder_id);
std::string set_speed(double F, const std::string_view comment = {}, const std::string_view cooling_marker = {}) const;

std::string get_travel_to_xy_gcode(const Vec2d &point, const std::string_view comment) const;
std::string travel_to_xy(const Vec2d &point, const std::string_view comment = {});
std::string travel_to_xy_G2G3IJ(const Vec2d &point, const Vec2d &ij, const bool ccw, const std::string_view comment = {});

/**
* @brief Return gcode with all three axis defined. Optionally adds feedrate.
* @brief Return gcode to travel to the specified point.
* Feed rate is computed based on the vector (to - m_pos).
* Maintains the internal m_pos position.
* Movements less than XYZ_EPSILON generate no output.
*
* Feedrate is added the starting point "from" is specified.
*
* @param from Optional starting point of the travel.
* @param to Where to travel to.
* @param comment Description of the travel purpose.
*/
std::string get_travel_to_xyz_gcode(const Vec3d &to, const std::string_view comment) const;
std::string travel_to_xyz(const Vec3d &to, const std::string_view comment = {});
std::string get_travel_to_z_gcode(double z, const std::string_view comment) const;
std::string travel_to_xy(const Vec2d &point, const std::string_view comment = {});
std::string travel_to_z(double z, const std::string_view comment = {});

std::string travel_to_xy_G2G3IJ(const Vec2d &point, const Vec2d &ij, const bool ccw, const std::string_view comment = {});

/**
* @brief Generate G-Code to travel to the specified point unconditionally.
* Feed rate is computed based on the vector (to - m_pos).
* Maintains the internal m_pos position.
* The distance test XYZ_EPSILON is not performed.
* @param to The point to travel to.
* @param comment Description of the travel purpose.
*/
std::string travel_to_xyz_force(const Vec3d &to, const std::string_view comment = {});
std::string travel_to_xy_force(const Vec2d &point, const std::string_view comment = {});
std::string travel_to_z_force(double z, const std::string_view comment = {});

/**
* @brief Generate G-Code to move to the specified point while extruding.
* Maintains the internal m_pos position.
* The distance test XYZ_EPSILON is not performed.
* @param point The point to move to.
* @param dE The E-steps to extrude while moving.
* @param comment Description of the movement purpose.
*/
std::string extrude_to_xy(const Vec2d &point, double dE, const std::string_view comment = {});
std::string extrude_to_xyz(const Vec3d &point, double dE, const std::string_view comment = {});

std::string extrude_to_xy_G2G3IJ(const Vec2d &point, const Vec2d &ij, const bool ccw, double dE, const std::string_view comment);
// std::string extrude_to_xyz(const Vec3d &point, double dE, const std::string_view comment = {});

std::string retract(bool before_wipe = false);
std::string retract_for_toolchange(bool before_wipe = false);
std::string unretract();
Expand Down Expand Up @@ -176,6 +195,9 @@ class GCodeFormatter {
static constexpr const std::array<double, 10> pow_10 { 1., 10., 100., 1000., 10000., 100000., 1000000., 10000000., 100000000., 1000000000.};
static constexpr const std::array<double, 10> pow_10_inv{1./1., 1./10., 1./100., 1./1000., 1./10000., 1./100000., 1./1000000., 1./10000000., 1./100000000., 1./1000000000.};

// Compute XYZ_EPSILON based on XYZF_EXPORT_DIGITS
static constexpr double XYZ_EPSILON = pow_10_inv[XYZF_EXPORT_DIGITS];

// Quantize doubles to a resolution of the G-code.
static double quantize(double v, size_t ndigits) { return std::round(v * pow_10[ndigits]) * pow_10_inv[ndigits]; }
static double quantize_xyzf(double v) { return quantize(v, XYZF_EXPORT_DIGITS); }
Expand Down
7 changes: 2 additions & 5 deletions src/libslic3r/GCode/WipeTowerIntegration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ std::string WipeTowerIntegration::append_tcr(GCodeGenerator &gcodegen, const Wip
);
} else {
gcode += gcodegen.writer().travel_to_xy(gcodegen.point_to_gcode(xy_point), comment);
gcode += gcodegen.writer().get_travel_to_z_gcode(z, comment);
gcode += gcodegen.writer().travel_to_z_force(z, comment);
}
}
gcode += gcodegen.unretract();
Expand All @@ -100,10 +100,7 @@ std::string WipeTowerIntegration::append_tcr(GCodeGenerator &gcodegen, const Wip
gcodegen.m_wipe.reset_path(); // We don't want wiping on the ramming lines.
toolchange_gcode_str = gcodegen.set_extruder(new_extruder_id, tcr.print_z); // TODO: toolchange_z vs print_z
if (gcodegen.config().wipe_tower) {
deretraction_str += gcodegen.writer().get_travel_to_z_gcode(z, "restore layer Z");
Vec3d position{gcodegen.writer().get_position()};
position.z() = z;
gcodegen.writer().update_position(position);
deretraction_str += gcodegen.writer().travel_to_z_force(z, "restore layer Z");
deretraction_str += gcodegen.unretract();
}
}
Expand Down
Loading