From bc3d184d7cd5853677caaa75827b3ae5c19d9331 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Wed, 6 Dec 2017 14:12:10 +0100 Subject: [PATCH 01/33] time estimator wip --- cmake/modules/FindPerlEmbed.cmake | 2 - xs/src/libslic3r/GCode.cpp | 88 ++++ xs/src/libslic3r/GCodeTimeEstimator.cpp | 584 ++++++++++++++++++++++++ xs/src/libslic3r/GCodeTimeEstimator.hpp | 204 +++++++++ 4 files changed, 876 insertions(+), 2 deletions(-) diff --git a/cmake/modules/FindPerlEmbed.cmake b/cmake/modules/FindPerlEmbed.cmake index b12fc40634..7dc1e2b52d 100644 --- a/cmake/modules/FindPerlEmbed.cmake +++ b/cmake/modules/FindPerlEmbed.cmake @@ -60,7 +60,6 @@ include(${PerlEmbed_TEMP_INCLUDE}) file(REMOVE ${PerlEmbed_TEMP_INCLUDE}) unset(PerlEmbed_TEMP_INCLUDE) -if (PerlEmbed_DEBUG) # First show the configuration extracted by FindPerl & FindPerlLibs: message(STATUS " PERL_INCLUDE_PATH = ${PERL_INCLUDE_PATH}") message(STATUS " PERL_LIBRARY = ${PERL_LIBRARY}") @@ -79,7 +78,6 @@ if (PerlEmbed_DEBUG) message(STATUS " LD = ${PerlEmbed_LD}") message(STATUS " PerlEmbed_LDFLAGS = ${PerlEmbed_LDFLAGS}") message(STATUS " PerlEmbed_LDDLFLAGS = ${PerlEmbed_LDDLFLAGS}") -endif() include(FindPackageHandleStandardArgs) diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 48bf288822..fad1e8ee20 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -5,6 +5,13 @@ #include "GCode/PrintExtents.hpp" #include "GCode/WipeTowerPrusaMM.hpp" +//############################################################################################################ +#include "GCodeTimeEstimator.hpp" +#ifdef WIN32 +#include "enrico/wintimer.h" +#endif // WIN32 +//############################################################################################################ + #include #include #include @@ -374,6 +381,87 @@ bool GCode::do_export(Print *print, const char *path) if (! result) boost::nowide::remove(path_tmp.c_str()); + +//############################################################################################################ +#ifdef WIN32 + WinTimer timer; + timer.Start(); +#endif // WIN32 + + My_GCodeTimeEstimator timeEstimator; + timeEstimator.parse_file(path); +#ifdef WIN32 + double timeParse = timer.GetElapsedTimeSec(); +#endif // WIN32 + timeEstimator.calculate_time(); +#ifdef WIN32 + double timeCalculate = timer.GetElapsedTimeSec(); +#endif // WIN32 + std::cout << std::endl << ">>> estimated time: " << timeEstimator.get_time() << " seconds." << std::endl << std::endl; + +#ifdef WIN32 + std::cout << std::endl << "parse_file() -> Time: " << timeParse << std::endl << std::endl; + std::cout << std::endl << "calculate_file() -> Time: " << timeCalculate - timeParse << std::endl << std::endl; +#endif // WIN32 + +/* + unsigned int i = 0; + const My_GCodeTimeEstimator::BlocksList& blocks = timeEstimator.get_blocks(); + float maxXYZ[3] = { 0.0f, 0.0f, 0.0f }; + unsigned int maxID[3] = { 0, 0, 0 }; + for (const My_GCodeTimeEstimator::Block& block : blocks) + { + ++i; + std::cout << std::endl << "Block: " + << i + << " (" + << block.delta_pos[My_GCodeTimeEstimator::X] + << ", " + << block.delta_pos[My_GCodeTimeEstimator::Y] + << ", " + << block.delta_pos[My_GCodeTimeEstimator::Z] + << ") - f: " + << block.feedrate + << " - a: " + << block.acceleration + << " - s: (" + << block.entry_feedrate + << ", " + << block.exit_feedrate + << ")" + << std::endl; + + float dx = ::abs(block.delta_pos[My_GCodeTimeEstimator::X]); + float dy = ::abs(block.delta_pos[My_GCodeTimeEstimator::Y]); + float dz = ::abs(block.delta_pos[My_GCodeTimeEstimator::Z]); + + if (maxXYZ[My_GCodeTimeEstimator::X] < dx) + { + maxXYZ[My_GCodeTimeEstimator::X] = dx; + maxID[My_GCodeTimeEstimator::X] = i; + } + + if (maxXYZ[My_GCodeTimeEstimator::Y] < dy) + { + maxXYZ[My_GCodeTimeEstimator::Y] = dy; + maxID[My_GCodeTimeEstimator::Y] = i; + } + + if (maxXYZ[My_GCodeTimeEstimator::Z] < dz) + { + maxXYZ[My_GCodeTimeEstimator::Z] = dz; + maxID[My_GCodeTimeEstimator::Z] = i; + } + } + + std::cout << std::endl << "MAX DX: " << maxID[My_GCodeTimeEstimator::X] << " - " << maxXYZ[My_GCodeTimeEstimator::X] << std::endl; + std::cout << std::endl << "MAX DY: " << maxID[My_GCodeTimeEstimator::Y] << " - " << maxXYZ[My_GCodeTimeEstimator::Y] << std::endl; + std::cout << std::endl << "MAX DZ: " << maxID[My_GCodeTimeEstimator::Z] << " - " << maxXYZ[My_GCodeTimeEstimator::Z] << std::endl; + + timeEstimator.print_counters(); +*/ +//############################################################################################################ + return result; } diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index c6fa353b40..b75745757d 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -2,8 +2,592 @@ #include #include +//########################################################################################################### +#include +static const std::string AXIS_STR = "XYZE"; +static const float MMMIN_TO_MMSEC = 1.0f / 60.0f; +static const float MILLISEC_TO_SEC = 0.001f; +static const float INCHES_TO_MM = 25.4f; +static const float DEFAULT_FEEDRATE = 0.0f; // <<<<<<<<< FIND A PROPER VALUE +static const float DEFAULT_ACCELERATION = 3000.0f; +static const float DEFAULT_AXIS_MAX_FEEDRATE[] = { 600.0f, 600.0f, 40.0f, 25.0f }; +static const float DEFAULT_AXIS_MAX_ACCELERATION[] = { 9000.0f, 9000.0f, 100.0f, 10000.0f }; + +static const float DEFAULT_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.2f, 2.5f }; // from firmware +// static const float DEFAULT_AXIS_MAX_JERK[] = { 20.0f, 20.0f, 0.4f, 5.0f }; / from CURA + +static const float MINIMUM_FEEDRATE = 0.01f; +static const float MINIMUM_PLANNER_SPEED = 0.05f; // <<<<<<<< WHAT IS THIS ??? +static const float FEEDRATE_THRESHOLD = 0.0001f; +//########################################################################################################### + namespace Slic3r { +//########################################################################################################### + float My_GCodeTimeEstimator::Block::move_length() const + { + float length = ::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z])); + return (length > 0.0f) ? length : ::abs(delta_pos[E]); + } + + void My_GCodeTimeEstimator::Block::calculate_trapezoid() + { + float accelerate_distance = estimate_acceleration_distance(entry_feedrate, feedrate, acceleration); + float decelerate_distance = estimate_acceleration_distance(feedrate, exit_feedrate, -acceleration); + + float distance = move_length(); + + float plateau_distance = distance - accelerate_distance - decelerate_distance; + + // Not enough space to reach the nominal feedrate. + // This means no cruising, and we'll have to use intersection_distance() to calculate when to abort acceleration + // and start braking in order to reach the exit_feedrate exactly at the end of this block. + if (plateau_distance < 0.0f) + { + accelerate_distance = clamp(0.0f, distance, intersection_distance(entry_feedrate, exit_feedrate, acceleration, distance)); + plateau_distance = 0.0f; + } + + trapezoid.distance = distance; + trapezoid.accelerate_until = accelerate_distance; + trapezoid.decelerate_after = accelerate_distance + plateau_distance; + trapezoid.entry_feedrate = entry_feedrate; + trapezoid.exit_feedrate = exit_feedrate; + } + + float My_GCodeTimeEstimator::Block::max_allowable_speed(float acceleration, float target_velocity, float distance) + { + return ::sqrt(sqr(target_velocity) - 2.0f * acceleration * distance); + } + + float My_GCodeTimeEstimator::Block::estimate_acceleration_distance(float initial_rate, float target_rate, float acceleration) + { + return (acceleration == 0.0f) ? 0.0f : (sqr(target_rate) - sqr(initial_rate)) / (2.0f * acceleration); + } + + float My_GCodeTimeEstimator::Block::intersection_distance(float initial_rate, float final_rate, float acceleration, float distance) + { + return (acceleration == 0.0f) ? 0.0f : (2.0f * acceleration * distance - sqr(initial_rate) + sqr(final_rate)) / (4.0f * acceleration); + } + + float My_GCodeTimeEstimator::Block::acceleration_time_from_distance(float initial_feedrate, float distance, float acceleration) + { + float discriminant = sqr(initial_feedrate) + 2.0f * acceleration * distance; + + // If discriminant is negative, we're moving in the wrong direction. + // Making the discriminant 0 then gives the extremum of the parabola instead of the intersection. + discriminant = std::max(0.0f, discriminant); + return (-initial_feedrate + ::sqrt(discriminant)) / acceleration; + } + + My_GCodeTimeEstimator::My_GCodeTimeEstimator() + { + } + + void My_GCodeTimeEstimator::parse(const std::string& gcode) + { + _reset(); + GCodeReader::parse(gcode, boost::bind(&My_GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); + } + + void My_GCodeTimeEstimator::parse_file(const std::string& file) + { + _reset(); + GCodeReader::parse_file(file, boost::bind(&My_GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); + } + + void My_GCodeTimeEstimator::calculate_time() + { + _time = get_additional_time(); + + for (const Block& block : _blocks) + { + const Block::Trapezoid& trapezoid = block.trapezoid; + float plateau_distance = trapezoid.decelerate_after - trapezoid.accelerate_until; + + _time += Block::acceleration_time_from_distance(block.entry_feedrate, trapezoid.accelerate_until, block.acceleration); + _time += plateau_distance / block.feedrate; + _time += Block::acceleration_time_from_distance(block.exit_feedrate, (trapezoid.distance - trapezoid.decelerate_after), block.acceleration); + } + } + + void My_GCodeTimeEstimator::set_axis_position(EAxis axis, float position) + { + _state.axis[axis].position = position; + } + + void My_GCodeTimeEstimator::set_axis_max_feedrate(EAxis axis, float feedrate_mm_sec) + { + _state.axis[axis].max_feedrate = feedrate_mm_sec; + } + + void My_GCodeTimeEstimator::set_axis_max_acceleration(EAxis axis, float acceleration) + { + _state.axis[axis].max_acceleration = acceleration; + } + + void My_GCodeTimeEstimator::set_axis_max_jerk(EAxis axis, float jerk) + { + _state.axis[axis].max_jerk = jerk; + } + + float My_GCodeTimeEstimator::get_axis_position(EAxis axis) const + { + return _state.axis[axis].position; + } + + float My_GCodeTimeEstimator::get_axis_max_feedrate(EAxis axis) const + { + return _state.axis[axis].max_feedrate; + } + + float My_GCodeTimeEstimator::get_axis_max_acceleration(EAxis axis) const + { + return _state.axis[axis].max_acceleration; + } + + float My_GCodeTimeEstimator::get_axis_max_jerk(EAxis axis) const + { + return _state.axis[axis].max_jerk; + } + + void My_GCodeTimeEstimator::set_feedrate(float feedrate_mm_sec) + { + _state.feedrate = std::max(feedrate_mm_sec, MINIMUM_FEEDRATE); + } + + float My_GCodeTimeEstimator::get_feedrate() const + { + return _state.feedrate; + } + + void My_GCodeTimeEstimator::set_acceleration(float acceleration) + { + _state.acceleration = acceleration; + } + + float My_GCodeTimeEstimator::get_acceleration() const + { + return _state.acceleration; + } + + void My_GCodeTimeEstimator::set_dialect(My_GCodeTimeEstimator::EDialect dialect) + { + _state.dialect = dialect; + } + + My_GCodeTimeEstimator::EDialect My_GCodeTimeEstimator::get_dialect() const + { + return _state.dialect; + } + + void My_GCodeTimeEstimator::set_units(My_GCodeTimeEstimator::EUnits units) + { + _state.units = units; + } + + My_GCodeTimeEstimator::EUnits My_GCodeTimeEstimator::get_units() const + { + return _state.units; + } + + void My_GCodeTimeEstimator::set_positioningType(My_GCodeTimeEstimator::EPositioningType type) + { + _state.positioningType = type; + } + + My_GCodeTimeEstimator::EPositioningType My_GCodeTimeEstimator::get_positioningType() const + { + return _state.positioningType; + } + + void My_GCodeTimeEstimator::add_additional_time(float timeSec) + { + _state.additional_time += timeSec; + } + + float My_GCodeTimeEstimator::get_additional_time() const + { + return _state.additional_time; + } + + void My_GCodeTimeEstimator::set_default() + { + set_units(Millimeters); + set_dialect(Unknown); + set_positioningType(Absolute); + + set_feedrate(DEFAULT_FEEDRATE); + set_acceleration(DEFAULT_ACCELERATION); + + for (unsigned char a = X; a < Num_Axis; ++a) + { + EAxis axis = (EAxis)a; + set_axis_max_feedrate(axis, DEFAULT_AXIS_MAX_FEEDRATE[a]); + set_axis_max_acceleration(axis, DEFAULT_AXIS_MAX_ACCELERATION[a]); + set_axis_max_jerk(axis, DEFAULT_AXIS_MAX_JERK[a]); + } + } + + float My_GCodeTimeEstimator::get_time() const + { + return _time; + } + + const My_GCodeTimeEstimator::BlocksList& My_GCodeTimeEstimator::get_blocks() const + { + return _blocks; + } + +// void My_GCodeTimeEstimator::print_counters() const +// { +// std::cout << std::endl; +// for (const CmdToCounterMap::value_type& counter : _cmdCounters) +// { +// std::cout << counter.first << " : " << counter.second << std::endl; +// } +// } + + void My_GCodeTimeEstimator::_reset() + { +// _cmdCounters.clear(); + + _blocks.clear(); + + set_default(); + set_axis_position(X, 0.0f); + set_axis_position(Y, 0.0f); + set_axis_position(Z, 0.0f); + + _state.additional_time = 0.0f; + } + + void My_GCodeTimeEstimator::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line) + { + if (line.cmd.length() > 1) + { + switch (line.cmd[0]) + { + case 'G': + { + switch (::atoi(&line.cmd[1])) + { + case 1: // Move + { + _processG1(line); + break; + } + case 4: // Dwell + { + _processG4(line); + break; + } + case 20: // Set Units to Inches + { + _processG20(line); + break; + } + case 21: // Set Units to Millimeters + { + _processG21(line); + break; + } + case 28: // Move to Origin (Home) + { + _processG28(line); + break; + } + case 90: // Set to Absolute Positioning + { + _processG90(line); + break; + } + case 91: // Set to Relative Positioning + { + _processG91(line); + break; + } + case 92: // Set Position + { + _processG92(line); + break; + } + } + + break; + } + case 'M': + { + switch (::atoi(&line.cmd[1])) + { + case 109: // Set Extruder Temperature and Wait + { + _processM109(line); + break; + } + case 203: // Set maximum feedrate + { + _processM203(line); + break; + } + case 204: // Set default acceleration + { + _processM204(line); + break; + } + case 566: // Set allowable instantaneous speed change + { + _processM566(line); + break; + } + } + + break; + } + } + +// CmdToCounterMap::iterator it = _cmdCounters.find(line.cmd); +// if (it == _cmdCounters.end()) +// _cmdCounters.insert(CmdToCounterMap::value_type(line.cmd, 1)); +// else +// ++it->second; + } + } + + void My_GCodeTimeEstimator::_processG1(const GCodeReader::GCodeLine& line) + { + float lengthsScaleFactor = (get_units() == Inches) ? INCHES_TO_MM : 1.0f; + + // gets position changes from line, if present + float new_pos[Num_Axis]; + + if (get_positioningType() == Absolute) + { + for (unsigned char a = X; a < Num_Axis; ++a) + { + new_pos[a] = line.has(AXIS_STR[a]) ? line.get_float(AXIS_STR[a]) * lengthsScaleFactor : get_axis_position((EAxis)a); + } + } + else // get_positioningType() == Relative + { + for (unsigned char a = X; a < Num_Axis; ++a) + { + new_pos[a] = get_axis_position((EAxis)a); + new_pos[a] += (line.has(AXIS_STR[a]) ? line.get_float(AXIS_STR[a]) * lengthsScaleFactor : 0.0f); + } + } + + // updates feedrate from line, if present + if (line.has('F')) + set_feedrate(line.get_float('F') * MMMIN_TO_MMSEC); + + // fills block data + Block block; + + // calculates block movement deltas + float max_abs_delta = 0.0f; + for (unsigned char a = X; a < Num_Axis; ++a) + { + block.delta_pos[a] = new_pos[a] - get_axis_position((EAxis)a); + max_abs_delta = std::max(max_abs_delta, ::abs(block.delta_pos[a])); + } + + // is it a move ? + if (max_abs_delta == 0.0f) + return; + + // calculates block feedrate + float feedrate = get_feedrate(); + + float distance = block.move_length(); + float invDistance = 1.0f / distance; + + float axis_feedrate[Num_Axis]; + float min_feedrate_factor = 1.0f; + for (unsigned char a = X; a < Num_Axis; ++a) + { + axis_feedrate[a] = feedrate * ::abs(block.delta_pos[a]) * invDistance; + if (axis_feedrate[a] > 0.0f) + min_feedrate_factor = std::min(min_feedrate_factor, get_axis_max_feedrate((EAxis)a) / axis_feedrate[a]); + } + + block.feedrate = min_feedrate_factor * feedrate; + for (unsigned char a = X; a < Num_Axis; ++a) + { + axis_feedrate[a] *= min_feedrate_factor; + } + + // calculates block acceleration + float acceleration = get_acceleration(); + + for (unsigned char a = X; a < Num_Axis; ++a) + { + float axis_max_acceleration = get_axis_max_acceleration((EAxis)a); + if (acceleration * ::abs(block.delta_pos[a]) * invDistance > axis_max_acceleration) + acceleration = axis_max_acceleration; + } + + block.acceleration = acceleration; + + // calculates block exit feedrate + float exit_feedrate = block.feedrate; + + for (unsigned char a = X; a < Num_Axis; ++a) + { + float half_axis_max_jerk = 0.5f * get_axis_max_jerk((EAxis)a); + if (axis_feedrate[a] > half_axis_max_jerk) + exit_feedrate = std::min(exit_feedrate, half_axis_max_jerk); + } + + block.exit_feedrate = exit_feedrate; + + // calculates block entry feedrate + float vmax_junction = exit_feedrate; + if (!_blocks.empty() && (_prev.feedrate > FEEDRATE_THRESHOLD)) + { + vmax_junction = block.feedrate; + float vmax_junction_factor = 1.0f; + + for (unsigned char a = X; a < Num_Axis; ++a) + { + float abs_delta_axis_feedrate = ::abs(axis_feedrate[a] - _prev.axis_feedrate[a]); + float axis_max_jerk = get_axis_max_jerk((EAxis)a); + if (abs_delta_axis_feedrate > axis_max_jerk) + vmax_junction_factor = std::min(vmax_junction_factor, axis_max_jerk / abs_delta_axis_feedrate); + } + + // limit vmax to not exceed previous feedrate + vmax_junction = std::min(_prev.feedrate, vmax_junction * vmax_junction_factor); + } + + block.entry_feedrate = std::min(vmax_junction, Block::max_allowable_speed(-acceleration, MINIMUM_PLANNER_SPEED, distance)); + + // calculates block trapezoid + block.calculate_trapezoid(); + + // updates previous cache + _prev.feedrate = feedrate; + for (unsigned char a = X; a < Num_Axis; ++a) + { + _prev.axis_feedrate[a] = axis_feedrate[a]; + } + + // updates axis positions + for (unsigned char a = X; a < Num_Axis; ++a) + { + set_axis_position((EAxis)a, new_pos[a]); + } + + // adds block to blocks list + _blocks.push_back(block); + } + + void My_GCodeTimeEstimator::_processG4(const GCodeReader::GCodeLine& line) + { + EDialect dialect = get_dialect(); + + if (line.has('P')) + add_additional_time(line.get_float('P') * MILLISEC_TO_SEC); + + // see: http://reprap.org/wiki/G-code#G4:_Dwell + if ((dialect == Repetier) || + (dialect == Marlin) || + (dialect == Smoothieware) || + (dialect == RepRapFirmware)) + { + if (line.has('S')) + add_additional_time(line.get_float('S')); + } + } + + void My_GCodeTimeEstimator::_processG20(const GCodeReader::GCodeLine& line) + { + set_units(Inches); + } + + void My_GCodeTimeEstimator::_processG21(const GCodeReader::GCodeLine& line) + { + set_units(Millimeters); + } + + void My_GCodeTimeEstimator::_processG28(const GCodeReader::GCodeLine& line) + { + // todo + } + + void My_GCodeTimeEstimator::_processG90(const GCodeReader::GCodeLine& line) + { + set_positioningType(Absolute); + } + + void My_GCodeTimeEstimator::_processG91(const GCodeReader::GCodeLine& line) + { + // >>>>>>>> THERE ARE DIALECT VARIANTS + + set_positioningType(Relative); + } + + void My_GCodeTimeEstimator::_processG92(const GCodeReader::GCodeLine& line) + { + // todo + } + + void My_GCodeTimeEstimator::_processM109(const GCodeReader::GCodeLine& line) + { + // todo + } + + void My_GCodeTimeEstimator::_processM203(const GCodeReader::GCodeLine& line) + { + EDialect dialect = get_dialect(); + + // see http://reprap.org/wiki/G-code#M203:_Set_maximum_feedrate + if (dialect == Repetier) + return; + + // see http://reprap.org/wiki/G-code#M203:_Set_maximum_feedrate + float factor = (dialect == Marlin) ? 1.0f : MMMIN_TO_MMSEC; + + if (line.has('X')) + set_axis_max_feedrate(X, line.get_float('X') * factor); + + if (line.has('Y')) + set_axis_max_feedrate(Y, line.get_float('Y') * factor); + + if (line.has('Z')) + set_axis_max_feedrate(Z, line.get_float('Z') * factor); + + if (line.has('E')) + set_axis_max_feedrate(E, line.get_float('E') * factor); + } + + void My_GCodeTimeEstimator::_processM204(const GCodeReader::GCodeLine& line) + { + if (line.has('S')) + set_acceleration(line.get_float('S')); // <<<< Is this correct ? + + if (line.has('T')) + { + // what to do ? + } + } + + void My_GCodeTimeEstimator::_processM566(const GCodeReader::GCodeLine& line) + { + if (line.has('X')) + set_axis_max_jerk(X, line.get_float('X') * MMMIN_TO_MMSEC); + + if (line.has('Y')) + set_axis_max_jerk(Y, line.get_float('Y') * MMMIN_TO_MMSEC); + + if (line.has('Z')) + set_axis_max_jerk(Z, line.get_float('Z') * MMMIN_TO_MMSEC); + + if (line.has('E')) + set_axis_max_jerk(E, line.get_float('E') * MMMIN_TO_MMSEC); + } +//########################################################################################################### + void GCodeTimeEstimator::parse(const std::string &gcode) { diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index dd301c929f..6e3de493f7 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -6,6 +6,210 @@ namespace Slic3r { +//########################################################################################################### + class My_GCodeTimeEstimator : public GCodeReader + { + public: + enum EUnits : unsigned char + { + Millimeters, + Inches + }; + + enum EAxis : unsigned char + { + X, + Y, + Z, + E, + Num_Axis + }; + + enum EDialect : unsigned char + { + Unknown, + Marlin, + Repetier, + Smoothieware, + RepRapFirmware, + Teacup, + Num_Dialects + }; + + enum EPositioningType + { + Absolute, + Relative + }; + + private: + struct Axis + { + float position; // mm + float max_feedrate; // mm/s + float max_acceleration; // mm/s^2 + float max_jerk; // mm/s + }; + + struct State + { + EDialect dialect; + EUnits units; + EPositioningType positioningType; + Axis axis[Num_Axis]; + float feedrate; // mm/s + float acceleration; // mm/s^2 + float additional_time; // s + }; + + struct PreviousBlockCache + { + float feedrate; // mm/s + float axis_feedrate[Num_Axis]; // mm/s + }; + + public: + struct Block + { + struct Trapezoid + { + float distance; // mm + float accelerate_until; // mm + float decelerate_after; // mm + float entry_feedrate; // mm/s + float exit_feedrate; // mm/s + }; + + float delta_pos[Num_Axis]; // mm + float feedrate; // mm/s + float acceleration; // mm/s^2 + float entry_feedrate; // mm/s + float exit_feedrate; // mm/s + + Trapezoid trapezoid; + + // Returns the length of the move covered by this block, in mm + float move_length() const; + + void calculate_trapezoid(); + + // Calculates the maximum allowable speed at this point when you must be able to reach target_velocity using the + // acceleration within the allotted distance. + static float max_allowable_speed(float acceleration, float target_velocity, float distance); + + // Calculates the distance (not time) it takes to accelerate from initial_rate to target_rate using the given acceleration: + static float estimate_acceleration_distance(float initial_rate, float target_rate, float acceleration); + + // This function gives you the point at which you must start braking (at the rate of -acceleration) if + // you started at speed initial_rate and accelerated until this point and want to end at the final_rate after + // a total travel of distance. This can be used to compute the intersection point between acceleration and + // deceleration in the cases where the trapezoid has no plateau (i.e. never reaches maximum speed) + static float intersection_distance(float initial_rate, float final_rate, float acceleration, float distance); + + // This function gives the time it needs to accelerate from an initial speed to reach a final distance. + static float acceleration_time_from_distance(float initial_feedrate, float distance, float acceleration); + }; + + typedef std::vector BlocksList; + + private: +// typedef std::map CmdToCounterMap; +// CmdToCounterMap _cmdCounters; + + State _state; + PreviousBlockCache _prev; + BlocksList _blocks; + float _time; // s + + public: + My_GCodeTimeEstimator(); + + void parse(const std::string& gcode); + void parse_file(const std::string& file); + + void calculate_time(); + + void set_axis_position(EAxis axis, float position); + void set_axis_max_feedrate(EAxis axis, float feedrate_mm_sec); + void set_axis_max_acceleration(EAxis axis, float acceleration); + void set_axis_max_jerk(EAxis axis, float jerk); + + float get_axis_position(EAxis axis) const; + float get_axis_max_feedrate(EAxis axis) const; + float get_axis_max_acceleration(EAxis axis) const; + float get_axis_max_jerk(EAxis axis) const; + + void set_feedrate(float feedrate_mm_sec); + float get_feedrate() const; + + void set_acceleration(float acceleration); + float get_acceleration() const; + + void set_dialect(EDialect dialect); + EDialect get_dialect() const; + + void set_units(EUnits units); + EUnits get_units() const; + + void set_positioningType(EPositioningType type); + EPositioningType get_positioningType() const; + + void add_additional_time(float timeSec); + float get_additional_time() const; + + void set_default(); + + // returns estimated time in seconds + float get_time() const; + + const BlocksList& get_blocks() const; + +// void print_counters() const; + + private: + void _reset(); + + // Processes GCode line + void _process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line); + + // Move + void _processG1(const GCodeReader::GCodeLine& line); + + // Dwell + void _processG4(const GCodeReader::GCodeLine& line); + + // Set Units to Inches + void _processG20(const GCodeReader::GCodeLine& line); + + // Set Units to Millimeters + void _processG21(const GCodeReader::GCodeLine& line); + + // Move to Origin (Home) + void _processG28(const GCodeReader::GCodeLine& line); + + // Set to Absolute Positioning + void _processG90(const GCodeReader::GCodeLine& line); + + // Set to Relative Positioning + void _processG91(const GCodeReader::GCodeLine& line); + + // Set Position + void _processG92(const GCodeReader::GCodeLine& line); + + // Set Extruder Temperature and Wait + void _processM109(const GCodeReader::GCodeLine& line); + + // Set maximum feedrate + void _processM203(const GCodeReader::GCodeLine& line); + + // Set default acceleration + void _processM204(const GCodeReader::GCodeLine& line); + + // Set allowable instantaneous speed change + void _processM566(const GCodeReader::GCodeLine& line); + }; +//########################################################################################################### + class GCodeTimeEstimator : public GCodeReader { public: float time = 0; // in seconds From 092d271fa2a01f94a54620fc688ca8fea6ea3af3 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 8 Dec 2017 10:50:36 +0100 Subject: [PATCH 02/33] time estimator wip stage 2 --- xs/src/libslic3r/GCode.cpp | 84 +--- xs/src/libslic3r/GCodeTimeEstimator.cpp | 618 ++++++++++++++++-------- xs/src/libslic3r/GCodeTimeEstimator.hpp | 139 ++++-- 3 files changed, 516 insertions(+), 325 deletions(-) diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index fad1e8ee20..8d8bf3e3ec 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -7,9 +7,6 @@ //############################################################################################################ #include "GCodeTimeEstimator.hpp" -#ifdef WIN32 -#include "enrico/wintimer.h" -#endif // WIN32 //############################################################################################################ #include @@ -383,83 +380,12 @@ bool GCode::do_export(Print *print, const char *path) boost::nowide::remove(path_tmp.c_str()); //############################################################################################################ -#ifdef WIN32 - WinTimer timer; - timer.Start(); -#endif // WIN32 + GCodeTimeEstimator timeEstimator; + timeEstimator.calculate_time_from_file(path); + float time = timeEstimator.get_time(); + std::string timeHMS = timeEstimator.get_time_hms(); - My_GCodeTimeEstimator timeEstimator; - timeEstimator.parse_file(path); -#ifdef WIN32 - double timeParse = timer.GetElapsedTimeSec(); -#endif // WIN32 - timeEstimator.calculate_time(); -#ifdef WIN32 - double timeCalculate = timer.GetElapsedTimeSec(); -#endif // WIN32 - std::cout << std::endl << ">>> estimated time: " << timeEstimator.get_time() << " seconds." << std::endl << std::endl; - -#ifdef WIN32 - std::cout << std::endl << "parse_file() -> Time: " << timeParse << std::endl << std::endl; - std::cout << std::endl << "calculate_file() -> Time: " << timeCalculate - timeParse << std::endl << std::endl; -#endif // WIN32 - -/* - unsigned int i = 0; - const My_GCodeTimeEstimator::BlocksList& blocks = timeEstimator.get_blocks(); - float maxXYZ[3] = { 0.0f, 0.0f, 0.0f }; - unsigned int maxID[3] = { 0, 0, 0 }; - for (const My_GCodeTimeEstimator::Block& block : blocks) - { - ++i; - std::cout << std::endl << "Block: " - << i - << " (" - << block.delta_pos[My_GCodeTimeEstimator::X] - << ", " - << block.delta_pos[My_GCodeTimeEstimator::Y] - << ", " - << block.delta_pos[My_GCodeTimeEstimator::Z] - << ") - f: " - << block.feedrate - << " - a: " - << block.acceleration - << " - s: (" - << block.entry_feedrate - << ", " - << block.exit_feedrate - << ")" - << std::endl; - - float dx = ::abs(block.delta_pos[My_GCodeTimeEstimator::X]); - float dy = ::abs(block.delta_pos[My_GCodeTimeEstimator::Y]); - float dz = ::abs(block.delta_pos[My_GCodeTimeEstimator::Z]); - - if (maxXYZ[My_GCodeTimeEstimator::X] < dx) - { - maxXYZ[My_GCodeTimeEstimator::X] = dx; - maxID[My_GCodeTimeEstimator::X] = i; - } - - if (maxXYZ[My_GCodeTimeEstimator::Y] < dy) - { - maxXYZ[My_GCodeTimeEstimator::Y] = dy; - maxID[My_GCodeTimeEstimator::Y] = i; - } - - if (maxXYZ[My_GCodeTimeEstimator::Z] < dz) - { - maxXYZ[My_GCodeTimeEstimator::Z] = dz; - maxID[My_GCodeTimeEstimator::Z] = i; - } - } - - std::cout << std::endl << "MAX DX: " << maxID[My_GCodeTimeEstimator::X] << " - " << maxXYZ[My_GCodeTimeEstimator::X] << std::endl; - std::cout << std::endl << "MAX DY: " << maxID[My_GCodeTimeEstimator::Y] << " - " << maxXYZ[My_GCodeTimeEstimator::Y] << std::endl; - std::cout << std::endl << "MAX DZ: " << maxID[My_GCodeTimeEstimator::Z] << " - " << maxXYZ[My_GCodeTimeEstimator::Z] << std::endl; - - timeEstimator.print_counters(); -*/ + std::cout << std::endl << ">>> estimated time: " << timeHMS << " (" << time << " seconds)" << std::endl << std::endl; //############################################################################################################ return result; diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index b75745757d..d612980bad 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -2,8 +2,6 @@ #include #include -//########################################################################################################### -#include static const std::string AXIS_STR = "XYZE"; static const float MMMIN_TO_MMSEC = 1.0f / 60.0f; static const float MILLISEC_TO_SEC = 0.001f; @@ -13,205 +11,258 @@ static const float DEFAULT_ACCELERATION = 3000.0f; static const float DEFAULT_AXIS_MAX_FEEDRATE[] = { 600.0f, 600.0f, 40.0f, 25.0f }; static const float DEFAULT_AXIS_MAX_ACCELERATION[] = { 9000.0f, 9000.0f, 100.0f, 10000.0f }; -static const float DEFAULT_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.2f, 2.5f }; // from firmware -// static const float DEFAULT_AXIS_MAX_JERK[] = { 20.0f, 20.0f, 0.4f, 5.0f }; / from CURA +static const float DEFAULT_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.2f, 2.5f }; // from Firmware +//static const float DEFAULT_AXIS_MAX_JERK[] = { 20.0f, 20.0f, 0.4f, 5.0f }; // from Cura -static const float MINIMUM_FEEDRATE = 0.01f; -static const float MINIMUM_PLANNER_SPEED = 0.05f; // <<<<<<<< WHAT IS THIS ??? -static const float FEEDRATE_THRESHOLD = 0.0001f; -//########################################################################################################### +static const float DEFAULT_MINIMUM_FEEDRATE = 0.0f; // from Firmware +//static const float DEFAULT_MINIMUM_FEEDRATE = 0.01f; // from Cura + +#if USE_CURA_JUNCTION_VMAX +static const float MINIMUM_PLANNER_SPEED = 0.05f; // from Cura <<<<<<<< WHAT IS THIS ??? +#endif // USE_CURA_JUNCTION_VMAX + +static const float PREVIOUS_FEEDRATE_THRESHOLD = 0.0001f; namespace Slic3r { -//########################################################################################################### - float My_GCodeTimeEstimator::Block::move_length() const + void GCodeTimeEstimator::Feedrates::reset() + { + feedrate = 0.0f; + safe_feedrate = 0.0f; + ::memset(axis_feedrate, 0, Num_Axis * sizeof(float)); + ::memset(abs_axis_feedrate, 0, Num_Axis * sizeof(float)); + } + + float GCodeTimeEstimator::Block::Trapezoid::acceleration_time(float acceleration) const + { + return acceleration_time_from_distance(feedrate.entry, accelerate_until, acceleration); + } + + float GCodeTimeEstimator::Block::Trapezoid::cruise_time() const + { + return (feedrate.cruise != 0.0f) ? cruise_distance() / feedrate.cruise : 0.0f; + } + + float GCodeTimeEstimator::Block::Trapezoid::deceleration_time(float acceleration) const + { + return acceleration_time_from_distance(feedrate.cruise, (distance - decelerate_after), -acceleration); + } + + float GCodeTimeEstimator::Block::Trapezoid::cruise_distance() const + { + return decelerate_after - accelerate_until; + } + + float GCodeTimeEstimator::Block::Trapezoid::acceleration_time_from_distance(float initial_feedrate, float distance, float acceleration) + { + return (acceleration != 0.0f) ? (speed_from_distance(initial_feedrate, distance, acceleration) - initial_feedrate) / acceleration : 0.0f; + } + + float GCodeTimeEstimator::Block::Trapezoid::speed_from_distance(float initial_feedrate, float distance, float acceleration) + { + return ::sqrt(sqr(initial_feedrate) + 2.0f * acceleration * distance); + } + + float GCodeTimeEstimator::Block::move_length() const { float length = ::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z])); return (length > 0.0f) ? length : ::abs(delta_pos[E]); } - void My_GCodeTimeEstimator::Block::calculate_trapezoid() + float GCodeTimeEstimator::Block::acceleration_time() const { - float accelerate_distance = estimate_acceleration_distance(entry_feedrate, feedrate, acceleration); - float decelerate_distance = estimate_acceleration_distance(feedrate, exit_feedrate, -acceleration); + return trapezoid.acceleration_time(acceleration); + } + float GCodeTimeEstimator::Block::cruise_time() const + { + return trapezoid.cruise_time(); + } + + float GCodeTimeEstimator::Block::deceleration_time() const + { + return trapezoid.deceleration_time(acceleration); + } + + float GCodeTimeEstimator::Block::cruise_distance() const + { + return trapezoid.cruise_distance(); + } + + void GCodeTimeEstimator::Block::calculate_trapezoid() + { float distance = move_length(); - float plateau_distance = distance - accelerate_distance - decelerate_distance; + trapezoid.distance = distance; + trapezoid.feedrate = feedrate; + + float accelerate_distance = estimate_acceleration_distance(feedrate.entry, feedrate.cruise, acceleration); + float decelerate_distance = estimate_acceleration_distance(feedrate.cruise, feedrate.exit, -acceleration); + float cruise_distance = distance - accelerate_distance - decelerate_distance; // Not enough space to reach the nominal feedrate. // This means no cruising, and we'll have to use intersection_distance() to calculate when to abort acceleration // and start braking in order to reach the exit_feedrate exactly at the end of this block. - if (plateau_distance < 0.0f) + if (cruise_distance < 0.0f) { - accelerate_distance = clamp(0.0f, distance, intersection_distance(entry_feedrate, exit_feedrate, acceleration, distance)); - plateau_distance = 0.0f; + accelerate_distance = clamp(0.0f, distance, intersection_distance(feedrate.entry, feedrate.exit, acceleration, distance)); + cruise_distance = 0.0f; + trapezoid.feedrate.cruise = Trapezoid::speed_from_distance(feedrate.entry, accelerate_distance, acceleration); } - trapezoid.distance = distance; trapezoid.accelerate_until = accelerate_distance; - trapezoid.decelerate_after = accelerate_distance + plateau_distance; - trapezoid.entry_feedrate = entry_feedrate; - trapezoid.exit_feedrate = exit_feedrate; + trapezoid.decelerate_after = accelerate_distance + cruise_distance; } - float My_GCodeTimeEstimator::Block::max_allowable_speed(float acceleration, float target_velocity, float distance) + float GCodeTimeEstimator::Block::max_allowable_speed(float acceleration, float target_velocity, float distance) { return ::sqrt(sqr(target_velocity) - 2.0f * acceleration * distance); } - float My_GCodeTimeEstimator::Block::estimate_acceleration_distance(float initial_rate, float target_rate, float acceleration) + float GCodeTimeEstimator::Block::estimate_acceleration_distance(float initial_rate, float target_rate, float acceleration) { return (acceleration == 0.0f) ? 0.0f : (sqr(target_rate) - sqr(initial_rate)) / (2.0f * acceleration); } - float My_GCodeTimeEstimator::Block::intersection_distance(float initial_rate, float final_rate, float acceleration, float distance) + float GCodeTimeEstimator::Block::intersection_distance(float initial_rate, float final_rate, float acceleration, float distance) { return (acceleration == 0.0f) ? 0.0f : (2.0f * acceleration * distance - sqr(initial_rate) + sqr(final_rate)) / (4.0f * acceleration); } - float My_GCodeTimeEstimator::Block::acceleration_time_from_distance(float initial_feedrate, float distance, float acceleration) - { - float discriminant = sqr(initial_feedrate) + 2.0f * acceleration * distance; - - // If discriminant is negative, we're moving in the wrong direction. - // Making the discriminant 0 then gives the extremum of the parabola instead of the intersection. - discriminant = std::max(0.0f, discriminant); - return (-initial_feedrate + ::sqrt(discriminant)) / acceleration; - } - - My_GCodeTimeEstimator::My_GCodeTimeEstimator() + GCodeTimeEstimator::GCodeTimeEstimator() { } - void My_GCodeTimeEstimator::parse(const std::string& gcode) + void GCodeTimeEstimator::calculate_time_from_text(const std::string& gcode) { _reset(); - GCodeReader::parse(gcode, boost::bind(&My_GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); + _parser.parse(gcode, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); + _calculate_time(); } - void My_GCodeTimeEstimator::parse_file(const std::string& file) + void GCodeTimeEstimator::calculate_time_from_file(const std::string& file) { _reset(); - GCodeReader::parse_file(file, boost::bind(&My_GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); + _parser.parse_file(file, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); + _calculate_time(); } - void My_GCodeTimeEstimator::calculate_time() - { - _time = get_additional_time(); - - for (const Block& block : _blocks) - { - const Block::Trapezoid& trapezoid = block.trapezoid; - float plateau_distance = trapezoid.decelerate_after - trapezoid.accelerate_until; - - _time += Block::acceleration_time_from_distance(block.entry_feedrate, trapezoid.accelerate_until, block.acceleration); - _time += plateau_distance / block.feedrate; - _time += Block::acceleration_time_from_distance(block.exit_feedrate, (trapezoid.distance - trapezoid.decelerate_after), block.acceleration); - } - } - - void My_GCodeTimeEstimator::set_axis_position(EAxis axis, float position) + void GCodeTimeEstimator::set_axis_position(EAxis axis, float position) { _state.axis[axis].position = position; } - void My_GCodeTimeEstimator::set_axis_max_feedrate(EAxis axis, float feedrate_mm_sec) + void GCodeTimeEstimator::set_axis_max_feedrate(EAxis axis, float feedrate_mm_sec) { _state.axis[axis].max_feedrate = feedrate_mm_sec; } - void My_GCodeTimeEstimator::set_axis_max_acceleration(EAxis axis, float acceleration) + void GCodeTimeEstimator::set_axis_max_acceleration(EAxis axis, float acceleration) { _state.axis[axis].max_acceleration = acceleration; } - void My_GCodeTimeEstimator::set_axis_max_jerk(EAxis axis, float jerk) + void GCodeTimeEstimator::set_axis_max_jerk(EAxis axis, float jerk) { _state.axis[axis].max_jerk = jerk; } - float My_GCodeTimeEstimator::get_axis_position(EAxis axis) const + float GCodeTimeEstimator::get_axis_position(EAxis axis) const { return _state.axis[axis].position; } - float My_GCodeTimeEstimator::get_axis_max_feedrate(EAxis axis) const + float GCodeTimeEstimator::get_axis_max_feedrate(EAxis axis) const { return _state.axis[axis].max_feedrate; } - float My_GCodeTimeEstimator::get_axis_max_acceleration(EAxis axis) const + float GCodeTimeEstimator::get_axis_max_acceleration(EAxis axis) const { return _state.axis[axis].max_acceleration; } - float My_GCodeTimeEstimator::get_axis_max_jerk(EAxis axis) const + float GCodeTimeEstimator::get_axis_max_jerk(EAxis axis) const { return _state.axis[axis].max_jerk; } - void My_GCodeTimeEstimator::set_feedrate(float feedrate_mm_sec) + void GCodeTimeEstimator::set_feedrate(float feedrate_mm_sec) { - _state.feedrate = std::max(feedrate_mm_sec, MINIMUM_FEEDRATE); + _state.feedrate = feedrate_mm_sec; } - float My_GCodeTimeEstimator::get_feedrate() const + float GCodeTimeEstimator::get_feedrate() const { return _state.feedrate; } - void My_GCodeTimeEstimator::set_acceleration(float acceleration) + void GCodeTimeEstimator::set_acceleration(float acceleration) { _state.acceleration = acceleration; } - float My_GCodeTimeEstimator::get_acceleration() const + float GCodeTimeEstimator::get_acceleration() const { return _state.acceleration; } - void My_GCodeTimeEstimator::set_dialect(My_GCodeTimeEstimator::EDialect dialect) + void GCodeTimeEstimator::set_minimum_feedrate(float feedrate_mm_sec) + { + _state.minimum_feedrate = feedrate_mm_sec; + } + + float GCodeTimeEstimator::get_minimum_feedrate() const + { + return _state.minimum_feedrate; + } + + void GCodeTimeEstimator::set_dialect(GCodeTimeEstimator::EDialect dialect) { _state.dialect = dialect; } - My_GCodeTimeEstimator::EDialect My_GCodeTimeEstimator::get_dialect() const + GCodeTimeEstimator::EDialect GCodeTimeEstimator::get_dialect() const { return _state.dialect; } - void My_GCodeTimeEstimator::set_units(My_GCodeTimeEstimator::EUnits units) + void GCodeTimeEstimator::set_units(GCodeTimeEstimator::EUnits units) { _state.units = units; } - My_GCodeTimeEstimator::EUnits My_GCodeTimeEstimator::get_units() const + GCodeTimeEstimator::EUnits GCodeTimeEstimator::get_units() const { return _state.units; } - void My_GCodeTimeEstimator::set_positioningType(My_GCodeTimeEstimator::EPositioningType type) + void GCodeTimeEstimator::set_positioningType(GCodeTimeEstimator::EPositioningType type) { _state.positioningType = type; } - My_GCodeTimeEstimator::EPositioningType My_GCodeTimeEstimator::get_positioningType() const + GCodeTimeEstimator::EPositioningType GCodeTimeEstimator::get_positioningType() const { return _state.positioningType; } - void My_GCodeTimeEstimator::add_additional_time(float timeSec) + void GCodeTimeEstimator::add_additional_time(float timeSec) { _state.additional_time += timeSec; } - float My_GCodeTimeEstimator::get_additional_time() const + void GCodeTimeEstimator::set_additional_time(float timeSec) + { + _state.additional_time = timeSec; + } + + float GCodeTimeEstimator::get_additional_time() const { return _state.additional_time; } - void My_GCodeTimeEstimator::set_default() + void GCodeTimeEstimator::set_default() { set_units(Millimeters); set_dialect(Unknown); @@ -219,6 +270,7 @@ namespace Slic3r { set_feedrate(DEFAULT_FEEDRATE); set_acceleration(DEFAULT_ACCELERATION); + set_minimum_feedrate(DEFAULT_MINIMUM_FEEDRATE); for (unsigned char a = X; a < Num_Axis; ++a) { @@ -229,40 +281,59 @@ namespace Slic3r { } } - float My_GCodeTimeEstimator::get_time() const + float GCodeTimeEstimator::get_time() const { return _time; } - const My_GCodeTimeEstimator::BlocksList& My_GCodeTimeEstimator::get_blocks() const + std::string GCodeTimeEstimator::get_time_hms() const { - return _blocks; + float timeinsecs = get_time(); + int hours = (int)(timeinsecs / 3600.0f); + timeinsecs -= (float)hours * 3600.0f; + int minutes = (int)(timeinsecs / 60.0f); + timeinsecs -= (float)minutes * 60.0f; + + char buf[16]; + ::sprintf(buf, "%02d:%02d:%02d", hours, minutes, (int)timeinsecs); + return buf; } -// void My_GCodeTimeEstimator::print_counters() const -// { -// std::cout << std::endl; -// for (const CmdToCounterMap::value_type& counter : _cmdCounters) -// { -// std::cout << counter.first << " : " << counter.second << std::endl; -// } -// } - - void My_GCodeTimeEstimator::_reset() + void GCodeTimeEstimator::_reset() { -// _cmdCounters.clear(); - _blocks.clear(); + _curr.reset(); + _prev.reset(); + set_default(); + set_axis_position(X, 0.0f); set_axis_position(Y, 0.0f); set_axis_position(Z, 0.0f); - _state.additional_time = 0.0f; + set_additional_time(0.0f); } - void My_GCodeTimeEstimator::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line) + void GCodeTimeEstimator::_calculate_time() + { +#if ENABLE_BLOCKS_PRE_PROCESSING + forward_pass(); + reverse_pass(); + recalculate_trapezoids(); +#endif // ENABLE_BLOCKS_PRE_PROCESSING + + _time = get_additional_time(); + + for (const Block& block : _blocks) + { + _time += block.acceleration_time(); + _time += block.cruise_time(); + _time += block.deceleration_time(); + } + } + + void GCodeTimeEstimator::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line) { if (line.cmd.length() > 1) { @@ -335,6 +406,11 @@ namespace Slic3r { _processM204(line); break; } + case 205: // Advanced settings + { + _processM205(line); + break; + } case 566: // Set allowable instantaneous speed change { _processM566(line); @@ -345,16 +421,10 @@ namespace Slic3r { break; } } - -// CmdToCounterMap::iterator it = _cmdCounters.find(line.cmd); -// if (it == _cmdCounters.end()) -// _cmdCounters.insert(CmdToCounterMap::value_type(line.cmd, 1)); -// else -// ++it->second; } } - void My_GCodeTimeEstimator::_processG1(const GCodeReader::GCodeLine& line) + void GCodeTimeEstimator::_processG1(const GCodeReader::GCodeLine& line) { float lengthsScaleFactor = (get_units() == Inches) ? INCHES_TO_MM : 1.0f; @@ -379,7 +449,7 @@ namespace Slic3r { // updates feedrate from line, if present if (line.has('F')) - set_feedrate(line.get_float('F') * MMMIN_TO_MMSEC); + set_feedrate(std::max(line.get_float('F') * MMMIN_TO_MMSEC, get_minimum_feedrate())); // fills block data Block block; @@ -397,24 +467,26 @@ namespace Slic3r { return; // calculates block feedrate - float feedrate = get_feedrate(); + _curr.feedrate = std::max(get_feedrate(), get_minimum_feedrate()); float distance = block.move_length(); float invDistance = 1.0f / distance; - float axis_feedrate[Num_Axis]; float min_feedrate_factor = 1.0f; for (unsigned char a = X; a < Num_Axis; ++a) { - axis_feedrate[a] = feedrate * ::abs(block.delta_pos[a]) * invDistance; - if (axis_feedrate[a] > 0.0f) - min_feedrate_factor = std::min(min_feedrate_factor, get_axis_max_feedrate((EAxis)a) / axis_feedrate[a]); + _curr.axis_feedrate[a] = _curr.feedrate * block.delta_pos[a] * invDistance; + _curr.abs_axis_feedrate[a] = ::abs(_curr.axis_feedrate[a]); + if (_curr.abs_axis_feedrate[a] > 0.0f) + min_feedrate_factor = std::min(min_feedrate_factor, get_axis_max_feedrate((EAxis)a) / _curr.abs_axis_feedrate[a]); } - block.feedrate = min_feedrate_factor * feedrate; + block.feedrate.cruise = min_feedrate_factor * _curr.feedrate; + for (unsigned char a = X; a < Num_Axis; ++a) { - axis_feedrate[a] *= min_feedrate_factor; + _curr.axis_feedrate[a] *= min_feedrate_factor; + _curr.abs_axis_feedrate[a] *= min_feedrate_factor; } // calculates block acceleration @@ -430,27 +502,28 @@ namespace Slic3r { block.acceleration = acceleration; // calculates block exit feedrate - float exit_feedrate = block.feedrate; + _curr.safe_feedrate = block.feedrate.cruise; for (unsigned char a = X; a < Num_Axis; ++a) { - float half_axis_max_jerk = 0.5f * get_axis_max_jerk((EAxis)a); - if (axis_feedrate[a] > half_axis_max_jerk) - exit_feedrate = std::min(exit_feedrate, half_axis_max_jerk); + float axis_max_jerk = get_axis_max_jerk((EAxis)a); + if (_curr.abs_axis_feedrate[a] > axis_max_jerk) + _curr.safe_feedrate = std::min(_curr.safe_feedrate, axis_max_jerk); } - block.exit_feedrate = exit_feedrate; + block.feedrate.exit = _curr.safe_feedrate; // calculates block entry feedrate - float vmax_junction = exit_feedrate; - if (!_blocks.empty() && (_prev.feedrate > FEEDRATE_THRESHOLD)) +#if USE_CURA_JUNCTION_VMAX + float vmax_junction = _curr.safe_feedrate; + if (!_blocks.empty() && (_prev.feedrate > PREVIOUS_FEEDRATE_THRESHOLD)) { - vmax_junction = block.feedrate; + vmax_junction = block.feedrate.cruise; float vmax_junction_factor = 1.0f; for (unsigned char a = X; a < Num_Axis; ++a) { - float abs_delta_axis_feedrate = ::abs(axis_feedrate[a] - _prev.axis_feedrate[a]); + float abs_delta_axis_feedrate = ::abs(_curr.axis_feedrate[a] - _prev.axis_feedrate[a]); float axis_max_jerk = get_axis_max_jerk((EAxis)a); if (abs_delta_axis_feedrate > axis_max_jerk) vmax_junction_factor = std::min(vmax_junction_factor, axis_max_jerk / abs_delta_axis_feedrate); @@ -460,17 +533,94 @@ namespace Slic3r { vmax_junction = std::min(_prev.feedrate, vmax_junction * vmax_junction_factor); } - block.entry_feedrate = std::min(vmax_junction, Block::max_allowable_speed(-acceleration, MINIMUM_PLANNER_SPEED, distance)); +#if ENABLE_BLOCKS_PRE_PROCESSING + float v_allowable = Block::max_allowable_speed(-acceleration, MINIMUM_PLANNER_SPEED, distance); + block.feedrate.entry = std::min(vmax_junction, v_allowable); +#else + block.feedrate.entry = std::min(vmax_junction, Block::max_allowable_speed(-acceleration, MINIMUM_PLANNER_SPEED, distance)); +#endif // ENABLE_BLOCKS_PRE_PROCESSING +#else + float vmax_junction = _curr.safe_feedrate; + if (!_blocks.empty() && (_prev.feedrate > PREVIOUS_FEEDRATE_THRESHOLD)) + { + bool prev_speed_larger = _prev.feedrate > block.feedrate.cruise; + float smaller_speed_factor = prev_speed_larger ? (block.feedrate.cruise / _prev.feedrate) : (_prev.feedrate / block.feedrate.cruise); + // Pick the smaller of the nominal speeds. Higher speed shall not be achieved at the junction during coasting. + vmax_junction = prev_speed_larger ? block.feedrate.cruise : _prev.feedrate; + + float v_factor = 1.0f; + bool limited = false; + + for (unsigned char a = X; a < Num_Axis; ++a) + { + // Limit an axis. We have to differentiate coasting from the reversal of an axis movement, or a full stop. + float v_exit = _prev.axis_feedrate[a]; + float v_entry = _curr.axis_feedrate[a]; + + if (prev_speed_larger) + v_exit *= smaller_speed_factor; + + if (limited) + { + v_exit *= v_factor; + v_entry *= v_factor; + } + + // Calculate the jerk depending on whether the axis is coasting in the same direction or reversing a direction. + float jerk = + (v_exit > v_entry) ? + (((v_entry > 0.0f) || (v_exit < 0.0f)) ? + // coasting + (v_exit - v_entry) : + // axis reversal + std::max(v_exit, -v_entry)) : + // v_exit <= v_entry + (((v_entry < 0.0f) || (v_exit > 0.0f)) ? + // coasting + (v_entry - v_exit) : + // axis reversal + std::max(-v_exit, v_entry)); + + float axis_max_jerk = get_axis_max_jerk((EAxis)a); + if (jerk > axis_max_jerk) + { + v_factor *= axis_max_jerk / jerk; + limited = true; + } + } + + if (limited) + vmax_junction *= v_factor; + + // Now the transition velocity is known, which maximizes the shared exit / entry velocity while + // respecting the jerk factors, it may be possible, that applying separate safe exit / entry velocities will achieve faster prints. + float vmax_junction_threshold = vmax_junction * 0.99f; + + // Not coasting. The machine will stop and start the movements anyway, better to start the segment from start. + if ((_prev.safe_feedrate > vmax_junction_threshold) && (_curr.safe_feedrate > vmax_junction_threshold)) + vmax_junction = _curr.safe_feedrate; + } + +#if ENABLE_BLOCKS_PRE_PROCESSING + float v_allowable = Block::max_allowable_speed(-acceleration, _curr.safe_feedrate, distance); + block.feedrate.entry = std::min(vmax_junction, v_allowable); +#else + block.feedrate.entry = std::min(vmax_junction, Block::max_allowable_speed(-acceleration, _curr.safe_feedrate, distance)); +#endif // ENABLE_BLOCKS_PRE_PROCESSING +#endif // USE_CURA_JUNCTION_VMAX + +#if ENABLE_BLOCKS_PRE_PROCESSING + block.max_entry_speed = vmax_junction; + block.flags.nominal_length = (block.feedrate.cruise <= v_allowable); + block.flags.recalculate = true; + block.safe_feedrate = _curr.safe_feedrate; +#endif // ENABLE_BLOCKS_PRE_PROCESSING // calculates block trapezoid block.calculate_trapezoid(); - // updates previous cache - _prev.feedrate = feedrate; - for (unsigned char a = X; a < Num_Axis; ++a) - { - _prev.axis_feedrate[a] = axis_feedrate[a]; - } + // updates previous + _prev = _curr; // updates axis positions for (unsigned char a = X; a < Num_Axis; ++a) @@ -482,7 +632,7 @@ namespace Slic3r { _blocks.push_back(block); } - void My_GCodeTimeEstimator::_processG4(const GCodeReader::GCodeLine& line) + void GCodeTimeEstimator::_processG4(const GCodeReader::GCodeLine& line) { EDialect dialect = get_dialect(); @@ -500,44 +650,44 @@ namespace Slic3r { } } - void My_GCodeTimeEstimator::_processG20(const GCodeReader::GCodeLine& line) + void GCodeTimeEstimator::_processG20(const GCodeReader::GCodeLine& line) { set_units(Inches); } - void My_GCodeTimeEstimator::_processG21(const GCodeReader::GCodeLine& line) + void GCodeTimeEstimator::_processG21(const GCodeReader::GCodeLine& line) { set_units(Millimeters); } - void My_GCodeTimeEstimator::_processG28(const GCodeReader::GCodeLine& line) + void GCodeTimeEstimator::_processG28(const GCodeReader::GCodeLine& line) { // todo } - void My_GCodeTimeEstimator::_processG90(const GCodeReader::GCodeLine& line) + void GCodeTimeEstimator::_processG90(const GCodeReader::GCodeLine& line) { set_positioningType(Absolute); } - void My_GCodeTimeEstimator::_processG91(const GCodeReader::GCodeLine& line) + void GCodeTimeEstimator::_processG91(const GCodeReader::GCodeLine& line) { // >>>>>>>> THERE ARE DIALECT VARIANTS set_positioningType(Relative); } - void My_GCodeTimeEstimator::_processG92(const GCodeReader::GCodeLine& line) + void GCodeTimeEstimator::_processG92(const GCodeReader::GCodeLine& line) { // todo } - void My_GCodeTimeEstimator::_processM109(const GCodeReader::GCodeLine& line) + void GCodeTimeEstimator::_processM109(const GCodeReader::GCodeLine& line) { // todo } - void My_GCodeTimeEstimator::_processM203(const GCodeReader::GCodeLine& line) + void GCodeTimeEstimator::_processM203(const GCodeReader::GCodeLine& line) { EDialect dialect = get_dialect(); @@ -561,7 +711,7 @@ namespace Slic3r { set_axis_max_feedrate(E, line.get_float('E') * factor); } - void My_GCodeTimeEstimator::_processM204(const GCodeReader::GCodeLine& line) + void GCodeTimeEstimator::_processM204(const GCodeReader::GCodeLine& line) { if (line.has('S')) set_acceleration(line.get_float('S')); // <<<< Is this correct ? @@ -572,7 +722,29 @@ namespace Slic3r { } } - void My_GCodeTimeEstimator::_processM566(const GCodeReader::GCodeLine& line) + void GCodeTimeEstimator::_processM205(const GCodeReader::GCodeLine& line) + { + if (line.has('X')) + { + float max_jerk = line.get_float('X'); + set_axis_max_jerk(X, max_jerk); + set_axis_max_jerk(Y, max_jerk); + } + + if (line.has('Y')) + set_axis_max_jerk(Y, line.get_float('Y')); + + if (line.has('Z')) + set_axis_max_jerk(Z, line.get_float('Z')); + + if (line.has('E')) + set_axis_max_jerk(E, line.get_float('E')); + + if (line.has('S')) + set_minimum_feedrate(line.get_float('S')); + } + + void GCodeTimeEstimator::_processM566(const GCodeReader::GCodeLine& line) { if (line.has('X')) set_axis_max_jerk(X, line.get_float('X') * MMMIN_TO_MMSEC); @@ -586,77 +758,119 @@ namespace Slic3r { if (line.has('E')) set_axis_max_jerk(E, line.get_float('E') * MMMIN_TO_MMSEC); } -//########################################################################################################### -void -GCodeTimeEstimator::parse(const std::string &gcode) -{ - GCodeReader::parse(gcode, boost::bind(&GCodeTimeEstimator::_parser, this, _1, _2)); -} +#if ENABLE_BLOCKS_PRE_PROCESSING + void GCodeTimeEstimator::forward_pass() + { + Block* block[2] = { nullptr, nullptr }; -void -GCodeTimeEstimator::parse_file(const std::string &file) -{ - GCodeReader::parse_file(file, boost::bind(&GCodeTimeEstimator::_parser, this, _1, _2)); -} - -void -GCodeTimeEstimator::_parser(GCodeReader&, const GCodeReader::GCodeLine &line) -{ - // std::cout << "[" << this->time << "] " << line.raw << std::endl; - if (line.cmd == "G1") { - const float dist_XY = line.dist_XY(); - const float new_F = line.new_F(); - - if (dist_XY > 0) { - //this->time += dist_XY / new_F * 60; - this->time += _accelerated_move(dist_XY, new_F/60, this->acceleration); - } else { - //this->time += std::abs(line.dist_E()) / new_F * 60; - this->time += _accelerated_move(std::abs(line.dist_E()), new_F/60, this->acceleration); - } - //this->time += std::abs(line.dist_Z()) / new_F * 60; - this->time += _accelerated_move(std::abs(line.dist_Z()), new_F/60, this->acceleration); - } else if (line.cmd == "M204" && line.has('S')) { - this->acceleration = line.get_float('S'); - } else if (line.cmd == "G4") { // swell - if (line.has('S')) { - this->time += line.get_float('S'); - } else if (line.has('P')) { - this->time += line.get_float('P')/1000; - } + for (Block& b : _blocks) + { + block[0] = block[1]; + block[1] = &b; + planner_forward_pass_kernel(block[0], block[1]); } -} -// Wildly optimistic acceleration "bell" curve modeling. -// Returns an estimate of how long the move with a given accel -// takes in seconds. -// It is assumed that the movement is smooth and uniform. -float -GCodeTimeEstimator::_accelerated_move(double length, double v, double acceleration) -{ - // for half of the move, there are 2 zones, where the speed is increasing/decreasing and - // where the speed is constant. - // Since the slowdown is assumed to be uniform, calculate the average velocity for half of the - // expected displacement. - // final velocity v = a*t => a * (dx / 0.5v) => v^2 = 2*a*dx - // v_avg = 0.5v => 2*v_avg = v - // d_x = v_avg*t => t = d_x / v_avg - acceleration = (acceleration == 0.0 ? 4000.0 : acceleration); // Set a default accel to use for print time in case it's 0 somehow. - auto half_length = length / 2.0; - auto t_init = v / acceleration; // time to final velocity - auto dx_init = (0.5*v*t_init); // Initial displacement for the time to get to final velocity - auto t = 0.0; - if (half_length >= dx_init) { - half_length -= (0.5*v*t_init); - t += t_init; - t += (half_length / v); // rest of time is at constant speed. - } else { - // If too much displacement for the expected final velocity, we don't hit the max, so reduce - // the average velocity to fit the displacement we actually are looking for. - t += std::sqrt(std::abs(length) * 2.0 * acceleration) / acceleration; + planner_forward_pass_kernel(block[1], nullptr); + } + + void GCodeTimeEstimator::reverse_pass() + { + Block* block[2] = { nullptr, nullptr }; + + for (int i = (int)_blocks.size() - 1; i >= 0; --i) + { + block[1] = block[0]; + block[0] = &_blocks[i]; + planner_reverse_pass_kernel(block[0], block[1]); } - return 2.0*t; // cut in half before, so double to get full time spent. -} + } + + void GCodeTimeEstimator::planner_forward_pass_kernel(Block* prev, Block* curr) + { + if (prev == nullptr) + return; + + // If the previous block is an acceleration block, but it is not long enough to complete the + // full speed change within the block, we need to adjust the entry speed accordingly. Entry + // speeds have already been reset, maximized, and reverse planned by reverse planner. + // If nominal length is true, max junction speed is guaranteed to be reached. No need to recheck. + if (!prev->flags.nominal_length) + { + if (prev->feedrate.entry < curr->feedrate.entry) + { + float entry_speed = std::min(curr->feedrate.entry, Block::max_allowable_speed(-prev->acceleration, prev->feedrate.entry, prev->move_length())); + + // Check for junction speed change + if (curr->feedrate.entry != entry_speed) + { + curr->feedrate.entry = entry_speed; + curr->flags.recalculate = true; + } + } + } + } + + void GCodeTimeEstimator::planner_reverse_pass_kernel(Block* curr, Block* next) + { + if ((curr == nullptr) || (next == nullptr)) + return; + + // If entry speed is already at the maximum entry speed, no need to recheck. Block is cruising. + // If not, block in state of acceleration or deceleration. Reset entry speed to maximum and + // check for maximum allowable speed reductions to ensure maximum possible planned speed. + if (curr->feedrate.entry != curr->max_entry_speed) + { + // If nominal length true, max junction speed is guaranteed to be reached. Only compute + // for max allowable speed if block is decelerating and nominal length is false. + if (!curr->flags.nominal_length && (curr->max_entry_speed > next->feedrate.entry)) + curr->feedrate.entry = std::min(curr->max_entry_speed, Block::max_allowable_speed(-curr->acceleration, next->feedrate.entry, curr->move_length())); + else + curr->feedrate.entry = curr->max_entry_speed; + + curr->flags.recalculate = true; + } + } + + void GCodeTimeEstimator::recalculate_trapezoids() + { + Block* curr = nullptr; + Block* next = nullptr; + + for (Block& b : _blocks) + { + curr = next; + next = &b; + + if (curr != nullptr) + { + // Recalculate if current block entry or exit junction speed has changed. + if (curr->flags.recalculate || next->flags.recalculate) + { + // NOTE: Entry and exit factors always > 0 by all previous logic operations. + Block block = *curr; + block.feedrate.exit = next->feedrate.entry; + block.calculate_trapezoid(); + curr->trapezoid = block.trapezoid; + curr->flags.recalculate = false; // Reset current only to ensure next trapezoid is computed + } + } + } + + // Last/newest block in buffer. Exit speed is set with MINIMUM_PLANNER_SPEED. Always recalculated. + if (next != nullptr) + { + Block block = *next; +#if USE_CURA_JUNCTION_VMAX + block.feedrate.exit = MINIMUM_PLANNER_SPEED; +#else + block.feedrate.exit = next->safe_feedrate; +#endif // USE_CURA_JUNCTION_VMAX + block.calculate_trapezoid(); + next->trapezoid = block.trapezoid; + next->flags.recalculate = false; + } + } +#endif // ENABLE_BLOCKS_PRE_PROCESSING } diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index 6e3de493f7..06d5c50e42 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -4,10 +4,12 @@ #include "libslic3r.h" #include "GCodeReader.hpp" +#define USE_CURA_JUNCTION_VMAX 0 +#define ENABLE_BLOCKS_PRE_PROCESSING 1 + namespace Slic3r { -//########################################################################################################### - class My_GCodeTimeEstimator : public GCodeReader + class GCodeTimeEstimator { public: enum EUnits : unsigned char @@ -51,6 +53,16 @@ namespace Slic3r { float max_jerk; // mm/s }; + struct Feedrates + { + float feedrate; // mm/s + float axis_feedrate[Num_Axis]; // mm/s + float abs_axis_feedrate[Num_Axis]; // mm/s + float safe_feedrate; // mm/s + + void reset(); + }; + struct State { EDialect dialect; @@ -60,37 +72,74 @@ namespace Slic3r { float feedrate; // mm/s float acceleration; // mm/s^2 float additional_time; // s - }; - - struct PreviousBlockCache - { - float feedrate; // mm/s - float axis_feedrate[Num_Axis]; // mm/s + float minimum_feedrate; // mm/s }; public: struct Block { + struct FeedrateProfile + { + float entry; // mm/s + float cruise; // mm/s + float exit; // mm/s + }; + struct Trapezoid { float distance; // mm float accelerate_until; // mm float decelerate_after; // mm - float entry_feedrate; // mm/s - float exit_feedrate; // mm/s + FeedrateProfile feedrate; + + float acceleration_time(float acceleration) const; + float cruise_time() const; + float deceleration_time(float acceleration) const; + float cruise_distance() const; + + // This function gives the time needed to accelerate from an initial speed to reach a final distance. + static float acceleration_time_from_distance(float initial_feedrate, float distance, float acceleration); + + // This function gives the final speed while accelerating at the given constant acceleration from the given initial speed along the given distance. + static float speed_from_distance(float initial_feedrate, float distance, float acceleration); }; - float delta_pos[Num_Axis]; // mm - float feedrate; // mm/s - float acceleration; // mm/s^2 - float entry_feedrate; // mm/s - float exit_feedrate; // mm/s +#if ENABLE_BLOCKS_PRE_PROCESSING + struct Flags + { + bool recalculate; + bool nominal_length; + }; + Flags flags; +#endif // ENABLE_BLOCKS_PRE_PROCESSING + + float delta_pos[Num_Axis]; // mm + float acceleration; // mm/s^2 +#if ENABLE_BLOCKS_PRE_PROCESSING + float max_entry_speed; // mm/s + float safe_feedrate; // mm/s +#endif // ENABLE_BLOCKS_PRE_PROCESSING + + FeedrateProfile feedrate; Trapezoid trapezoid; // Returns the length of the move covered by this block, in mm float move_length() const; + // Returns the time spent accelerating toward cruise speed, in seconds + float acceleration_time() const; + + // Returns the time spent at cruise speed, in seconds + float cruise_time() const; + + // Returns the time spent decelerating from cruise speed, in seconds + float deceleration_time() const; + + // Returns the distance covered at cruise speed, in mm + float cruise_distance() const; + + // Calculates this block's trapezoid void calculate_trapezoid(); // Calculates the maximum allowable speed at this point when you must be able to reach target_velocity using the @@ -105,29 +154,26 @@ namespace Slic3r { // a total travel of distance. This can be used to compute the intersection point between acceleration and // deceleration in the cases where the trapezoid has no plateau (i.e. never reaches maximum speed) static float intersection_distance(float initial_rate, float final_rate, float acceleration, float distance); - - // This function gives the time it needs to accelerate from an initial speed to reach a final distance. - static float acceleration_time_from_distance(float initial_feedrate, float distance, float acceleration); }; typedef std::vector BlocksList; private: -// typedef std::map CmdToCounterMap; -// CmdToCounterMap _cmdCounters; - + GCodeReader _parser; State _state; - PreviousBlockCache _prev; + Feedrates _curr; + Feedrates _prev; BlocksList _blocks; float _time; // s public: - My_GCodeTimeEstimator(); + GCodeTimeEstimator(); - void parse(const std::string& gcode); - void parse_file(const std::string& file); + // Calculates the time estimate from the given gcode in string format + void calculate_time_from_text(const std::string& gcode); - void calculate_time(); + // Calculates the time estimate from the gcode contained in the file with the given filename + void calculate_time_from_file(const std::string& file); void set_axis_position(EAxis axis, float position); void set_axis_max_feedrate(EAxis axis, float feedrate_mm_sec); @@ -145,6 +191,9 @@ namespace Slic3r { void set_acceleration(float acceleration); float get_acceleration() const; + void set_minimum_feedrate(float feedrate_mm_sec); + float get_minimum_feedrate() const; + void set_dialect(EDialect dialect); EDialect get_dialect() const; @@ -155,20 +204,23 @@ namespace Slic3r { EPositioningType get_positioningType() const; void add_additional_time(float timeSec); + void set_additional_time(float timeSec); float get_additional_time() const; void set_default(); - // returns estimated time in seconds + // Returns the estimated time, in seconds float get_time() const; - const BlocksList& get_blocks() const; - -// void print_counters() const; + // Returns the estimated time, in format HH:MM:SS + std::string get_time_hms() const; private: void _reset(); + // Calculates the time estimate + void _calculate_time(); + // Processes GCode line void _process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line); @@ -205,23 +257,22 @@ namespace Slic3r { // Set default acceleration void _processM204(const GCodeReader::GCodeLine& line); + // Advanced settings + void _processM205(const GCodeReader::GCodeLine& line); + // Set allowable instantaneous speed change void _processM566(const GCodeReader::GCodeLine& line); - }; -//########################################################################################################### -class GCodeTimeEstimator : public GCodeReader { - public: - float time = 0; // in seconds - - void parse(const std::string &gcode); - void parse_file(const std::string &file); - - protected: - float acceleration = 9000; - void _parser(GCodeReader&, const GCodeReader::GCodeLine &line); - static float _accelerated_move(double length, double v, double acceleration); -}; +#if ENABLE_BLOCKS_PRE_PROCESSING + void forward_pass(); + void reverse_pass(); + + void planner_forward_pass_kernel(Block* prev, Block* curr); + void planner_reverse_pass_kernel(Block* curr, Block* next); + + void recalculate_trapezoids(); +#endif // ENABLE_BLOCKS_PRE_PROCESSING + }; } /* namespace Slic3r */ From a0a503e4a884775d21404afd0d2acc019a27a88d Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 11 Dec 2017 09:06:29 +0100 Subject: [PATCH 03/33] integration of time estimator into gcode export - save time estimation into gcode file --- xs/src/libslic3r/GCode.cpp | 127 ++++++++++++++++++++---- xs/src/libslic3r/GCode.hpp | 10 ++ xs/src/libslic3r/GCodeTimeEstimator.cpp | 33 ++++-- xs/src/libslic3r/GCodeTimeEstimator.hpp | 9 ++ 4 files changed, 148 insertions(+), 31 deletions(-) diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 8d8bf3e3ec..018c01b713 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -5,10 +5,6 @@ #include "GCode/PrintExtents.hpp" #include "GCode/WipeTowerPrusaMM.hpp" -//############################################################################################################ -#include "GCodeTimeEstimator.hpp" -//############################################################################################################ - #include #include #include @@ -263,16 +259,77 @@ std::string WipeTowerIntegration::finalize(GCode &gcodegen) #define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_writer.extruder()->id()) +#if ENABLE_TIME_ESTIMATOR +// Helper class for writing to file with/without time estimation +class Write +{ + static GCodeTimeEstimator* s_time_estimator; + +public: + static void set_time_estimator(GCodeTimeEstimator* time_estimator) + { + s_time_estimator = time_estimator; + } + + static void write(FILE* file, const std::string& what) + { + if (!what.empty()) + { + fwrite(what.data(), 1, what.size(), file); + + if (s_time_estimator != nullptr) + { + const char endLine = '\n'; + std::string::size_type beginPos = 0; + std::string::size_type endPos = what.find_first_of(endLine, beginPos); + while (endPos != std::string::npos) + { + s_time_estimator->add_gcode_line(what.substr(beginPos, endPos - beginPos + 1)); + + beginPos = endPos + 1; + endPos = what.find_first_of(endLine, beginPos); + } + } + } + } +}; + +//std::string Write::s_cache = ""; +GCodeTimeEstimator* Write::s_time_estimator = nullptr; +#endif // ENABLE_TIME_ESTIMATOR + inline void write(FILE *file, const std::string &what) { - fwrite(what.data(), 1, what.size(), file); +#if ENABLE_TIME_ESTIMATOR + Write::write(file, what); +#else + fwrite(what.data(), 1, what.size(), file); +#endif // ENABLE_TIME_ESTIMATOR } +#if ENABLE_TIME_ESTIMATOR +inline void write_format(FILE* file, const char* format, ...) +{ + char buffer[1024]; + va_list args; + va_start(args, format); + int res = ::vsnprintf(buffer, 1024, format, args); + va_end(args); + + if (res >= 0) + write(file, buffer); +} +#endif // ENABLE_TIME_ESTIMATOR + inline void writeln(FILE *file, const std::string &what) { if (! what.empty()) { - write(file, what); - fprintf(file, "\n"); +#if ENABLE_TIME_ESTIMATOR + write_format(file, "%s\n", what.c_str()); +#else + write(file, what); + fprintf(file, "\n"); +#endif // ENABLE_TIME_ESTIMATOR } } @@ -379,20 +436,28 @@ bool GCode::do_export(Print *print, const char *path) if (! result) boost::nowide::remove(path_tmp.c_str()); -//############################################################################################################ - GCodeTimeEstimator timeEstimator; - timeEstimator.calculate_time_from_file(path); - float time = timeEstimator.get_time(); - std::string timeHMS = timeEstimator.get_time_hms(); + // debug only -> tests time estimator from file + { + GCodeTimeEstimator timeEstimator; + timeEstimator.calculate_time_from_file(path); + float time = timeEstimator.get_time(); + std::string timeHMS = timeEstimator.get_time_hms(); - std::cout << std::endl << ">>> estimated time: " << timeHMS << " (" << time << " seconds)" << std::endl << std::endl; -//############################################################################################################ + std::cout << std::endl << "Time estimated from file:" << std::endl; + std::cout << std::endl << ">>> estimated time: " << timeHMS << " (" << time << " seconds)" << std::endl << std::endl; + } return result; } bool GCode::_do_export(Print &print, FILE *file) { +#if ENABLE_TIME_ESTIMATOR + // resets time estimator + m_time_estimator.reset(); + Write::set_time_estimator(&m_time_estimator); +#endif // ENABLE_TIME_ESTIMATOR + // How many times will be change_layer() called? // change_layer() in turn increments the progress bar status. m_layer_count = 0; @@ -496,7 +561,7 @@ bool GCode::_do_export(Print &print, FILE *file) fprintf(file, "; %s\n", line.c_str()); } if (! lines.empty()) - fprintf(file, "\n"); + fprintf(file, "\n"); } // Write some terse information on the slicing parameters. { @@ -555,8 +620,8 @@ bool GCode::_do_export(Print &print, FILE *file) // Disable fan. if (! print.config.cooling.get_at(initial_extruder_id) || print.config.disable_fan_first_layers.get_at(initial_extruder_id)) - write(file, m_writer.set_fan(0, true)); - + write(file, m_writer.set_fan(0, true)); + // Set bed temperature if the start G-code does not contain any bed temp control G-codes. { // Always call m_writer.set_bed_temperature() so it will set the internal "current" state of the bed temp as if @@ -565,7 +630,7 @@ bool GCode::_do_export(Print &print, FILE *file) std::string gcode = m_writer.set_bed_temperature(print.config.first_layer_bed_temperature.get_at(initial_extruder_id), true); if (boost::ifind_first(print.config.start_gcode.value, std::string("M140")).empty() && boost::ifind_first(print.config.start_gcode.value, std::string("M190")).empty()) - write(file, gcode); + write(file, gcode); } // Set extruder(s) temperature before and after start G-code. @@ -715,15 +780,28 @@ bool GCode::_do_export(Print &print, FILE *file) bbox_prime.offset(0.5f); // Beep for 500ms, tone 800Hz. Yet better, play some Morse. write(file, this->retract()); +#if ENABLE_TIME_ESTIMATOR + write_format(file, "M300 S800 P500\n"); +#else fprintf(file, "M300 S800 P500\n"); +#endif // ENABLE_TIME_ESTIMATOR if (bbox_prime.overlap(bbox_print)) { // Wait for the user to remove the priming extrusions, otherwise they would // get covered by the print. - fprintf(file, "M1 Remove priming towers and click button.\n"); - } else { +#if ENABLE_TIME_ESTIMATOR + write_format(file, "M1 Remove priming towers and click button.\n"); +#else + fprintf(file, "M1 Remove priming towers and click button.\n"); +#endif // ENABLE_TIME_ESTIMATOR + } + else { // Just wait for a bit to let the user check, that the priming succeeded. //TODO Add a message explaining what the printer is waiting for. This needs a firmware fix. - fprintf(file, "M1 S10\n"); +#if ENABLE_TIME_ESTIMATOR + write_format(file, "M1 S10\n"); +#else + fprintf(file, "M1 S10\n"); +#endif // ENABLE_TIME_ESTIMATOR } } else write(file, WipeTowerIntegration::prime_single_color_print(print, initial_extruder_id, *this)); @@ -778,6 +856,11 @@ bool GCode::_do_export(Print &print, FILE *file) } fprintf(file, "; total filament cost = %.1lf\n", print.total_cost); +#if ENABLE_TIME_ESTIMATOR + m_time_estimator.calculate_time(); + fprintf(file, "; estimated printing time = %s\n", m_time_estimator.get_time_hms()); +#endif // ENABLE_TIME_ESTIMATOR + // Append full config. fprintf(file, "\n"); { @@ -785,7 +868,7 @@ bool GCode::_do_export(Print &print, FILE *file) for (size_t i = 0; i < sizeof(configs) / sizeof(configs[0]); ++ i) { StaticPrintConfig *cfg = configs[i]; for (const std::string &key : cfg->keys()) - fprintf(file, "; %s = %s\n", key.c_str(), cfg->serialize(key).c_str()); + fprintf(file, "; %s = %s\n", key.c_str(), cfg->serialize(key).c_str()); } } diff --git a/xs/src/libslic3r/GCode.hpp b/xs/src/libslic3r/GCode.hpp index e68cf49c78..ba5270785c 100644 --- a/xs/src/libslic3r/GCode.hpp +++ b/xs/src/libslic3r/GCode.hpp @@ -1,6 +1,8 @@ #ifndef slic3r_GCode_hpp_ #define slic3r_GCode_hpp_ +#define ENABLE_TIME_ESTIMATOR 1 + #include "libslic3r.h" #include "ExPolygon.hpp" #include "GCodeWriter.hpp" @@ -15,6 +17,9 @@ #include "GCode/SpiralVase.hpp" #include "GCode/ToolOrdering.hpp" #include "GCode/WipeTower.hpp" +#if ENABLE_TIME_ESTIMATOR +#include "GCodeTimeEstimator.hpp" +#endif // ENABLE_TIME_ESTIMATOR #include "EdgeGrid.hpp" #include @@ -267,6 +272,11 @@ protected: // Index of a last object copy extruded. std::pair m_last_obj_copy; +#if ENABLE_TIME_ESTIMATOR + // Time estimator + GCodeTimeEstimator m_time_estimator; +#endif // ENABLE_TIME_ESTIMATOR + std::string _extrude(const ExtrusionPath &path, std::string description = "", double speed = -1); void _print_first_layer_extruder_temperatures(FILE *file, Print &print, unsigned int first_printing_extruder_id, bool wait); // this flag triggers first layer speeds diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index d612980bad..6c07620211 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -131,20 +131,33 @@ namespace Slic3r { GCodeTimeEstimator::GCodeTimeEstimator() { + reset(); + set_default(); } void GCodeTimeEstimator::calculate_time_from_text(const std::string& gcode) { - _reset(); _parser.parse(gcode, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); _calculate_time(); + reset(); } void GCodeTimeEstimator::calculate_time_from_file(const std::string& file) { - _reset(); _parser.parse_file(file, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); _calculate_time(); + reset(); + } + + void GCodeTimeEstimator::add_gcode_line(const std::string& gcode_line) + { + _parser.parse_line(gcode_line, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); + } + + void GCodeTimeEstimator::calculate_time() + { + _calculate_time(); + _reset(); } void GCodeTimeEstimator::set_axis_position(EAxis axis, float position) @@ -281,6 +294,12 @@ namespace Slic3r { } } + void GCodeTimeEstimator::reset() + { + _blocks.clear(); + _reset(); + } + float GCodeTimeEstimator::get_time() const { return _time; @@ -294,20 +313,16 @@ namespace Slic3r { int minutes = (int)(timeinsecs / 60.0f); timeinsecs -= (float)minutes * 60.0f; - char buf[16]; - ::sprintf(buf, "%02d:%02d:%02d", hours, minutes, (int)timeinsecs); - return buf; + char buffer[16]; + ::sprintf(buffer, "%02d:%02d:%02d", hours, minutes, (int)timeinsecs); + return buffer; } void GCodeTimeEstimator::_reset() { - _blocks.clear(); - _curr.reset(); _prev.reset(); - set_default(); - set_axis_position(X, 0.0f); set_axis_position(Y, 0.0f); set_axis_position(Z, 0.0f); diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index 06d5c50e42..4f8d0b31f1 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -175,6 +175,12 @@ namespace Slic3r { // Calculates the time estimate from the gcode contained in the file with the given filename void calculate_time_from_file(const std::string& file); + // Adds the given gcode line + void add_gcode_line(const std::string& gcode_line); + + // Calculates the time estimate from gcode lines added using add_gcode_line() + void calculate_time(); + void set_axis_position(EAxis axis, float position); void set_axis_max_feedrate(EAxis axis, float feedrate_mm_sec); void set_axis_max_acceleration(EAxis axis, float acceleration); @@ -209,6 +215,9 @@ namespace Slic3r { void set_default(); + // Call this method before to start adding lines using add_gcode_line() when reusing an instance of GCodeTimeEstimator + void reset(); + // Returns the estimated time, in seconds float get_time() const; From bea9628be08d9c2be9ba49c7538112d39b1d6fa8 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 11 Dec 2017 11:11:54 +0100 Subject: [PATCH 04/33] time estimation shown in GUI after gcode export --- lib/Slic3r/GUI/Plater.pm | 2 ++ xs/src/libslic3r/GCode.cpp | 54 ++++++-------------------------------- xs/src/libslic3r/GCode.hpp | 6 ----- xs/src/libslic3r/Print.hpp | 6 ++--- xs/xsp/Print.xsp | 10 +++++++ 5 files changed, 23 insertions(+), 55 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index aadd159f94..0f56da7ca9 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -441,6 +441,7 @@ sub new { fil_mm3 => "Used Filament (mm^3)", fil_g => "Used Filament (g)", cost => "Cost", + time => "Estimated printing time (min)", ); while (my $field = shift @info) { my $label = shift @info; @@ -1540,6 +1541,7 @@ sub on_export_completed { $self->{"print_info_cost"}->SetLabel(sprintf("%.2f" , $self->{print}->total_cost)); $self->{"print_info_fil_g"}->SetLabel(sprintf("%.2f" , $self->{print}->total_weight)); $self->{"print_info_fil_mm3"}->SetLabel(sprintf("%.2f" , $self->{print}->total_extruded_volume)); + $self->{"print_info_time"}->SetLabel(sprintf("%.2f" , $self->{print}->estimated_print_time)); $self->{"print_info_box_show"}->(1); # this updates buttons status diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 018c01b713..cf826ff68d 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -259,7 +259,6 @@ std::string WipeTowerIntegration::finalize(GCode &gcodegen) #define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_writer.extruder()->id()) -#if ENABLE_TIME_ESTIMATOR // Helper class for writing to file with/without time estimation class Write { @@ -296,18 +295,12 @@ public: //std::string Write::s_cache = ""; GCodeTimeEstimator* Write::s_time_estimator = nullptr; -#endif // ENABLE_TIME_ESTIMATOR inline void write(FILE *file, const std::string &what) { -#if ENABLE_TIME_ESTIMATOR Write::write(file, what); -#else - fwrite(what.data(), 1, what.size(), file); -#endif // ENABLE_TIME_ESTIMATOR } -#if ENABLE_TIME_ESTIMATOR inline void write_format(FILE* file, const char* format, ...) { char buffer[1024]; @@ -319,17 +312,11 @@ inline void write_format(FILE* file, const char* format, ...) if (res >= 0) write(file, buffer); } -#endif // ENABLE_TIME_ESTIMATOR inline void writeln(FILE *file, const std::string &what) { if (! what.empty()) { -#if ENABLE_TIME_ESTIMATOR write_format(file, "%s\n", what.c_str()); -#else - write(file, what); - fprintf(file, "\n"); -#endif // ENABLE_TIME_ESTIMATOR } } @@ -436,27 +423,14 @@ bool GCode::do_export(Print *print, const char *path) if (! result) boost::nowide::remove(path_tmp.c_str()); - // debug only -> tests time estimator from file - { - GCodeTimeEstimator timeEstimator; - timeEstimator.calculate_time_from_file(path); - float time = timeEstimator.get_time(); - std::string timeHMS = timeEstimator.get_time_hms(); - - std::cout << std::endl << "Time estimated from file:" << std::endl; - std::cout << std::endl << ">>> estimated time: " << timeHMS << " (" << time << " seconds)" << std::endl << std::endl; - } - return result; } bool GCode::_do_export(Print &print, FILE *file) { -#if ENABLE_TIME_ESTIMATOR // resets time estimator m_time_estimator.reset(); Write::set_time_estimator(&m_time_estimator); -#endif // ENABLE_TIME_ESTIMATOR // How many times will be change_layer() called? // change_layer() in turn increments the progress bar status. @@ -780,28 +754,16 @@ bool GCode::_do_export(Print &print, FILE *file) bbox_prime.offset(0.5f); // Beep for 500ms, tone 800Hz. Yet better, play some Morse. write(file, this->retract()); -#if ENABLE_TIME_ESTIMATOR - write_format(file, "M300 S800 P500\n"); -#else - fprintf(file, "M300 S800 P500\n"); -#endif // ENABLE_TIME_ESTIMATOR + write(file, "M300 S800 P500\n"); if (bbox_prime.overlap(bbox_print)) { // Wait for the user to remove the priming extrusions, otherwise they would // get covered by the print. -#if ENABLE_TIME_ESTIMATOR - write_format(file, "M1 Remove priming towers and click button.\n"); -#else - fprintf(file, "M1 Remove priming towers and click button.\n"); -#endif // ENABLE_TIME_ESTIMATOR - } + write(file, "M1 Remove priming towers and click button.\n"); + } else { // Just wait for a bit to let the user check, that the priming succeeded. //TODO Add a message explaining what the printer is waiting for. This needs a firmware fix. -#if ENABLE_TIME_ESTIMATOR - write_format(file, "M1 S10\n"); -#else - fprintf(file, "M1 S10\n"); -#endif // ENABLE_TIME_ESTIMATOR + write(file, "M1 S10\n"); } } else write(file, WipeTowerIntegration::prime_single_color_print(print, initial_extruder_id, *this)); @@ -830,12 +792,16 @@ bool GCode::_do_export(Print &print, FILE *file) write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100% write(file, m_writer.postamble()); + // calculates estimated printing time + m_time_estimator.calculate_time(); + // Get filament stats. print.filament_stats.clear(); print.total_used_filament = 0.; print.total_extruded_volume = 0.; print.total_weight = 0.; print.total_cost = 0.; + print.estimated_print_time = (double)m_time_estimator.get_time() / 60.0; for (const Extruder &extruder : m_writer.extruders()) { double used_filament = extruder.used_filament(); double extruded_volume = extruder.extruded_volume(); @@ -855,11 +821,7 @@ bool GCode::_do_export(Print &print, FILE *file) print.total_extruded_volume = print.total_extruded_volume + extruded_volume; } fprintf(file, "; total filament cost = %.1lf\n", print.total_cost); - -#if ENABLE_TIME_ESTIMATOR - m_time_estimator.calculate_time(); fprintf(file, "; estimated printing time = %s\n", m_time_estimator.get_time_hms()); -#endif // ENABLE_TIME_ESTIMATOR // Append full config. fprintf(file, "\n"); diff --git a/xs/src/libslic3r/GCode.hpp b/xs/src/libslic3r/GCode.hpp index ba5270785c..b29a6ed2f6 100644 --- a/xs/src/libslic3r/GCode.hpp +++ b/xs/src/libslic3r/GCode.hpp @@ -1,8 +1,6 @@ #ifndef slic3r_GCode_hpp_ #define slic3r_GCode_hpp_ -#define ENABLE_TIME_ESTIMATOR 1 - #include "libslic3r.h" #include "ExPolygon.hpp" #include "GCodeWriter.hpp" @@ -17,9 +15,7 @@ #include "GCode/SpiralVase.hpp" #include "GCode/ToolOrdering.hpp" #include "GCode/WipeTower.hpp" -#if ENABLE_TIME_ESTIMATOR #include "GCodeTimeEstimator.hpp" -#endif // ENABLE_TIME_ESTIMATOR #include "EdgeGrid.hpp" #include @@ -272,10 +268,8 @@ protected: // Index of a last object copy extruded. std::pair m_last_obj_copy; -#if ENABLE_TIME_ESTIMATOR // Time estimator GCodeTimeEstimator m_time_estimator; -#endif // ENABLE_TIME_ESTIMATOR std::string _extrude(const ExtrusionPath &path, std::string description = "", double speed = -1); void _print_first_layer_extruder_temperatures(FILE *file, Print &print, unsigned int first_printing_extruder_id, bool wait); diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index c4093b795d..bf137924a4 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -233,14 +233,14 @@ public: PrintRegionPtrs regions; PlaceholderParser placeholder_parser; // TODO: status_cb - double total_used_filament, total_extruded_volume, total_cost, total_weight; - std::map filament_stats; + double total_used_filament, total_extruded_volume, total_cost, total_weight, estimated_print_time; + std::map filament_stats; PrintState state; // ordered collections of extrusion paths to build skirt loops and brim ExtrusionEntityCollection skirt, brim; - Print() : total_used_filament(0), total_extruded_volume(0) { restart(); } + Print() : total_used_filament(0), total_extruded_volume(0), estimated_print_time(0) { restart(); } ~Print() { clear_objects(); } // methods for handling objects diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index b937fe6e89..cb2f633994 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -273,5 +273,15 @@ Print::total_cost(...) OUTPUT: RETVAL +double +Print::estimated_print_time(...) + CODE: + if (items > 1) { + THIS->estimated_print_time = (double)SvNV(ST(1)); + } + RETVAL = THIS->estimated_print_time; + OUTPUT: + RETVAL + %} }; From 34a0a2cb5e2d2ec94f9458248fa6076b4a842ee0 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 11 Dec 2017 14:03:29 +0100 Subject: [PATCH 05/33] GCodeTimeEstimator - added process of M82 and M83 gcodes --- xs/src/libslic3r/GCodeTimeEstimator.cpp | 77 ++++++++++++++++++------- xs/src/libslic3r/GCodeTimeEstimator.hpp | 22 +++++-- 2 files changed, 73 insertions(+), 26 deletions(-) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index 6c07620211..d711564581 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -250,14 +250,24 @@ namespace Slic3r { return _state.units; } - void GCodeTimeEstimator::set_positioningType(GCodeTimeEstimator::EPositioningType type) + void GCodeTimeEstimator::set_positioning_xyz_type(GCodeTimeEstimator::EPositioningType type) { - _state.positioningType = type; + _state.positioning_xyz_type = type; } - GCodeTimeEstimator::EPositioningType GCodeTimeEstimator::get_positioningType() const + GCodeTimeEstimator::EPositioningType GCodeTimeEstimator::get_positioning_xyz_type() const { - return _state.positioningType; + return _state.positioning_xyz_type; + } + + void GCodeTimeEstimator::set_positioning_e_type(GCodeTimeEstimator::EPositioningType type) + { + _state.positioning_e_type = type; + } + + GCodeTimeEstimator::EPositioningType GCodeTimeEstimator::get_positioning_e_type() const + { + return _state.positioning_e_type; } void GCodeTimeEstimator::add_additional_time(float timeSec) @@ -279,7 +289,8 @@ namespace Slic3r { { set_units(Millimeters); set_dialect(Unknown); - set_positioningType(Absolute); + set_positioning_xyz_type(Absolute); + set_positioning_e_type(Relative); set_feedrate(DEFAULT_FEEDRATE); set_acceleration(DEFAULT_ACCELERATION); @@ -406,6 +417,16 @@ namespace Slic3r { { switch (::atoi(&line.cmd[1])) { + case 82: // Set extruder to absolute mode + { + _processM82(line); + break; + } + case 83: // Set extruder to relative mode + { + _processM83(line); + break; + } case 109: // Set Extruder Temperature and Wait { _processM109(line); @@ -439,27 +460,29 @@ namespace Slic3r { } } + // Returns the new absolute position on the given axis in dependence of the given parameters + float axis_absolute_position_from_G1_line(GCodeTimeEstimator::EAxis axis, const GCodeReader::GCodeLine& lineG1, GCodeTimeEstimator::EUnits units, GCodeTimeEstimator::EPositioningType type, float current_absolute_position) + { + float lengthsScaleFactor = (units == GCodeTimeEstimator::Inches) ? INCHES_TO_MM : 1.0f; + if (lineG1.has(AXIS_STR[axis])) + { + float ret = lineG1.get_float(AXIS_STR[axis]) * lengthsScaleFactor; + return (type == GCodeTimeEstimator::Absolute) ? ret : current_absolute_position + ret; + } + else + return current_absolute_position; + } + void GCodeTimeEstimator::_processG1(const GCodeReader::GCodeLine& line) { float lengthsScaleFactor = (get_units() == Inches) ? INCHES_TO_MM : 1.0f; - // gets position changes from line, if present + // updates axes positions from line + EUnits units = get_units(); float new_pos[Num_Axis]; - - if (get_positioningType() == Absolute) + for (unsigned char a = X; a < Num_Axis; ++a) { - for (unsigned char a = X; a < Num_Axis; ++a) - { - new_pos[a] = line.has(AXIS_STR[a]) ? line.get_float(AXIS_STR[a]) * lengthsScaleFactor : get_axis_position((EAxis)a); - } - } - else // get_positioningType() == Relative - { - for (unsigned char a = X; a < Num_Axis; ++a) - { - new_pos[a] = get_axis_position((EAxis)a); - new_pos[a] += (line.has(AXIS_STR[a]) ? line.get_float(AXIS_STR[a]) * lengthsScaleFactor : 0.0f); - } + new_pos[a] = axis_absolute_position_from_G1_line((EAxis)a, line, units, (a == E) ? get_positioning_e_type() : get_positioning_xyz_type(), get_axis_position((EAxis)a)); } // updates feedrate from line, if present @@ -682,14 +705,24 @@ namespace Slic3r { void GCodeTimeEstimator::_processG90(const GCodeReader::GCodeLine& line) { - set_positioningType(Absolute); + set_positioning_xyz_type(Absolute); } void GCodeTimeEstimator::_processG91(const GCodeReader::GCodeLine& line) { // >>>>>>>> THERE ARE DIALECT VARIANTS - set_positioningType(Relative); + set_positioning_xyz_type(Relative); + } + + void GCodeTimeEstimator::_processM82(const GCodeReader::GCodeLine& line) + { + set_positioning_e_type(Absolute); + } + + void GCodeTimeEstimator::_processM83(const GCodeReader::GCodeLine& line) + { + set_positioning_e_type(Relative); } void GCodeTimeEstimator::_processG92(const GCodeReader::GCodeLine& line) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index 4f8d0b31f1..36d66f4355 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -67,7 +67,8 @@ namespace Slic3r { { EDialect dialect; EUnits units; - EPositioningType positioningType; + EPositioningType positioning_xyz_type; + EPositioningType positioning_e_type; Axis axis[Num_Axis]; float feedrate; // mm/s float acceleration; // mm/s^2 @@ -178,15 +179,19 @@ namespace Slic3r { // Adds the given gcode line void add_gcode_line(const std::string& gcode_line); - // Calculates the time estimate from gcode lines added using add_gcode_line() + // Calculates the time estimate from the gcode lines added using add_gcode_line() void calculate_time(); + // Set current position on the given axis with the given value void set_axis_position(EAxis axis, float position); + void set_axis_max_feedrate(EAxis axis, float feedrate_mm_sec); void set_axis_max_acceleration(EAxis axis, float acceleration); void set_axis_max_jerk(EAxis axis, float jerk); + // Returns current position on the given axis float get_axis_position(EAxis axis) const; + float get_axis_max_feedrate(EAxis axis) const; float get_axis_max_acceleration(EAxis axis) const; float get_axis_max_jerk(EAxis axis) const; @@ -206,8 +211,11 @@ namespace Slic3r { void set_units(EUnits units); EUnits get_units() const; - void set_positioningType(EPositioningType type); - EPositioningType get_positioningType() const; + void set_positioning_xyz_type(EPositioningType type); + EPositioningType get_positioning_xyz_type() const; + + void set_positioning_e_type(EPositioningType type); + EPositioningType get_positioning_e_type() const; void add_additional_time(float timeSec); void set_additional_time(float timeSec); @@ -257,6 +265,12 @@ namespace Slic3r { // Set Position void _processG92(const GCodeReader::GCodeLine& line); + // Set extruder to absolute mode + void _processM82(const GCodeReader::GCodeLine& line); + + // Set extruder to relative mode + void _processM83(const GCodeReader::GCodeLine& line); + // Set Extruder Temperature and Wait void _processM109(const GCodeReader::GCodeLine& line); From e199d0532c04087eedd99c5104230d61332d4156 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 11 Dec 2017 15:15:21 +0100 Subject: [PATCH 06/33] GCodeTimeEstimator - added process of G92 gcode --- xs/src/libslic3r/GCodeTimeEstimator.cpp | 37 +++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index d711564581..b0dd627131 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -475,8 +475,6 @@ namespace Slic3r { void GCodeTimeEstimator::_processG1(const GCodeReader::GCodeLine& line) { - float lengthsScaleFactor = (get_units() == Inches) ? INCHES_TO_MM : 1.0f; - // updates axes positions from line EUnits units = get_units(); float new_pos[Num_Axis]; @@ -727,7 +725,40 @@ namespace Slic3r { void GCodeTimeEstimator::_processG92(const GCodeReader::GCodeLine& line) { - // todo + float lengthsScaleFactor = (get_units() == Inches) ? INCHES_TO_MM : 1.0f; + bool anyFound = false; + + if (line.has('X')) + { + set_axis_position(X, line.get_float('X') * lengthsScaleFactor); + anyFound = true; + } + + if (line.has('Y')) + { + set_axis_position(Y, line.get_float('Y') * lengthsScaleFactor); + anyFound = true; + } + + if (line.has('Z')) + { + set_axis_position(Z, line.get_float('Z') * lengthsScaleFactor); + anyFound = true; + } + + if (line.has('E')) + { + set_axis_position(E, line.get_float('E') * lengthsScaleFactor); + anyFound = true; + } + + if (!anyFound) + { + for (unsigned char a = X; a < Num_Axis; ++a) + { + set_axis_position((EAxis)a, 0.0f); + } + } } void GCodeTimeEstimator::_processM109(const GCodeReader::GCodeLine& line) From 20234c94eee03e7e361a91fafedf5c1a753baed5 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 12 Dec 2017 13:44:52 +0100 Subject: [PATCH 07/33] GCodeTimeEstimator - added retract_acceleration, minimum_travel_feedrate members and process of M201 gcode --- xs/src/libslic3r/GCodeTimeEstimator.cpp | 92 ++++++++++++++++++++----- xs/src/libslic3r/GCodeTimeEstimator.hpp | 19 ++++- 2 files changed, 92 insertions(+), 19 deletions(-) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index b0dd627131..b6caaf79e4 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -6,16 +6,14 @@ static const std::string AXIS_STR = "XYZE"; static const float MMMIN_TO_MMSEC = 1.0f / 60.0f; static const float MILLISEC_TO_SEC = 0.001f; static const float INCHES_TO_MM = 25.4f; -static const float DEFAULT_FEEDRATE = 0.0f; // <<<<<<<<< FIND A PROPER VALUE -static const float DEFAULT_ACCELERATION = 3000.0f; -static const float DEFAULT_AXIS_MAX_FEEDRATE[] = { 600.0f, 600.0f, 40.0f, 25.0f }; -static const float DEFAULT_AXIS_MAX_ACCELERATION[] = { 9000.0f, 9000.0f, 100.0f, 10000.0f }; - -static const float DEFAULT_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.2f, 2.5f }; // from Firmware -//static const float DEFAULT_AXIS_MAX_JERK[] = { 20.0f, 20.0f, 0.4f, 5.0f }; // from Cura - -static const float DEFAULT_MINIMUM_FEEDRATE = 0.0f; // from Firmware -//static const float DEFAULT_MINIMUM_FEEDRATE = 0.01f; // from Cura +static const float DEFAULT_FEEDRATE = 1500.0f; // from Prusa Firmware (Marlin_main.cpp) +static const float DEFAULT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 +static const float DEFAULT_RETRACT_ACCELERATION = 1500.0f; // Prusa Firmware 1_75mm_MK2 +static const float DEFAULT_AXIS_MAX_FEEDRATE[] = { 500.0f, 500.0f, 12.0f, 120.0f }; // Prusa Firmware 1_75mm_MK2 +static const float DEFAULT_AXIS_MAX_ACCELERATION[] = { 9000.0f, 9000.0f, 500.0f, 10000.0f }; // Prusa Firmware 1_75mm_MK2 +static const float DEFAULT_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.2f, 2.5f }; // from Prusa Firmware (Configuration.h) +static const float DEFAULT_MINIMUM_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) +static const float DEFAULT_MINIMUM_TRAVEL_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) #if USE_CURA_JUNCTION_VMAX static const float MINIMUM_PLANNER_SPEED = 0.05f; // from Cura <<<<<<<< WHAT IS THIS ??? @@ -69,6 +67,16 @@ namespace Slic3r { return (length > 0.0f) ? length : ::abs(delta_pos[E]); } + float GCodeTimeEstimator::Block::is_extruder_only_move() const + { + return (delta_pos[X] == 0.0f) && (delta_pos[Y] == 0.0f) && (delta_pos[Z] == 0.0f) && (delta_pos[E] != 0.0f); + } + + float GCodeTimeEstimator::Block::is_travel_move() const + { + return delta_pos[E] == 0.0f; + } + float GCodeTimeEstimator::Block::acceleration_time() const { return trapezoid.acceleration_time(acceleration); @@ -210,9 +218,9 @@ namespace Slic3r { return _state.feedrate; } - void GCodeTimeEstimator::set_acceleration(float acceleration) + void GCodeTimeEstimator::set_acceleration(float acceleration_mm_sec2) { - _state.acceleration = acceleration; + _state.acceleration = acceleration_mm_sec2; } float GCodeTimeEstimator::get_acceleration() const @@ -220,6 +228,16 @@ namespace Slic3r { return _state.acceleration; } + void GCodeTimeEstimator::set_retract_acceleration(float acceleration_mm_sec2) + { + _state.retract_acceleration = acceleration_mm_sec2; + } + + float GCodeTimeEstimator::get_retract_acceleration() const + { + return _state.retract_acceleration; + } + void GCodeTimeEstimator::set_minimum_feedrate(float feedrate_mm_sec) { _state.minimum_feedrate = feedrate_mm_sec; @@ -230,6 +248,16 @@ namespace Slic3r { return _state.minimum_feedrate; } + void GCodeTimeEstimator::set_minimum_travel_feedrate(float feedrate_mm_sec) + { + _state.minimum_travel_feedrate = feedrate_mm_sec; + } + + float GCodeTimeEstimator::get_minimum_travel_feedrate() const + { + return _state.minimum_travel_feedrate; + } + void GCodeTimeEstimator::set_dialect(GCodeTimeEstimator::EDialect dialect) { _state.dialect = dialect; @@ -294,7 +322,9 @@ namespace Slic3r { set_feedrate(DEFAULT_FEEDRATE); set_acceleration(DEFAULT_ACCELERATION); + set_retract_acceleration(DEFAULT_RETRACT_ACCELERATION); set_minimum_feedrate(DEFAULT_MINIMUM_FEEDRATE); + set_minimum_travel_feedrate(DEFAULT_MINIMUM_TRAVEL_FEEDRATE); for (unsigned char a = X; a < Num_Axis; ++a) { @@ -432,6 +462,11 @@ namespace Slic3r { _processM109(line); break; } + case 201: // Set max printing acceleration + { + _processM201(line); + break; + } case 203: // Set maximum feedrate { _processM203(line); @@ -503,7 +538,7 @@ namespace Slic3r { return; // calculates block feedrate - _curr.feedrate = std::max(get_feedrate(), get_minimum_feedrate()); + _curr.feedrate = std::max(get_feedrate(), block.is_travel_move() ? get_minimum_travel_feedrate() : get_minimum_feedrate()); float distance = block.move_length(); float invDistance = 1.0f / distance; @@ -526,7 +561,7 @@ namespace Slic3r { } // calculates block acceleration - float acceleration = get_acceleration(); + float acceleration = block.is_extruder_only_move() ? get_retract_acceleration() : get_acceleration(); for (unsigned char a = X; a < Num_Axis; ++a) { @@ -766,6 +801,26 @@ namespace Slic3r { // todo } + void GCodeTimeEstimator::_processM201(const GCodeReader::GCodeLine& line) + { + EDialect dialect = get_dialect(); + + // see http://reprap.org/wiki/G-code#M201:_Set_max_printing_acceleration + float factor = ((dialect != RepRapFirmware) && (get_units() == GCodeTimeEstimator::Inches)) ? INCHES_TO_MM : 1.0f; + + if (line.has('X')) + set_axis_max_acceleration(X, line.get_float('X') * factor); + + if (line.has('Y')) + set_axis_max_acceleration(Y, line.get_float('Y') * factor); + + if (line.has('Z')) + set_axis_max_acceleration(Z, line.get_float('Z') * factor); + + if (line.has('E')) + set_axis_max_acceleration(E, line.get_float('E') * factor); + } + void GCodeTimeEstimator::_processM203(const GCodeReader::GCodeLine& line) { EDialect dialect = get_dialect(); @@ -793,12 +848,10 @@ namespace Slic3r { void GCodeTimeEstimator::_processM204(const GCodeReader::GCodeLine& line) { if (line.has('S')) - set_acceleration(line.get_float('S')); // <<<< Is this correct ? + set_acceleration(line.get_float('S')); if (line.has('T')) - { - // what to do ? - } + set_retract_acceleration(line.get_float('T')); } void GCodeTimeEstimator::_processM205(const GCodeReader::GCodeLine& line) @@ -821,6 +874,9 @@ namespace Slic3r { if (line.has('S')) set_minimum_feedrate(line.get_float('S')); + + if (line.has('T')) + set_minimum_travel_feedrate(line.get_float('T')); } void GCodeTimeEstimator::_processM566(const GCodeReader::GCodeLine& line) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index 36d66f4355..e173ab4132 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -72,8 +72,10 @@ namespace Slic3r { Axis axis[Num_Axis]; float feedrate; // mm/s float acceleration; // mm/s^2 + float retract_acceleration; // mm/s^2 float additional_time; // s float minimum_feedrate; // mm/s + float minimum_travel_feedrate; // mm/s }; public: @@ -128,6 +130,12 @@ namespace Slic3r { // Returns the length of the move covered by this block, in mm float move_length() const; + // Returns true if this block is a retract/unretract move only + float is_extruder_only_move() const; + + // Returns true if this block is a move with no extrusion + float is_travel_move() const; + // Returns the time spent accelerating toward cruise speed, in seconds float acceleration_time() const; @@ -199,12 +207,18 @@ namespace Slic3r { void set_feedrate(float feedrate_mm_sec); float get_feedrate() const; - void set_acceleration(float acceleration); + void set_acceleration(float acceleration_mm_sec2); float get_acceleration() const; + void set_retract_acceleration(float acceleration_mm_sec2); + float get_retract_acceleration() const; + void set_minimum_feedrate(float feedrate_mm_sec); float get_minimum_feedrate() const; + void set_minimum_travel_feedrate(float feedrate_mm_sec); + float get_minimum_travel_feedrate() const; + void set_dialect(EDialect dialect); EDialect get_dialect() const; @@ -274,6 +288,9 @@ namespace Slic3r { // Set Extruder Temperature and Wait void _processM109(const GCodeReader::GCodeLine& line); + // Set max printing acceleration + void _processM201(const GCodeReader::GCodeLine& line); + // Set maximum feedrate void _processM203(const GCodeReader::GCodeLine& line); From 0fe855cd6d12f067a6f14469c886a5091b421752 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 14 Dec 2017 09:18:28 +0100 Subject: [PATCH 08/33] Time estimate shown in GUI as formatted string / Write to file made by class GCode's private methods --- lib/Slic3r/GUI/Plater.pm | 4 +- xs/src/libslic3r/GCode.cpp | 225 +++++++++++------------- xs/src/libslic3r/GCode.hpp | 11 ++ xs/src/libslic3r/GCodeTimeEstimator.cpp | 22 ++- xs/src/libslic3r/GCodeTimeEstimator.hpp | 5 +- xs/src/libslic3r/Print.hpp | 5 +- xs/xsp/Print.xsp | 15 +- 7 files changed, 146 insertions(+), 141 deletions(-) diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index f687dcec41..c7d42559cc 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -434,7 +434,7 @@ sub new { fil_mm3 => "Used Filament (mm^3)", fil_g => "Used Filament (g)", cost => "Cost", - time => "Estimated printing time (min)", + time => "Estimated printing time", ); while (my $field = shift @info) { my $label = shift @info; @@ -1428,7 +1428,7 @@ sub on_export_completed { $self->{"print_info_cost"}->SetLabel(sprintf("%.2f" , $self->{print}->total_cost)); $self->{"print_info_fil_g"}->SetLabel(sprintf("%.2f" , $self->{print}->total_weight)); $self->{"print_info_fil_mm3"}->SetLabel(sprintf("%.2f" , $self->{print}->total_extruded_volume)); - $self->{"print_info_time"}->SetLabel(sprintf("%.2f" , $self->{print}->estimated_print_time)); + $self->{"print_info_time"}->SetLabel($self->{print}->estimated_print_time); $self->{"print_info_fil_m"}->SetLabel(sprintf("%.2f" , $self->{print}->total_used_filament / 1000)); $self->{"print_info_box_show"}->(1); diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 0e85c55a88..7f8b86adfa 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -267,72 +267,6 @@ std::string WipeTowerIntegration::finalize(GCode &gcodegen) #define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_writer.extruder()->id()) -// Helper class for writing to file with/without time estimation -class Write -{ - static GCodeTimeEstimator* s_time_estimator; - -public: - static void set_time_estimator(GCodeTimeEstimator* time_estimator) - { - s_time_estimator = time_estimator; - } - - static void write(FILE* file, const std::string& what) - { - if (!what.empty()) - { - fwrite(what.data(), 1, what.size(), file); - - if (s_time_estimator != nullptr) - { - const char endLine = '\n'; - std::string::size_type beginPos = 0; - std::string::size_type endPos = what.find_first_of(endLine, beginPos); - while (endPos != std::string::npos) - { - s_time_estimator->add_gcode_line(what.substr(beginPos, endPos - beginPos + 1)); - - beginPos = endPos + 1; - endPos = what.find_first_of(endLine, beginPos); - } - } - } - } -}; - -//std::string Write::s_cache = ""; -GCodeTimeEstimator* Write::s_time_estimator = nullptr; - -inline void write(FILE *file, const std::string &what) -{ - Write::write(file, what); -} - -inline void write_format(FILE* file, const char* format, ...) -{ - char buffer[1024]; - va_list args; - va_start(args, format); - int res = ::vsnprintf(buffer, 1024, format, args); - va_end(args); - - if (res >= 0) - write(file, buffer); -} - -// 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. -inline void writeln(FILE *file, const std::string &what) -{ - if (! what.empty()) { - if (what.back() != '\n') - write_format(file, "%s\n", what.c_str()); - else - write(file, what); - } -} - // Collect pairs of object_layer + support_layer sorted by print_z. // object_layer & support_layer are considered to be on the same print_z, if they are not further than EPSILON. std::vector GCode::collect_layers_to_print(const PrintObject &object) @@ -456,7 +390,6 @@ void GCode::_do_export(Print &print, FILE *file) { // resets time estimator m_time_estimator.reset(); - Write::set_time_estimator(&m_time_estimator); // How many times will be change_layer() called? // change_layer() in turn increments the progress bar status. @@ -541,7 +474,7 @@ void GCode::_do_export(Print &print, FILE *file) m_enable_extrusion_role_markers = (bool)m_pressure_equalizer; // Write information on the generator. - fprintf(file, "; %s\n\n", Slic3r::header_slic3r_generated().c_str()); + _write_format(file, "; %s\n\n", Slic3r::header_slic3r_generated().c_str()); // Write notes (content of the Print Settings tab -> Notes) { std::list lines; @@ -550,10 +483,10 @@ void GCode::_do_export(Print &print, FILE *file) // Remove the trailing '\r' from the '\r\n' sequence. if (! line.empty() && line.back() == '\r') line.pop_back(); - fprintf(file, "; %s\n", line.c_str()); + _write_format(file, "; %s\n", line.c_str()); } if (! lines.empty()) - fprintf(file, "\n"); + _write(file, "\n"); } // Write some terse information on the slicing parameters. { @@ -562,16 +495,17 @@ void GCode::_do_export(Print &print, FILE *file) const double first_layer_height = first_object->config.first_layer_height.get_abs_value(layer_height); for (size_t region_id = 0; region_id < print.regions.size(); ++ region_id) { auto region = print.regions[region_id]; - fprintf(file, "; external perimeters extrusion width = %.2fmm\n", region->flow(frExternalPerimeter, layer_height, false, false, -1., *first_object).width); - fprintf(file, "; perimeters extrusion width = %.2fmm\n", region->flow(frPerimeter, layer_height, false, false, -1., *first_object).width); - fprintf(file, "; infill extrusion width = %.2fmm\n", region->flow(frInfill, layer_height, false, false, -1., *first_object).width); - fprintf(file, "; solid infill extrusion width = %.2fmm\n", region->flow(frSolidInfill, layer_height, false, false, -1., *first_object).width); - fprintf(file, "; top infill extrusion width = %.2fmm\n", region->flow(frTopSolidInfill, layer_height, false, false, -1., *first_object).width); + _write_format(file, "; external perimeters extrusion width = %.2fmm\n", region->flow(frExternalPerimeter, layer_height, false, false, -1., *first_object).width); + _write_format(file, "; perimeters extrusion width = %.2fmm\n", region->flow(frPerimeter, layer_height, false, false, -1., *first_object).width); + _write_format(file, "; infill extrusion width = %.2fmm\n", region->flow(frInfill, layer_height, false, false, -1., *first_object).width); + _write_format(file, "; solid infill extrusion width = %.2fmm\n", region->flow(frSolidInfill, layer_height, false, false, -1., *first_object).width); + _write_format(file, "; top infill extrusion width = %.2fmm\n", region->flow(frTopSolidInfill, layer_height, false, false, -1., *first_object).width); if (print.has_support_material()) - fprintf(file, "; support material extrusion width = %.2fmm\n", support_material_flow(first_object).width); + _write_format(file, "; support material extrusion width = %.2fmm\n", support_material_flow(first_object).width); if (print.config.first_layer_extrusion_width.value > 0) - fprintf(file, "; first layer extrusion width = %.2fmm\n", region->flow(frPerimeter, first_layer_height, false, true, -1., *first_object).width); - fprintf(file, "\n"); + _write_format(file, "; first layer extrusion width = %.2fmm\n", region->flow(frPerimeter, first_layer_height, false, true, -1., *first_object).width); + + _write(file, "\n"); } } @@ -615,7 +549,7 @@ void GCode::_do_export(Print &print, FILE *file) // Disable fan. if (! print.config.cooling.get_at(initial_extruder_id) || print.config.disable_fan_first_layers.get_at(initial_extruder_id)) - write(file, m_writer.set_fan(0, true)); + _write(file, m_writer.set_fan(0, true)); // Let the start-up script prime the 1st printing tool. m_placeholder_parser.set("initial_tool", initial_extruder_id); @@ -632,24 +566,24 @@ void GCode::_do_export(Print &print, FILE *file) // Set extruder(s) temperature before and after start G-code. this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, false); // Write the custom start G-code - writeln(file, start_gcode); + _writeln(file, start_gcode); // Process filament-specific gcode in extruder order. if (print.config.single_extruder_multi_material) { if (has_wipe_tower) { // Wipe tower will control the extruder switching, it will call the start_filament_gcode. } else { // Only initialize the initial extruder. - writeln(file, this->placeholder_parser_process("start_filament_gcode", print.config.start_filament_gcode.values[initial_extruder_id], initial_extruder_id)); + _writeln(file, this->placeholder_parser_process("start_filament_gcode", print.config.start_filament_gcode.values[initial_extruder_id], initial_extruder_id)); } } else { for (const std::string &start_gcode : print.config.start_filament_gcode.values) - writeln(file, this->placeholder_parser_process("start_gcode", start_gcode, (unsigned int)(&start_gcode - &print.config.start_filament_gcode.values.front()))); + _writeln(file, this->placeholder_parser_process("start_gcode", start_gcode, (unsigned int)(&start_gcode - &print.config.start_filament_gcode.values.front()))); } this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, true); // Set other general things. - write(file, this->preamble()); - + _write(file, this->preamble()); + // Initialize a motion planner for object-to-object travel moves. if (print.config.avoid_crossing_perimeters.value) { // Collect outer contours of all objects over all layers. @@ -697,7 +631,7 @@ void GCode::_do_export(Print &print, FILE *file) } // Set initial extruder only after custom start G-code. - write(file, this->set_extruder(initial_extruder_id)); + _write(file, this->set_extruder(initial_extruder_id)); // Do all objects for each layer. if (print.config.complete_objects.value) { @@ -727,8 +661,8 @@ void GCode::_do_export(Print &print, FILE *file) // This happens before Z goes down to layer 0 again, so that no collision happens hopefully. m_enable_cooling_markers = false; // we're not filtering these moves through CoolingBuffer m_avoid_crossing_perimeters.use_external_mp_once = true; - write(file, this->retract()); - write(file, this->travel_to(Point(0, 0), erNone, "move to origin position for next object")); + _write(file, this->retract()); + _write(file, this->travel_to(Point(0, 0), erNone, "move to origin position for next object")); m_enable_cooling_markers = true; // Disable motion planner when traveling to first object point. m_avoid_crossing_perimeters.disable_once = true; @@ -740,7 +674,7 @@ void GCode::_do_export(Print &print, FILE *file) // Set first layer bed and extruder temperatures, don't wait for it to reach the temperature. this->_print_first_layer_bed_temperature(file, print, between_objects_gcode, initial_extruder_id, false); this->_print_first_layer_extruder_temperatures(file, print, between_objects_gcode, initial_extruder_id, false); - writeln(file, between_objects_gcode); + _writeln(file, between_objects_gcode); } // Reset the cooling buffer internal state (the current position, feed rate, accelerations). m_cooling_buffer->reset(); @@ -753,8 +687,9 @@ void GCode::_do_export(Print &print, FILE *file) this->process_layer(file, print, lrs, tool_ordering.tools_for_layer(ltp.print_z()), © - object._shifted_copies.data()); } if (m_pressure_equalizer) - write(file, m_pressure_equalizer->process("", true)); - ++ finished_objects; + _write(file, m_pressure_equalizer->process("", true)); + + ++finished_objects; // Flag indicating whether the nozzle temperature changes from 1st to 2nd layer were performed. // Reset it when starting another object from 1st layer. m_second_layer_things_done = false; @@ -773,7 +708,7 @@ void GCode::_do_export(Print &print, FILE *file) // Prusa Multi-Material wipe tower. if (has_wipe_tower && ! layers_to_print.empty()) { m_wipe_tower.reset(new WipeTowerIntegration(print.config, *print.m_wipe_tower_priming.get(), print.m_wipe_tower_tool_changes, *print.m_wipe_tower_final_purge.get())); - write(file, m_wipe_tower->prime(*this)); + _write(file, m_wipe_tower->prime(*this)); // Verify, whether the print overaps the priming extrusions. BoundingBoxf bbox_print(get_print_extrusions_extents(print)); coordf_t twolayers_printz = ((layers_to_print.size() == 1) ? layers_to_print.front() : layers_to_print[1]).first + EPSILON; @@ -783,16 +718,17 @@ void GCode::_do_export(Print &print, FILE *file) BoundingBoxf bbox_prime(get_wipe_tower_priming_extrusions_extents(print)); bbox_prime.offset(0.5f); // Beep for 500ms, tone 800Hz. Yet better, play some Morse. - write(file, this->retract()); - write(file, "M300 S800 P500\n"); + _write(file, this->retract()); + _write(file, "M300 S800 P500\n"); if (bbox_prime.overlap(bbox_print)) { // Wait for the user to remove the priming extrusions, otherwise they would // get covered by the print. - write(file, "M1 Remove priming towers and click button.\n"); - } else { + _write(file, "M1 Remove priming towers and click button.\n"); + } + else { // Just wait for a bit to let the user check, that the priming succeeded. //TODO Add a message explaining what the printer is waiting for. This needs a firmware fix. - write(file, "M1 S10\n"); + _write(file, "M1 S10\n"); } } // Extrude the layers. @@ -803,26 +739,27 @@ void GCode::_do_export(Print &print, FILE *file) this->process_layer(file, print, layer.second, layer_tools, size_t(-1)); } if (m_pressure_equalizer) - write(file, m_pressure_equalizer->process("", true)); + _write(file, m_pressure_equalizer->process("", true)); if (m_wipe_tower) // Purge the extruder, pull out the active filament. - write(file, m_wipe_tower->finalize(*this)); + _write(file, m_wipe_tower->finalize(*this)); } // Write end commands to file. - write(file, this->retract()); - write(file, m_writer.set_fan(false)); + _write(file, this->retract()); + _write(file, m_writer.set_fan(false)); // Process filament-specific gcode in extruder order. if (print.config.single_extruder_multi_material) { // Process the end_filament_gcode for the active filament only. - writeln(file, this->placeholder_parser_process("end_filament_gcode", print.config.end_filament_gcode.get_at(m_writer.extruder()->id()), m_writer.extruder()->id())); - } else { - for (const std::string &end_gcode : print.config.end_filament_gcode.values) - writeln(file, this->placeholder_parser_process("end_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front()))); + _writeln(file, this->placeholder_parser_process("end_filament_gcode", print.config.end_filament_gcode.get_at(m_writer.extruder()->id()), m_writer.extruder()->id())); } - writeln(file, this->placeholder_parser_process("end_gcode", print.config.end_gcode, m_writer.extruder()->id())); - write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100% - write(file, m_writer.postamble()); + else { + for (const std::string &end_gcode : print.config.end_filament_gcode.values) + _writeln(file, this->placeholder_parser_process("end_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front()))); + } + _writeln(file, this->placeholder_parser_process("end_gcode", print.config.end_gcode, m_writer.extruder()->id())); + _write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100% + _write(file, m_writer.postamble()); // calculates estimated printing time m_time_estimator.calculate_time(); @@ -833,37 +770,37 @@ void GCode::_do_export(Print &print, FILE *file) print.total_extruded_volume = 0.; print.total_weight = 0.; print.total_cost = 0.; - print.estimated_print_time = (double)m_time_estimator.get_time() / 60.0; + print.estimated_print_time = m_time_estimator.get_time_hms(); for (const Extruder &extruder : m_writer.extruders()) { double used_filament = extruder.used_filament(); double extruded_volume = extruder.extruded_volume(); double filament_weight = extruded_volume * extruder.filament_density() * 0.001; double filament_cost = filament_weight * extruder.filament_cost() * 0.001; print.filament_stats.insert(std::pair(extruder.id(), used_filament)); - fprintf(file, "; filament used = %.1lfmm (%.1lfcm3)\n", used_filament, extruded_volume * 0.001); + _write_format(file, "; filament used = %.1lfmm (%.1lfcm3)\n", used_filament, extruded_volume * 0.001); if (filament_weight > 0.) { print.total_weight = print.total_weight + filament_weight; - fprintf(file, "; filament used = %.1lf\n", filament_weight); + _write_format(file, "; filament used = %.1lf\n", filament_weight); if (filament_cost > 0.) { print.total_cost = print.total_cost + filament_cost; - fprintf(file, "; filament cost = %.1lf\n", filament_cost); + _write_format(file, "; filament cost = %.1lf\n", filament_cost); } } - print.total_used_filament = print.total_used_filament + used_filament; + print.total_used_filament = print.total_used_filament + used_filament; print.total_extruded_volume = print.total_extruded_volume + extruded_volume; } - fprintf(file, "; total filament cost = %.1lf\n", print.total_cost); - fprintf(file, "; estimated printing time = %s\n", m_time_estimator.get_time_hms()); + _write_format(file, "; total filament cost = %.1lf\n", print.total_cost); + _write_format(file, "; estimated printing time = %s\n", m_time_estimator.get_time_hms()); // Append full config. - fprintf(file, "\n"); + _write(file, "\n"); { StaticPrintConfig *configs[] = { &print.config, &print.default_object_config, &print.default_region_config }; for (size_t i = 0; i < sizeof(configs) / sizeof(configs[0]); ++ i) { StaticPrintConfig *cfg = configs[i]; for (const std::string &key : cfg->keys()) if (key != "compatible_printers") - fprintf(file, "; %s = %s\n", key.c_str(), cfg->serialize(key).c_str()); + _write_format(file, "; %s = %s\n", key.c_str(), cfg->serialize(key).c_str()); } } } @@ -954,7 +891,7 @@ void GCode::_print_first_layer_bed_temperature(FILE *file, Print &print, const s // the custom start G-code emited these. std::string set_temp_gcode = m_writer.set_bed_temperature(temp, wait); if (! temp_set_by_gcode) - write(file, set_temp_gcode); + _write(file, set_temp_gcode); } // Write 1st layer extruder temperatures into the G-code. @@ -977,15 +914,16 @@ void GCode::_print_first_layer_extruder_temperatures(FILE *file, Print &print, c // Set temperature of the first printing extruder only. int temp = print.config.first_layer_temperature.get_at(first_printing_extruder_id); if (temp > 0) - write(file, m_writer.set_temperature(temp, wait, first_printing_extruder_id)); - } else { + _write(file, m_writer.set_temperature(temp, wait, first_printing_extruder_id)); + } + else { // Set temperatures of all the printing extruders. for (unsigned int tool_id : print.extruders()) { int temp = print.config.first_layer_temperature.get_at(tool_id); if (print.config.ooze_prevention.value) temp += print.config.standby_temperature_delta.value; if (temp > 0) - write(file, m_writer.set_temperature(temp, wait, tool_id)); + _write(file, m_writer.set_temperature(temp, wait, tool_id)); } } } @@ -1419,7 +1357,7 @@ void GCode::process_layer( gcode = m_pressure_equalizer->process(gcode.c_str(), false); // printf("G-code after filter:\n%s\n", out.c_str()); - write(file, gcode); + _write(file, gcode); } void GCode::apply_print_config(const PrintConfig &print_config) @@ -2054,6 +1992,51 @@ std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fill return gcode; } +void GCode::_write(FILE* file, const std::string& what) +{ + if (!what.empty()) + { + // writes string to file + fwrite(what.data(), 1, what.size(), file); + + // updates time estimator and gcode lines vector + const char endLine = '\n'; + std::string::size_type beginPos = 0; + std::string::size_type endPos = what.find_first_of(endLine, beginPos); + while (endPos != std::string::npos) + { + std::string line = what.substr(beginPos, endPos - beginPos + 1); + m_time_estimator.add_gcode_line(line); + + beginPos = endPos + 1; + endPos = what.find_first_of(endLine, beginPos); + } + } +} + +void GCode::_writeln(FILE* file, const std::string& what) +{ + if (!what.empty()) + { + if (what.back() != '\n') + _write_format(file, "%s\n", what.c_str()); + else + _write(file, what); + } +} + +void GCode::_write_format(FILE* file, const char* format, ...) +{ + char buffer[1024]; + va_list args; + va_start(args, format); + int res = ::vsnprintf(buffer, 1024, format, args); + va_end(args); + + if (res >= 0) + _writeln(file, buffer); +} + std::string GCode::_extrude(const ExtrusionPath &path, std::string description, double speed) { std::string gcode; diff --git a/xs/src/libslic3r/GCode.hpp b/xs/src/libslic3r/GCode.hpp index bb40c4ea33..cb8b0027af 100644 --- a/xs/src/libslic3r/GCode.hpp +++ b/xs/src/libslic3r/GCode.hpp @@ -277,6 +277,17 @@ protected: // Time estimator GCodeTimeEstimator m_time_estimator; + // Write a string into a file. + void _write(FILE* file, const std::string& 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(FILE* file, const std::string& what); + + // Formats and write into a file the given data. + void _write_format(FILE* file, const char* format, ...); + std::string _extrude(const ExtrusionPath &path, std::string description = "", double speed = -1); void _print_first_layer_bed_temperature(FILE *file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait); void _print_first_layer_extruder_temperatures(FILE *file, Print &print, const std::string &gcode, unsigned int first_printing_extruder_id, bool wait); diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index b6caaf79e4..6d46524576 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -157,6 +157,16 @@ namespace Slic3r { reset(); } + void GCodeTimeEstimator::calculate_time_from_lines(const std::vector& gcode_lines) + { + for (const std::string& line : gcode_lines) + { + _parser.parse_line(line, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); + } + _calculate_time(); + reset(); + } + void GCodeTimeEstimator::add_gcode_line(const std::string& gcode_line) { _parser.parse_line(gcode_line, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); @@ -354,8 +364,14 @@ namespace Slic3r { int minutes = (int)(timeinsecs / 60.0f); timeinsecs -= (float)minutes * 60.0f; - char buffer[16]; - ::sprintf(buffer, "%02d:%02d:%02d", hours, minutes, (int)timeinsecs); + char buffer[64]; + if (hours > 0) + ::sprintf(buffer, "%dh %dm %ds", hours, minutes, (int)timeinsecs); + else if (minutes > 0) + ::sprintf(buffer, "%dm %ds", minutes, (int)timeinsecs); + else + ::sprintf(buffer, "%ds", (int)timeinsecs); + return buffer; } @@ -393,7 +409,7 @@ namespace Slic3r { { if (line.cmd.length() > 1) { - switch (line.cmd[0]) + switch (::toupper(line.cmd[0])) { case 'G': { diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index e173ab4132..e5bf1e902c 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -184,6 +184,9 @@ namespace Slic3r { // Calculates the time estimate from the gcode contained in the file with the given filename void calculate_time_from_file(const std::string& file); + // Calculates the time estimate from the gcode contained in given list of gcode lines + void calculate_time_from_lines(const std::vector& gcode_lines); + // Adds the given gcode line void add_gcode_line(const std::string& gcode_line); @@ -252,7 +255,7 @@ namespace Slic3r { // Calculates the time estimate void _calculate_time(); - // Processes GCode line + // Processes the given gcode line void _process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line); // Move diff --git a/xs/src/libslic3r/Print.hpp b/xs/src/libslic3r/Print.hpp index bf137924a4..a81406f11e 100644 --- a/xs/src/libslic3r/Print.hpp +++ b/xs/src/libslic3r/Print.hpp @@ -233,14 +233,15 @@ public: PrintRegionPtrs regions; PlaceholderParser placeholder_parser; // TODO: status_cb - double total_used_filament, total_extruded_volume, total_cost, total_weight, estimated_print_time; + std::string estimated_print_time; + double total_used_filament, total_extruded_volume, total_cost, total_weight; std::map filament_stats; PrintState state; // ordered collections of extrusion paths to build skirt loops and brim ExtrusionEntityCollection skirt, brim; - Print() : total_used_filament(0), total_extruded_volume(0), estimated_print_time(0) { restart(); } + Print() : total_used_filament(0), total_extruded_volume(0) { restart(); } ~Print() { clear_objects(); } // methods for handling objects diff --git a/xs/xsp/Print.xsp b/xs/xsp/Print.xsp index 0dff871b71..b415a8f837 100644 --- a/xs/xsp/Print.xsp +++ b/xs/xsp/Print.xsp @@ -153,6 +153,8 @@ _constant() %code%{ RETVAL = &THIS->skirt; %}; Ref brim() %code%{ RETVAL = &THIS->brim; %}; + std::string estimated_print_time() + %code%{ RETVAL = THIS->estimated_print_time; %}; PrintObjectPtrs* objects() %code%{ RETVAL = &THIS->objects; %}; @@ -281,17 +283,6 @@ Print::total_cost(...) } RETVAL = THIS->total_cost; OUTPUT: - RETVAL - -double -Print::estimated_print_time(...) - CODE: - if (items > 1) { - THIS->estimated_print_time = (double)SvNV(ST(1)); - } - RETVAL = THIS->estimated_print_time; - OUTPUT: - RETVAL - + RETVAL %} }; From b2eb522f55d544dbde261b63c3a3c61349f20033 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Tue, 19 Dec 2017 09:29:04 +0100 Subject: [PATCH 09/33] GCodeTimeEstimator - clean up unused code --- xs/src/libslic3r/GCodeTimeEstimator.cpp | 76 +++++-------------------- xs/src/libslic3r/GCodeTimeEstimator.hpp | 23 +++----- 2 files changed, 22 insertions(+), 77 deletions(-) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index 6d46524576..56cff252c8 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -15,10 +15,6 @@ static const float DEFAULT_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.2f, 2.5f }; // fr static const float DEFAULT_MINIMUM_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) static const float DEFAULT_MINIMUM_TRAVEL_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) -#if USE_CURA_JUNCTION_VMAX -static const float MINIMUM_PLANNER_SPEED = 0.05f; // from Cura <<<<<<<< WHAT IS THIS ??? -#endif // USE_CURA_JUNCTION_VMAX - static const float PREVIOUS_FEEDRATE_THRESHOLD = 0.0001f; namespace Slic3r { @@ -389,11 +385,9 @@ namespace Slic3r { void GCodeTimeEstimator::_calculate_time() { -#if ENABLE_BLOCKS_PRE_PROCESSING - forward_pass(); - reverse_pass(); - recalculate_trapezoids(); -#endif // ENABLE_BLOCKS_PRE_PROCESSING + _forward_pass(); + _reverse_pass(); + _recalculate_trapezoids(); _time = get_additional_time(); @@ -601,32 +595,6 @@ namespace Slic3r { block.feedrate.exit = _curr.safe_feedrate; // calculates block entry feedrate -#if USE_CURA_JUNCTION_VMAX - float vmax_junction = _curr.safe_feedrate; - if (!_blocks.empty() && (_prev.feedrate > PREVIOUS_FEEDRATE_THRESHOLD)) - { - vmax_junction = block.feedrate.cruise; - float vmax_junction_factor = 1.0f; - - for (unsigned char a = X; a < Num_Axis; ++a) - { - float abs_delta_axis_feedrate = ::abs(_curr.axis_feedrate[a] - _prev.axis_feedrate[a]); - float axis_max_jerk = get_axis_max_jerk((EAxis)a); - if (abs_delta_axis_feedrate > axis_max_jerk) - vmax_junction_factor = std::min(vmax_junction_factor, axis_max_jerk / abs_delta_axis_feedrate); - } - - // limit vmax to not exceed previous feedrate - vmax_junction = std::min(_prev.feedrate, vmax_junction * vmax_junction_factor); - } - -#if ENABLE_BLOCKS_PRE_PROCESSING - float v_allowable = Block::max_allowable_speed(-acceleration, MINIMUM_PLANNER_SPEED, distance); - block.feedrate.entry = std::min(vmax_junction, v_allowable); -#else - block.feedrate.entry = std::min(vmax_junction, Block::max_allowable_speed(-acceleration, MINIMUM_PLANNER_SPEED, distance)); -#endif // ENABLE_BLOCKS_PRE_PROCESSING -#else float vmax_junction = _curr.safe_feedrate; if (!_blocks.empty() && (_prev.feedrate > PREVIOUS_FEEDRATE_THRESHOLD)) { @@ -688,20 +656,13 @@ namespace Slic3r { vmax_junction = _curr.safe_feedrate; } -#if ENABLE_BLOCKS_PRE_PROCESSING float v_allowable = Block::max_allowable_speed(-acceleration, _curr.safe_feedrate, distance); block.feedrate.entry = std::min(vmax_junction, v_allowable); -#else - block.feedrate.entry = std::min(vmax_junction, Block::max_allowable_speed(-acceleration, _curr.safe_feedrate, distance)); -#endif // ENABLE_BLOCKS_PRE_PROCESSING -#endif // USE_CURA_JUNCTION_VMAX -#if ENABLE_BLOCKS_PRE_PROCESSING block.max_entry_speed = vmax_junction; block.flags.nominal_length = (block.feedrate.cruise <= v_allowable); block.flags.recalculate = true; block.safe_feedrate = _curr.safe_feedrate; -#endif // ENABLE_BLOCKS_PRE_PROCESSING // calculates block trapezoid block.calculate_trapezoid(); @@ -749,7 +710,7 @@ namespace Slic3r { void GCodeTimeEstimator::_processG28(const GCodeReader::GCodeLine& line) { - // todo + // TODO } void GCodeTimeEstimator::_processG90(const GCodeReader::GCodeLine& line) @@ -759,7 +720,7 @@ namespace Slic3r { void GCodeTimeEstimator::_processG91(const GCodeReader::GCodeLine& line) { - // >>>>>>>> THERE ARE DIALECT VARIANTS + // TODO: THERE ARE DIALECT VARIANTS set_positioning_xyz_type(Relative); } @@ -814,7 +775,7 @@ namespace Slic3r { void GCodeTimeEstimator::_processM109(const GCodeReader::GCodeLine& line) { - // todo + // TODO } void GCodeTimeEstimator::_processM201(const GCodeReader::GCodeLine& line) @@ -910,8 +871,7 @@ namespace Slic3r { set_axis_max_jerk(E, line.get_float('E') * MMMIN_TO_MMSEC); } -#if ENABLE_BLOCKS_PRE_PROCESSING - void GCodeTimeEstimator::forward_pass() + void GCodeTimeEstimator::_forward_pass() { Block* block[2] = { nullptr, nullptr }; @@ -919,13 +879,13 @@ namespace Slic3r { { block[0] = block[1]; block[1] = &b; - planner_forward_pass_kernel(block[0], block[1]); + _planner_forward_pass_kernel(block[0], block[1]); } - planner_forward_pass_kernel(block[1], nullptr); + _planner_forward_pass_kernel(block[1], nullptr); } - void GCodeTimeEstimator::reverse_pass() + void GCodeTimeEstimator::_reverse_pass() { Block* block[2] = { nullptr, nullptr }; @@ -933,11 +893,11 @@ namespace Slic3r { { block[1] = block[0]; block[0] = &_blocks[i]; - planner_reverse_pass_kernel(block[0], block[1]); + _planner_reverse_pass_kernel(block[0], block[1]); } } - void GCodeTimeEstimator::planner_forward_pass_kernel(Block* prev, Block* curr) + void GCodeTimeEstimator::_planner_forward_pass_kernel(Block* prev, Block* curr) { if (prev == nullptr) return; @@ -962,7 +922,7 @@ namespace Slic3r { } } - void GCodeTimeEstimator::planner_reverse_pass_kernel(Block* curr, Block* next) + void GCodeTimeEstimator::_planner_reverse_pass_kernel(Block* curr, Block* next) { if ((curr == nullptr) || (next == nullptr)) return; @@ -983,7 +943,7 @@ namespace Slic3r { } } - void GCodeTimeEstimator::recalculate_trapezoids() + void GCodeTimeEstimator::_recalculate_trapezoids() { Block* curr = nullptr; Block* next = nullptr; @@ -1008,20 +968,14 @@ namespace Slic3r { } } - // Last/newest block in buffer. Exit speed is set with MINIMUM_PLANNER_SPEED. Always recalculated. + // Last/newest block in buffer. Always recalculated. if (next != nullptr) { Block block = *next; -#if USE_CURA_JUNCTION_VMAX - block.feedrate.exit = MINIMUM_PLANNER_SPEED; -#else block.feedrate.exit = next->safe_feedrate; -#endif // USE_CURA_JUNCTION_VMAX block.calculate_trapezoid(); next->trapezoid = block.trapezoid; next->flags.recalculate = false; } } -#endif // ENABLE_BLOCKS_PRE_PROCESSING - } diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index e5bf1e902c..894d00ef35 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -4,9 +4,6 @@ #include "libslic3r.h" #include "GCodeReader.hpp" -#define USE_CURA_JUNCTION_VMAX 0 -#define ENABLE_BLOCKS_PRE_PROCESSING 1 - namespace Slic3r { class GCodeTimeEstimator @@ -38,7 +35,7 @@ namespace Slic3r { Num_Dialects }; - enum EPositioningType + enum EPositioningType : unsigned char { Absolute, Relative @@ -107,7 +104,6 @@ namespace Slic3r { static float speed_from_distance(float initial_feedrate, float distance, float acceleration); }; -#if ENABLE_BLOCKS_PRE_PROCESSING struct Flags { bool recalculate; @@ -115,14 +111,11 @@ namespace Slic3r { }; Flags flags; -#endif // ENABLE_BLOCKS_PRE_PROCESSING float delta_pos[Num_Axis]; // mm float acceleration; // mm/s^2 -#if ENABLE_BLOCKS_PRE_PROCESSING float max_entry_speed; // mm/s float safe_feedrate; // mm/s -#endif // ENABLE_BLOCKS_PRE_PROCESSING FeedrateProfile feedrate; Trapezoid trapezoid; @@ -246,7 +239,7 @@ namespace Slic3r { // Returns the estimated time, in seconds float get_time() const; - // Returns the estimated time, in format HH:MM:SS + // Returns the estimated time, in format HHh MMm SSs std::string get_time_hms() const; private: @@ -306,15 +299,13 @@ namespace Slic3r { // Set allowable instantaneous speed change void _processM566(const GCodeReader::GCodeLine& line); -#if ENABLE_BLOCKS_PRE_PROCESSING - void forward_pass(); - void reverse_pass(); + void _forward_pass(); + void _reverse_pass(); - void planner_forward_pass_kernel(Block* prev, Block* curr); - void planner_reverse_pass_kernel(Block* curr, Block* next); + void _planner_forward_pass_kernel(Block* prev, Block* curr); + void _planner_reverse_pass_kernel(Block* curr, Block* next); - void recalculate_trapezoids(); -#endif // ENABLE_BLOCKS_PRE_PROCESSING + void _recalculate_trapezoids(); }; } /* namespace Slic3r */ From a056eadc1e3d5b93a300a954bbeae39e6896bb55 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 29 Dec 2017 21:15:20 +0100 Subject: [PATCH 10/33] Changed perimeter-infill overlap of the bundled Prusa i3 MK3 printer profiles from 35% to 25%. --- resources/profiles/Original Prusa i3 MK2 and MK2S.ini | 8 ++++---- .../Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini | 8 ++++---- resources/profiles/Original Prusa i3 MK2MM.ini | 8 ++++---- resources/profiles/Original Prusa i3 MK3.ini | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/resources/profiles/Original Prusa i3 MK2 and MK2S.ini b/resources/profiles/Original Prusa i3 MK2 and MK2S.ini index b25a6c6718..c70b07b03b 100644 --- a/resources/profiles/Original Prusa i3 MK2 and MK2S.ini +++ b/resources/profiles/Original Prusa i3 MK2 and MK2S.ini @@ -569,7 +569,7 @@ infill_extruder = 1 infill_extrusion_width = 0.45 infill_first = 0 infill_only_where_needed = 0 -infill_overlap = 35% +infill_overlap = 25% infill_speed = 200 interface_shells = 0 layer_height = 0.1 @@ -1099,7 +1099,7 @@ infill_extruder = 1 infill_extrusion_width = 0.45 infill_first = 0 infill_only_where_needed = 0 -infill_overlap = 35% +infill_overlap = 25% infill_speed = 200 interface_shells = 0 layer_height = 0.15 @@ -1735,7 +1735,7 @@ infill_extruder = 1 infill_extrusion_width = 0.45 infill_first = 0 infill_only_where_needed = 0 -infill_overlap = 35% +infill_overlap = 25% infill_speed = 200 interface_shells = 0 layer_height = 0.2 @@ -2265,7 +2265,7 @@ infill_extruder = 1 infill_extrusion_width = 0.7 infill_first = 0 infill_only_where_needed = 0 -infill_overlap = 35% +infill_overlap = 25% infill_speed = 200 interface_shells = 0 layer_height = 0.35 diff --git a/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini b/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini index b9312e5881..fca8758e3d 100644 --- a/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini +++ b/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini @@ -569,7 +569,7 @@ infill_extruder = 1 infill_extrusion_width = 0.45 infill_first = 0 infill_only_where_needed = 0 -infill_overlap = 35% +infill_overlap = 25% infill_speed = 200 interface_shells = 0 layer_height = 0.1 @@ -1099,7 +1099,7 @@ infill_extruder = 1 infill_extrusion_width = 0.45 infill_first = 0 infill_only_where_needed = 0 -infill_overlap = 35% +infill_overlap = 25% infill_speed = 200 interface_shells = 0 layer_height = 0.15 @@ -1735,7 +1735,7 @@ infill_extruder = 1 infill_extrusion_width = 0.45 infill_first = 0 infill_only_where_needed = 0 -infill_overlap = 35% +infill_overlap = 25% infill_speed = 200 interface_shells = 0 layer_height = 0.2 @@ -2265,7 +2265,7 @@ infill_extruder = 1 infill_extrusion_width = 0.7 infill_first = 0 infill_only_where_needed = 0 -infill_overlap = 35% +infill_overlap = 25% infill_speed = 200 interface_shells = 0 layer_height = 0.35 diff --git a/resources/profiles/Original Prusa i3 MK2MM.ini b/resources/profiles/Original Prusa i3 MK2MM.ini index 72daf721d3..abcb90ec41 100644 --- a/resources/profiles/Original Prusa i3 MK2MM.ini +++ b/resources/profiles/Original Prusa i3 MK2MM.ini @@ -569,7 +569,7 @@ infill_extruder = 1 infill_extrusion_width = 0.45 infill_first = 0 infill_only_where_needed = 0 -infill_overlap = 35% +infill_overlap = 25% infill_speed = 200 interface_shells = 0 layer_height = 0.1 @@ -1099,7 +1099,7 @@ infill_extruder = 1 infill_extrusion_width = 0.45 infill_first = 0 infill_only_where_needed = 0 -infill_overlap = 35% +infill_overlap = 25% infill_speed = 200 interface_shells = 0 layer_height = 0.15 @@ -1735,7 +1735,7 @@ infill_extruder = 1 infill_extrusion_width = 0.45 infill_first = 0 infill_only_where_needed = 0 -infill_overlap = 35% +infill_overlap = 25% infill_speed = 200 interface_shells = 0 layer_height = 0.2 @@ -2265,7 +2265,7 @@ infill_extruder = 1 infill_extrusion_width = 0.7 infill_first = 0 infill_only_where_needed = 0 -infill_overlap = 35% +infill_overlap = 25% infill_speed = 200 interface_shells = 0 layer_height = 0.35 diff --git a/resources/profiles/Original Prusa i3 MK3.ini b/resources/profiles/Original Prusa i3 MK3.ini index ea02885a02..228cdb130d 100644 --- a/resources/profiles/Original Prusa i3 MK3.ini +++ b/resources/profiles/Original Prusa i3 MK3.ini @@ -569,7 +569,7 @@ infill_extruder = 1 infill_extrusion_width = 0.45 infill_first = 0 infill_only_where_needed = 0 -infill_overlap = 35% +infill_overlap = 25% infill_speed = 200 interface_shells = 0 layer_height = 0.1 @@ -1099,7 +1099,7 @@ infill_extruder = 1 infill_extrusion_width = 0.45 infill_first = 0 infill_only_where_needed = 0 -infill_overlap = 35% +infill_overlap = 25% infill_speed = 200 interface_shells = 0 layer_height = 0.15 @@ -1735,7 +1735,7 @@ infill_extruder = 1 infill_extrusion_width = 0.45 infill_first = 0 infill_only_where_needed = 0 -infill_overlap = 35% +infill_overlap = 25% infill_speed = 200 interface_shells = 0 layer_height = 0.2 @@ -2265,7 +2265,7 @@ infill_extruder = 1 infill_extrusion_width = 0.7 infill_first = 0 infill_only_where_needed = 0 -infill_overlap = 35% +infill_overlap = 25% infill_speed = 200 interface_shells = 0 layer_height = 0.35 From f58d66fe5ee5efd29ccbbdbac5a5093dbebef192 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 29 Dec 2017 21:17:30 +0100 Subject: [PATCH 11/33] Disabled the object auto centering by default. --- xs/src/slic3r/GUI/AppConfig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xs/src/slic3r/GUI/AppConfig.cpp b/xs/src/slic3r/GUI/AppConfig.cpp index 9378a20942..99339e2f35 100644 --- a/xs/src/slic3r/GUI/AppConfig.cpp +++ b/xs/src/slic3r/GUI/AppConfig.cpp @@ -29,7 +29,7 @@ void AppConfig::set_defaults() { // Reset the empty fields to defaults. if (get("autocenter").empty()) - set("autocenter", "1"); + set("autocenter", "0"); // Disable background processing by default as it is not stable. if (get("background_processing").empty()) set("background_processing", "0"); From 4c35d98d7d8ca342eb4d6dae4f9b332e89ef18c8 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 29 Dec 2017 21:21:26 +0100 Subject: [PATCH 12/33] Bumped up the version number. --- xs/src/libslic3r/libslic3r.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xs/src/libslic3r/libslic3r.h b/xs/src/libslic3r/libslic3r.h index fc61a32527..e4d318e5ef 100644 --- a/xs/src/libslic3r/libslic3r.h +++ b/xs/src/libslic3r/libslic3r.h @@ -14,7 +14,7 @@ #include #define SLIC3R_FORK_NAME "Slic3r Prusa Edition" -#define SLIC3R_VERSION "1.38.5" +#define SLIC3R_VERSION "1.38.6" #define SLIC3R_BUILD "UNKNOWN" typedef long coord_t; From d7998870c7c763ea9ed0334658fc86ee6c60e51c Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 29 Dec 2017 21:39:55 +0100 Subject: [PATCH 13/33] Bumped up the minimum firmware version of the MK3 printers to 3.1.1-RC4 --- .../profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini | 2 +- resources/profiles/Original Prusa i3 MK3.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini b/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini index fca8758e3d..0ee20e8ead 100644 --- a/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini +++ b/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini @@ -3666,7 +3666,7 @@ retract_speed = 35 serial_port = serial_speed = 250000 single_extruder_multi_material = 0 -start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M115 U3.1.1-RC4 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 diff --git a/resources/profiles/Original Prusa i3 MK3.ini b/resources/profiles/Original Prusa i3 MK3.ini index 228cdb130d..e82c7c3cf2 100644 --- a/resources/profiles/Original Prusa i3 MK3.ini +++ b/resources/profiles/Original Prusa i3 MK3.ini @@ -3386,7 +3386,7 @@ retract_speed = 35 serial_port = serial_speed = 250000 single_extruder_multi_material = 0 -start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M115 U3.1.1-RC4 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 From 0de0e4ff4112fc953f2ebd080076e78619a10b31 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 2 Jan 2018 10:34:32 +0100 Subject: [PATCH 14/33] Bumped up the version number. --- xs/src/libslic3r/libslic3r.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xs/src/libslic3r/libslic3r.h b/xs/src/libslic3r/libslic3r.h index e4d318e5ef..1a02605e1b 100644 --- a/xs/src/libslic3r/libslic3r.h +++ b/xs/src/libslic3r/libslic3r.h @@ -14,7 +14,7 @@ #include #define SLIC3R_FORK_NAME "Slic3r Prusa Edition" -#define SLIC3R_VERSION "1.38.6" +#define SLIC3R_VERSION "1.39.0" #define SLIC3R_BUILD "UNKNOWN" typedef long coord_t; From c6bc55e4f9c7683ff1b414018dbe137bd7e21bcf Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 2 Jan 2018 10:36:45 +0100 Subject: [PATCH 15/33] Added a comment on disabling ICU integration when compiling Boost on Linux. --- doc/How_to_build_Slic3r.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/How_to_build_Slic3r.txt b/doc/How_to_build_Slic3r.txt index a1d1129813..22e6f953e2 100644 --- a/doc/How_to_build_Slic3r.txt +++ b/doc/How_to_build_Slic3r.txt @@ -311,5 +311,6 @@ One may save compilation time by compiling just what Slic3r needs. ./bootstrap.sh --with-libraries=system,filesystem,thread,log,locale,regex The -fPIC flag is required on Linux to make the static libraries rellocatable, so they could be embedded into a shared library. -./bjam -a link=static variant=release threading=multi cxxflags=-fPIC cflags=-fPIC +It is important to disable boost.locale.icu=off when compiling the static boost library. +./bjam -a link=static variant=release threading=multi boost.locale.icu=off --with-locale cxxflags=-fPIC cflags=-fPIC To install on Linux to /usr/local/..., run the line above with the additional install keyword and with sudo. From fec05d430baebdcd93607b69750513cc4c606be6 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 2 Jan 2018 11:14:22 +0100 Subject: [PATCH 16/33] Fixed a typo in fprintf --- xs/src/libslic3r/GCode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 6da860d369..47bd6bc077 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -786,7 +786,7 @@ void GCode::_do_export(Print &print, FILE *file) print.total_extruded_volume = print.total_extruded_volume + extruded_volume; } _write_format(file, "; total filament cost = %.1lf\n", print.total_cost); - _write_format(file, "; estimated printing time = %s\n", m_time_estimator.get_time_hms()); + _write_format(file, "; estimated printing time = %s\n", m_time_estimator.get_time_hms().c_str()); // Append full config. _write(file, "\n"); From 0e4ecfaf56ffe276340a4f9ab7f963eee1c56d7b Mon Sep 17 00:00:00 2001 From: bubnikv Date: Tue, 2 Jan 2018 13:29:40 +0100 Subject: [PATCH 17/33] Fix of time estimator (int abs used instead of float abs) --- xs/src/libslic3r/GCodeTimeEstimator.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index 56cff252c8..43b3316761 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -2,6 +2,8 @@ #include #include +#include + static const std::string AXIS_STR = "XYZE"; static const float MMMIN_TO_MMSEC = 1.0f / 60.0f; static const float MILLISEC_TO_SEC = 0.001f; @@ -60,7 +62,7 @@ namespace Slic3r { float GCodeTimeEstimator::Block::move_length() const { float length = ::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z])); - return (length > 0.0f) ? length : ::abs(delta_pos[E]); + return (length > 0.0f) ? length : std::abs(delta_pos[E]); } float GCodeTimeEstimator::Block::is_extruder_only_move() const @@ -165,11 +167,13 @@ namespace Slic3r { void GCodeTimeEstimator::add_gcode_line(const std::string& gcode_line) { + PROFILE_FUNC(); _parser.parse_line(gcode_line, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); } void GCodeTimeEstimator::calculate_time() { + PROFILE_FUNC(); _calculate_time(); _reset(); } @@ -401,6 +405,7 @@ namespace Slic3r { void GCodeTimeEstimator::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line) { + PROFILE_FUNC(); if (line.cmd.length() > 1) { switch (::toupper(line.cmd[0])) @@ -540,7 +545,7 @@ namespace Slic3r { for (unsigned char a = X; a < Num_Axis; ++a) { block.delta_pos[a] = new_pos[a] - get_axis_position((EAxis)a); - max_abs_delta = std::max(max_abs_delta, ::abs(block.delta_pos[a])); + max_abs_delta = std::max(max_abs_delta, std::abs(block.delta_pos[a])); } // is it a move ? @@ -557,7 +562,7 @@ namespace Slic3r { for (unsigned char a = X; a < Num_Axis; ++a) { _curr.axis_feedrate[a] = _curr.feedrate * block.delta_pos[a] * invDistance; - _curr.abs_axis_feedrate[a] = ::abs(_curr.axis_feedrate[a]); + _curr.abs_axis_feedrate[a] = std::abs(_curr.axis_feedrate[a]); if (_curr.abs_axis_feedrate[a] > 0.0f) min_feedrate_factor = std::min(min_feedrate_factor, get_axis_max_feedrate((EAxis)a) / _curr.abs_axis_feedrate[a]); } @@ -576,7 +581,7 @@ namespace Slic3r { for (unsigned char a = X; a < Num_Axis; ++a) { float axis_max_acceleration = get_axis_max_acceleration((EAxis)a); - if (acceleration * ::abs(block.delta_pos[a]) * invDistance > axis_max_acceleration) + if (acceleration * std::abs(block.delta_pos[a]) * invDistance > axis_max_acceleration) acceleration = axis_max_acceleration; } From b292554fd84e95db9c19fb9f8df56b50cbaec9b5 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 3 Jan 2018 17:29:49 +0100 Subject: [PATCH 18/33] Optimized the GCodeReader. Fixed the profiling build. --- xs/CMakeLists.txt | 8 +- xs/src/Shiny/ShinyManager.c | 4 +- xs/src/libslic3r/GCode.cpp | 55 +++--- xs/src/libslic3r/GCode.hpp | 3 +- xs/src/libslic3r/GCode/SpiralVase.cpp | 47 ++--- xs/src/libslic3r/GCode/SpiralVase.hpp | 2 +- xs/src/libslic3r/GCodeReader.cpp | 221 ++++++++++++++++++------ xs/src/libslic3r/GCodeReader.hpp | 122 +++++++++---- xs/src/libslic3r/GCodeTimeEstimator.cpp | 147 +++++++++------- xs/src/libslic3r/GCodeTimeEstimator.hpp | 3 + xs/src/libslic3r/libslic3r.h | 2 +- 11 files changed, 396 insertions(+), 218 deletions(-) diff --git a/xs/CMakeLists.txt b/xs/CMakeLists.txt index 2f8eb14c56..9e23112c5f 100644 --- a/xs/CMakeLists.txt +++ b/xs/CMakeLists.txt @@ -349,8 +349,8 @@ if(APPLE) target_link_libraries(XS "-undefined dynamic_lookup") endif() target_link_libraries(XS libslic3r libslic3r_gui admesh clipper nowide polypartition poly2tri) -if(SLIC3R_DEBUG) - target_link_libraries(Shiny) +if(SLIC3R_PROFILE) + target_link_libraries(XS Shiny) endif() # Add the OpenGL and GLU libraries. @@ -393,7 +393,7 @@ endif () if (SLIC3R_PROFILE) message("Slic3r will be built with a Shiny invasive profiler") - target_compile_definitions(XS PRIVATE -DSLIC3R_PROFILE) + add_definitions(-DSLIC3R_PROFILE) endif () if (SLIC3R_HAS_BROKEN_CROAK) @@ -552,7 +552,7 @@ endif() add_executable(slic3r ${PROJECT_SOURCE_DIR}/src/slic3r.cpp) target_include_directories(XS PRIVATE src src/libslic3r) target_link_libraries(slic3r libslic3r libslic3r_gui admesh ${Boost_LIBRARIES} clipper ${EXPAT_LIBRARIES} ${GLEW_LIBRARIES} polypartition poly2tri ${TBB_LIBRARIES} ${wxWidgets_LIBRARIES}) -if(SLIC3R_DEBUG) +if(SLIC3R_PROFILE) target_link_libraries(Shiny) endif() if (APPLE) diff --git a/xs/src/Shiny/ShinyManager.c b/xs/src/Shiny/ShinyManager.c index 2cb0df4c29..6b28118513 100644 --- a/xs/src/Shiny/ShinyManager.c +++ b/xs/src/Shiny/ShinyManager.c @@ -90,8 +90,8 @@ ShinyNode* _ShinyManager_dummyNodeTable[] = { NULL }; /* primary hash function */ SHINY_INLINE uint32_t hash_value(void* a_pParent, void* a_pZone) { -// uint32_t a = (uint32_t) a_pParent + (uint32_t) a_pZone; - uint32_t a = *reinterpret_cast(&a_pParent) + *reinterpret_cast(&a_pZone); + uint32_t a = (uint32_t) a_pParent + (uint32_t) a_pZone; +// uint32_t a = *reinterpret_cast(&a_pParent) + *reinterpret_cast(&a_pZone); a = (a+0x7ed55d16) + (a<<12); a = (a^0xc761c23c) ^ (a>>19); diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 47bd6bc077..f713015f72 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -20,6 +20,8 @@ #include "SVG.hpp" +#include + #if 0 // Enable debugging and asserts, even in the release build. #define DEBUG @@ -348,6 +350,8 @@ std::vector>> GCode::collec void GCode::do_export(Print *print, const char *path) { + PROFILE_CLEAR(); + // Remove the old g-code if it exists. boost::nowide::remove(path); @@ -384,10 +388,16 @@ void GCode::do_export(Print *print, const char *path) throw std::runtime_error( std::string("Failed to rename the output G-code file from ") + path_tmp + " to " + path + '\n' + "Is " + path_tmp + " locked?" + '\n'); + + // Write the profiler measurements to file + PROFILE_UPDATE(); + PROFILE_OUTPUT(debug_out_path("gcode-export-profile.txt").c_str()); } void GCode::_do_export(Print &print, FILE *file) { + PROFILE_FUNC(); + // resets time estimator m_time_estimator.reset(); @@ -1987,44 +1997,41 @@ std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fill return gcode; } -void GCode::_write(FILE* file, const std::string& what) +void GCode::_write(FILE* file, const char *what, size_t size) { - if (!what.empty()) { + if (size > 0) { // writes string to file - fwrite(what.data(), 1, what.size(), file); + fwrite(what, 1, size, file); // updates time estimator and gcode lines vector - const char endLine = '\n'; - std::string::size_type beginPos = 0; - std::string::size_type endPos = what.find_first_of(endLine, beginPos); - while (endPos != std::string::npos) { - std::string line = what.substr(beginPos, endPos - beginPos + 1); - m_time_estimator.add_gcode_line(line); - beginPos = endPos + 1; - endPos = what.find_first_of(endLine, beginPos); - } + m_time_estimator.add_gcode_block(what); } } -void GCode::_writeln(FILE* file, const std::string& what) +void GCode::_writeln(FILE* file, const std::string &what) { - if (!what.empty()) { - if (what.back() != '\n') - _write_format(file, "%s\n", what.c_str()); - else - _write(file, what); - } + if (! what.empty()) + _write(file, (what.back() == '\n') ? what : (what + '\n')); } void GCode::_write_format(FILE* file, const char* format, ...) { - char buffer[1024]; va_list args; va_start(args, format); - int res = ::vsnprintf(buffer, 1024, format, args); + int buflen = +#ifdef _MSC_VER + _vscprintf(format, args); +#else + vsnprintf(nullptr, 0, format, args); +#endif + char buffer[1024]; + bool buffer_dynamic = buflen > 1024; + char *bufptr = buffer_dynamic ? (char*)malloc(buflen) : buffer; + int res = ::vsnprintf(bufptr, buflen, format, args); + if (res >= 0 && bufptr[0] != 0) + _write(file, bufptr, buflen); va_end(args); - - if (res >= 0) - _writeln(file, buffer); + if (buffer_dynamic) + free(bufptr); } std::string GCode::_extrude(const ExtrusionPath &path, std::string description, double speed) diff --git a/xs/src/libslic3r/GCode.hpp b/xs/src/libslic3r/GCode.hpp index cb8b0027af..5c622ec2d4 100644 --- a/xs/src/libslic3r/GCode.hpp +++ b/xs/src/libslic3r/GCode.hpp @@ -278,7 +278,8 @@ protected: GCodeTimeEstimator m_time_estimator; // Write a string into a file. - void _write(FILE* file, const std::string& what); + void _write(FILE* file, const std::string& what) { this->_write(file, what.c_str(), what.size()); } + void _write(FILE* file, const char *what, size_t size); // Write a string into a file. // Add a newline, if the string does not end with a newline already. diff --git a/xs/src/libslic3r/GCode/SpiralVase.cpp b/xs/src/libslic3r/GCode/SpiralVase.cpp index fd300067fa..892d3b4ccd 100644 --- a/xs/src/libslic3r/GCode/SpiralVase.cpp +++ b/xs/src/libslic3r/GCode/SpiralVase.cpp @@ -4,17 +4,7 @@ namespace Slic3r { -std::string -_format_z(float z) -{ - std::ostringstream ss; - ss << std::fixed << std::setprecision(3) - << z; - return ss.str(); -} - -std::string -SpiralVase::process_layer(const std::string &gcode) +std::string SpiralVase::process_layer(const std::string &gcode) { /* This post-processor relies on several assumptions: - all layers are processed through it, including those that are not supposed @@ -38,16 +28,17 @@ SpiralVase::process_layer(const std::string &gcode) bool set_z = false; { + //FIXME Performance warning: This copies the GCodeConfig of the reader. GCodeReader r = this->_reader; // clone r.parse(gcode, [&total_layer_length, &layer_height, &z, &set_z] - (GCodeReader &, const GCodeReader::GCodeLine &line) { - if (line.cmd == "G1") { - if (line.extruding()) { - total_layer_length += line.dist_XY(); - } else if (line.has('Z')) { - layer_height += line.dist_Z(); + (GCodeReader &reader, const GCodeReader::GCodeLine &line) { + if (line.cmd_is("G1")) { + if (line.extruding(reader)) { + total_layer_length += line.dist_XY(reader); + } else if (line.has(Z)) { + layer_height += line.dist_Z(reader); if (!set_z) { - z = line.new_Z(); + z = line.new_Z(reader); set_z = true; } } @@ -60,22 +51,22 @@ SpiralVase::process_layer(const std::string &gcode) std::string new_gcode; this->_reader.parse(gcode, [&new_gcode, &z, &layer_height, &total_layer_length] - (GCodeReader &, GCodeReader::GCodeLine line) { - if (line.cmd == "G1") { - if (line.has('Z')) { + (GCodeReader &reader, GCodeReader::GCodeLine line) { + if (line.cmd_is("G1")) { + if (line.has_z()) { // If this is the initial Z move of the layer, replace it with a // (redundant) move to the last Z of previous layer. - line.set('Z', _format_z(z)); - new_gcode += line.raw + '\n'; + line.set(reader, Z, z); + new_gcode += line.raw() + '\n'; return; } else { - float dist_XY = line.dist_XY(); + float dist_XY = line.dist_XY(reader); if (dist_XY > 0) { // horizontal move - if (line.extruding()) { + if (line.extruding(reader)) { z += dist_XY * layer_height / total_layer_length; - line.set('Z', _format_z(z)); - new_gcode += line.raw + '\n'; + line.set(reader, Z, z); + new_gcode += line.raw() + '\n'; } return; @@ -87,7 +78,7 @@ SpiralVase::process_layer(const std::string &gcode) } } } - new_gcode += line.raw + '\n'; + new_gcode += line.raw() + '\n'; }); return new_gcode; diff --git a/xs/src/libslic3r/GCode/SpiralVase.hpp b/xs/src/libslic3r/GCode/SpiralVase.hpp index 2346425247..60aa668d89 100644 --- a/xs/src/libslic3r/GCode/SpiralVase.hpp +++ b/xs/src/libslic3r/GCode/SpiralVase.hpp @@ -13,7 +13,7 @@ class SpiralVase { SpiralVase(const PrintConfig &config) : enable(false), _config(&config) { - this->_reader.Z = this->_config->z_offset; + this->_reader.z() = this->_config->z_offset; this->_reader.apply_config(*this->_config); }; std::string process_layer(const std::string &gcode); diff --git a/xs/src/libslic3r/GCodeReader.cpp b/xs/src/libslic3r/GCodeReader.cpp index 453cc9f944..86009fb0fa 100644 --- a/xs/src/libslic3r/GCodeReader.cpp +++ b/xs/src/libslic3r/GCodeReader.cpp @@ -4,6 +4,8 @@ #include #include +#include + namespace Slic3r { void GCodeReader::apply_config(const GCodeConfig &config) @@ -26,58 +28,121 @@ void GCodeReader::parse(const std::string &gcode, callback_t callback) this->parse_line(line, callback); } -void GCodeReader::parse_line(std::string line, callback_t callback) +static inline bool is_whitespace(char c) { - GCodeLine gline(this); - gline.raw = line; - if (this->verbose) - std::cout << line << std::endl; - - // strip comment - { - size_t pos = line.find(';'); - if (pos != std::string::npos) { - gline.comment = line.substr(pos+1); - line.erase(pos); - } - } + return c == ' ' || c == '\t'; +} + +static inline bool is_end_of_line(char c) +{ + return c == '\r' || c == '\n' || c == 0; +} + +static inline bool is_end_of_gcode_line(char c) +{ + return c == ';' || is_end_of_line(c); +} + +static inline bool is_end_of_word(char c) +{ + return is_whitespace(c) || is_end_of_gcode_line(c); +} + +static inline const char* skip_whitespaces(const char *c) +{ + for (; is_whitespace(*c); ++ c); + return c; +} + +static inline const char* skip_word(const char *c) +{ + for (; ! is_end_of_word(*c); ++ c); + return c; +} + +const char* GCodeReader::parse_line_internal(const char *ptr, GCodeLine &gline, std::pair &command) +{ + PROFILE_FUNC(); // command and args + const char *c = ptr; { - std::vector args; - boost::split(args, line, boost::is_any_of(" ")); - - // first one is cmd - gline.cmd = args.front(); - args.erase(args.begin()); - - for (std::string &arg : args) { - if (arg.size() < 2) continue; - gline.args.insert(std::make_pair(arg[0], arg.substr(1))); + PROFILE_BLOCK(command_and_args); + // Skip the whitespaces. + command.first = skip_whitespaces(c); + // Skip the command. + c = command.second = skip_word(command.first); + // Up to the end of line or comment. + while (! is_end_of_gcode_line(*c)) { + // Skip whitespaces. + c = skip_whitespaces(c); + if (is_end_of_gcode_line(*c)) + break; + // Check the name of the axis. + Axis axis = NUM_AXES; + switch (*c) { + case 'X': axis = X; break; + case 'Y': axis = Y; break; + case 'Z': axis = Z; break; + case 'F': axis = F; break; + default: + if (*c == m_extrusion_axis) + axis = E; + break; + } + if (axis != NUM_AXES) { + // Try to parse the numeric value. + char *pend = nullptr; + double v = strtod(++ c, &pend); + if (pend != nullptr && is_end_of_word(*pend)) { + // The axis value has been parsed correctly. + gline.m_axis[int(axis)] = float(v); + gline.m_mask |= 1 << int(axis); + c = pend; + } else + // Skip the rest of the word. + c = skip_word(c); + } else + // Skip the rest of the word. + c = skip_word(c); } } - // convert extrusion axis - if (m_extrusion_axis != 'E') { - const auto it = gline.args.find(m_extrusion_axis); - if (it != gline.args.end()) { - std::swap(gline.args['E'], it->second); - gline.args.erase(it); - } + if (gline.has(E) && m_config.use_relative_e_distances) + m_position[E] = 0; + + // Skip the rest of the line. + for (; ! is_end_of_line(*c); ++ c); + + // Copy the raw string including the comment, without the trailing newlines. + if (c > ptr) { + PROFILE_BLOCK(copy_raw_string); + gline.m_raw.assign(ptr, c); } - - if (gline.has('E') && m_config.use_relative_e_distances) - this->E = 0; - - if (callback) callback(*this, gline); - - // update coordinates - if (gline.cmd == "G0" || gline.cmd == "G1" || gline.cmd == "G92") { - this->X = gline.new_X(); - this->Y = gline.new_Y(); - this->Z = gline.new_Z(); - this->E = gline.new_E(); - this->F = gline.new_F(); + + // Skip the trailing newlines. + if (*c == '\r') + ++ c; + if (*c == '\n') + ++ c; + + if (m_verbose) + std::cout << gline.m_raw << std::endl; + + return c; +} + +void GCodeReader::update_coordinates(GCodeLine &gline, std::pair &command) +{ + PROFILE_FUNC(); + if (*command.first == 'G') { + int cmd_len = int(command.second - command.first); + if ((cmd_len == 2 && (command.first[1] == '0' || command.first[1] == '1')) || + (cmd_len == 3 && command.first[1] == '9' && command.first[2] == '2')) { + for (size_t i = 0; i < NUM_AXES; ++ i) + if (gline.has(Axis(i))) + this->m_position[i] = gline.value(Axis(i)); + } } } @@ -89,22 +154,64 @@ void GCodeReader::parse_file(const std::string &file, callback_t callback) this->parse_line(line, callback); } -void GCodeReader::GCodeLine::set(char arg, std::string value) +bool GCodeReader::GCodeLine::has_value(char axis, float &value) const { - const std::string space(" "); - if (this->has(arg)) { - size_t pos = this->raw.find(space + arg)+2; - size_t end = this->raw.find(' ', pos+1); - this->raw = this->raw.replace(pos, end-pos, value); - } else { - size_t pos = this->raw.find(' '); - if (pos == std::string::npos) { - this->raw += space + arg + value; - } else { - this->raw = this->raw.replace(pos, 0, space + arg + value); + const char *c = m_raw.c_str(); + // Skip the whitespaces. + c = skip_whitespaces(c); + // Skip the command. + c = skip_word(c); + // Up to the end of line or comment. + while (! is_end_of_gcode_line(*c)) { + // Skip whitespaces. + c = skip_whitespaces(c); + if (is_end_of_gcode_line(*c)) + break; + // Check the name of the axis. + if (*c == axis) { + // Try to parse the numeric value. + char *pend = nullptr; + double v = strtod(++ c, &pend); + if (pend != nullptr && is_end_of_word(*pend)) { + // The axis value has been parsed correctly. + value = float(v); + return true; + } } + // Skip the rest of the word. + c = skip_word(c); } - this->args[arg] = value; + return false; +} + +void GCodeReader::GCodeLine::set(const GCodeReader &reader, const Axis axis, const float new_value, const int decimal_digits) +{ + std::ostringstream ss; + ss << std::fixed << std::setprecision(decimal_digits) << new_value; + + char match[3] = " X"; + if (int(axis) < 3) + match[1] += int(axis); + else if (axis == F) + match[1] = 'F'; + else { + assert(axis == E); + match[1] = reader.extrusion_axis(); + } + + if (this->has(axis)) { + size_t pos = m_raw.find(match)+2; + size_t end = m_raw.find(' ', pos+1); + m_raw = m_raw.replace(pos, end-pos, ss.str()); + } else { + size_t pos = m_raw.find(' '); + if (pos == std::string::npos) + m_raw += std::string(match) + ss.str(); + else + m_raw = m_raw.replace(pos, 0, std::string(match) + ss.str()); + } + m_axis[axis] = new_value; + m_mask |= 1 << int(axis); } } diff --git a/xs/src/libslic3r/GCodeReader.hpp b/xs/src/libslic3r/GCodeReader.hpp index 1792d6cdee..4a78255208 100644 --- a/xs/src/libslic3r/GCodeReader.hpp +++ b/xs/src/libslic3r/GCodeReader.hpp @@ -11,54 +11,104 @@ namespace Slic3r { class GCodeReader { -public: +public: class GCodeLine { public: - GCodeReader* reader; - std::string raw; - std::string cmd; - std::string comment; - std::map args; - - GCodeLine(GCodeReader* _reader) : reader(_reader) {}; - - bool has(char arg) const { return this->args.count(arg) > 0; }; - float get_float(char arg) const { return float(atof(this->args.at(arg).c_str())); }; - float new_X() const { return this->has('X') ? float(atof(this->args.at('X').c_str())) : this->reader->X; }; - float new_Y() const { return this->has('Y') ? float(atof(this->args.at('Y').c_str())) : this->reader->Y; }; - float new_Z() const { return this->has('Z') ? float(atof(this->args.at('Z').c_str())) : this->reader->Z; }; - float new_E() const { return this->has('E') ? float(atof(this->args.at('E').c_str())) : this->reader->E; }; - float new_F() const { return this->has('F') ? float(atof(this->args.at('F').c_str())) : this->reader->F; }; - float dist_X() const { return this->new_X() - this->reader->X; }; - float dist_Y() const { return this->new_Y() - this->reader->Y; }; - float dist_Z() const { return this->new_Z() - this->reader->Z; }; - float dist_E() const { return this->new_E() - this->reader->E; }; - float dist_XY() const { - float x = this->dist_X(); - float y = this->dist_Y(); + GCodeLine() { reset(); } + void reset() { m_mask = 0; memset(m_axis, 0, sizeof(m_axis)); m_raw.clear(); } + + const std::string& raw() const { return m_raw; } + const std::string cmd() const + { size_t pos = m_raw.find_first_of(" \t\n;"); return (pos == std::string::npos) ? m_raw : m_raw.substr(0, pos); } + const std::string comment() const + { size_t pos = m_raw.find(';'); return (pos == std::string::npos) ? "" : m_raw.substr(pos + 1); } + + bool has(Axis axis) const { return (m_mask & (1 << int(axis))) != 0; } + float value(Axis axis) const { return m_axis[axis]; } + bool has_value(char axis, float &value) const; + float new_Z(const GCodeReader &reader) const { return this->has(Z) ? this->z() : reader.z(); } + float new_E(const GCodeReader &reader) const { return this->has(E) ? this->e() : reader.e(); } + float new_F(const GCodeReader &reader) const { return this->has(F) ? this->f() : reader.f(); } + float dist_X(const GCodeReader &reader) const { return this->has(X) ? (this->x() - reader.x()) : 0; } + float dist_Y(const GCodeReader &reader) const { return this->has(Y) ? (this->y() - reader.y()) : 0; } + float dist_Z(const GCodeReader &reader) const { return this->has(Z) ? (this->z() - reader.z()) : 0; } + float dist_E(const GCodeReader &reader) const { return this->has(E) ? (this->e() - reader.e()) : 0; } + float dist_XY(const GCodeReader &reader) const { + float x = this->has(X) ? (this->x() - reader.x()) : 0; + float y = this->has(Y) ? (this->y() - reader.y()) : 0; return sqrt(x*x + y*y); - }; - bool extruding() const { return this->cmd == "G1" && this->dist_E() > 0; }; - bool retracting() const { return this->cmd == "G1" && this->dist_E() < 0; }; - bool travel() const { return this->cmd == "G1" && ! this->has('E'); }; - void set(char arg, std::string value); + } + bool cmd_is(const char *cmd_test) const { + int len = strlen(cmd_test); + if (strncmp(m_raw.c_str(), cmd_test, len)) + return false; + char c = m_raw.c_str()[len]; + return c == 0 || c == ' ' || c == '\t' || c == ';'; + } + bool extruding(const GCodeReader &reader) const { return this->cmd_is("G1") && this->dist_E(reader) > 0; } + bool retracting(const GCodeReader &reader) const { return this->cmd_is("G1") && this->dist_E(reader) < 0; } + bool travel() const { return this->cmd_is("G1") && ! this->has(E); } + void set(const GCodeReader &reader, const Axis axis, const float new_value, const int decimal_digits = 3); + + bool has_x() const { return this->has(X); } + bool has_y() const { return this->has(Y); } + bool has_z() const { return this->has(Z); } + bool has_e() const { return this->has(E); } + bool has_f() const { return this->has(F); } + float x() const { return m_axis[X]; } + float y() const { return m_axis[Y]; } + float z() const { return m_axis[Z]; } + float e() const { return m_axis[E]; } + float f() const { return m_axis[F]; } + + private: + std::string m_raw; + float m_axis[NUM_AXES]; + uint32_t m_mask; + friend class GCodeReader; }; + typedef std::function callback_t; - float X, Y, Z, E, F; - bool verbose; - callback_t callback; - - GCodeReader() : X(0), Y(0), Z(0), E(0), F(0), verbose(false), m_extrusion_axis('E') {}; + GCodeReader() : m_verbose(false), m_extrusion_axis('E') { memset(m_position, 0, sizeof(m_position)); } void apply_config(const GCodeConfig &config); void apply_config(const DynamicPrintConfig &config); void parse(const std::string &gcode, callback_t callback); - void parse_line(std::string line, callback_t callback); + template + const char* parse_line(const char *ptr, GCodeLine &gline, Callback &callback) + { + std::pair cmd; + const char *end = parse_line_internal(ptr, gline, cmd); + callback(*this, gline); + update_coordinates(gline, cmd); + return end; + } + template + void parse_line(const std::string &line, Callback &callback) + { GCodeLine gline; this->parse_line(line.c_str(), gline, callback); } void parse_file(const std::string &file, callback_t callback); - + + float& x() { return m_position[X]; } + float x() const { return m_position[X]; } + float& y() { return m_position[Y]; } + float y() const { return m_position[Y]; } + float& z() { return m_position[Z]; } + float z() const { return m_position[Z]; } + float& e() { return m_position[E]; } + float e() const { return m_position[E]; } + float& f() { return m_position[F]; } + float f() const { return m_position[F]; } + + char extrusion_axis() const { return m_extrusion_axis; } + private: + const char* parse_line_internal(const char *ptr, GCodeLine &gline, std::pair &command); + void update_coordinates(GCodeLine &gline, std::pair &command); + GCodeConfig m_config; - char m_extrusion_axis; + char m_extrusion_axis; + float m_position[NUM_AXES]; + bool m_verbose; }; } /* namespace Slic3r */ diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index 43b3316761..31ee30cc1a 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -4,7 +4,6 @@ #include -static const std::string AXIS_STR = "XYZE"; static const float MMMIN_TO_MMSEC = 1.0f / 60.0f; static const float MILLISEC_TO_SEC = 0.001f; static const float INCHES_TO_MM = 25.4f; @@ -159,7 +158,9 @@ namespace Slic3r { { for (const std::string& line : gcode_lines) { - _parser.parse_line(line, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); + _parser.parse_line(line, + [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) + { this->_process_gcode_line(reader, line); }); } _calculate_time(); reset(); @@ -168,7 +169,21 @@ namespace Slic3r { void GCodeTimeEstimator::add_gcode_line(const std::string& gcode_line) { PROFILE_FUNC(); - _parser.parse_line(gcode_line, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); + _parser.parse_line(gcode_line, + [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) + { this->_process_gcode_line(reader, line); }); + } + + void GCodeTimeEstimator::add_gcode_block(const char *ptr) + { + PROFILE_FUNC(); + GCodeReader::GCodeLine gline; + for (; *ptr != 0;) { + gline.reset(); + ptr = _parser.parse_line(ptr, gline, + [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) + { this->_process_gcode_line(reader, line); }); + } } void GCodeTimeEstimator::calculate_time() @@ -406,13 +421,14 @@ namespace Slic3r { void GCodeTimeEstimator::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line) { PROFILE_FUNC(); - if (line.cmd.length() > 1) + std::string cmd = line.cmd(); + if (cmd.length() > 1) { - switch (::toupper(line.cmd[0])) + switch (::toupper(cmd[0])) { case 'G': { - switch (::atoi(&line.cmd[1])) + switch (::atoi(&cmd[1])) { case 1: // Move { @@ -460,7 +476,7 @@ namespace Slic3r { } case 'M': { - switch (::atoi(&line.cmd[1])) + switch (::atoi(&cmd[1])) { case 82: // Set extruder to absolute mode { @@ -514,9 +530,9 @@ namespace Slic3r { float axis_absolute_position_from_G1_line(GCodeTimeEstimator::EAxis axis, const GCodeReader::GCodeLine& lineG1, GCodeTimeEstimator::EUnits units, GCodeTimeEstimator::EPositioningType type, float current_absolute_position) { float lengthsScaleFactor = (units == GCodeTimeEstimator::Inches) ? INCHES_TO_MM : 1.0f; - if (lineG1.has(AXIS_STR[axis])) + if (lineG1.has(Slic3r::Axis(axis))) { - float ret = lineG1.get_float(AXIS_STR[axis]) * lengthsScaleFactor; + float ret = lineG1.value(Slic3r::Axis(axis)) * lengthsScaleFactor; return (type == GCodeTimeEstimator::Absolute) ? ret : current_absolute_position + ret; } else @@ -534,8 +550,8 @@ namespace Slic3r { } // updates feedrate from line, if present - if (line.has('F')) - set_feedrate(std::max(line.get_float('F') * MMMIN_TO_MMSEC, get_minimum_feedrate())); + if (line.has_f()) + set_feedrate(std::max(line.f() * MMMIN_TO_MMSEC, get_minimum_feedrate())); // fills block data Block block; @@ -682,15 +698,16 @@ namespace Slic3r { } // adds block to blocks list - _blocks.push_back(block); + _blocks.emplace_back(block); } void GCodeTimeEstimator::_processG4(const GCodeReader::GCodeLine& line) { EDialect dialect = get_dialect(); - if (line.has('P')) - add_additional_time(line.get_float('P') * MILLISEC_TO_SEC); + float value; + if (line.has_value('P', value)) + add_additional_time(value * MILLISEC_TO_SEC); // see: http://reprap.org/wiki/G-code#G4:_Dwell if ((dialect == Repetier) || @@ -698,8 +715,8 @@ namespace Slic3r { (dialect == Smoothieware) || (dialect == RepRapFirmware)) { - if (line.has('S')) - add_additional_time(line.get_float('S')); + if (line.has_value('S', value)) + add_additional_time(value); } } @@ -745,27 +762,27 @@ namespace Slic3r { float lengthsScaleFactor = (get_units() == Inches) ? INCHES_TO_MM : 1.0f; bool anyFound = false; - if (line.has('X')) + if (line.has_x()) { - set_axis_position(X, line.get_float('X') * lengthsScaleFactor); + set_axis_position(X, line.x() * lengthsScaleFactor); anyFound = true; } - if (line.has('Y')) + if (line.has_y()) { - set_axis_position(Y, line.get_float('Y') * lengthsScaleFactor); + set_axis_position(Y, line.y() * lengthsScaleFactor); anyFound = true; } - if (line.has('Z')) + if (line.has_z()) { - set_axis_position(Z, line.get_float('Z') * lengthsScaleFactor); + set_axis_position(Z, line.z() * lengthsScaleFactor); anyFound = true; } - if (line.has('E')) + if (line.has_e()) { - set_axis_position(E, line.get_float('E') * lengthsScaleFactor); + set_axis_position(E, line.e() * lengthsScaleFactor); anyFound = true; } @@ -790,17 +807,17 @@ namespace Slic3r { // see http://reprap.org/wiki/G-code#M201:_Set_max_printing_acceleration float factor = ((dialect != RepRapFirmware) && (get_units() == GCodeTimeEstimator::Inches)) ? INCHES_TO_MM : 1.0f; - if (line.has('X')) - set_axis_max_acceleration(X, line.get_float('X') * factor); + if (line.has_x()) + set_axis_max_acceleration(X, line.x() * factor); - if (line.has('Y')) - set_axis_max_acceleration(Y, line.get_float('Y') * factor); + if (line.has_y()) + set_axis_max_acceleration(Y, line.y() * factor); - if (line.has('Z')) - set_axis_max_acceleration(Z, line.get_float('Z') * factor); + if (line.has_z()) + set_axis_max_acceleration(Z, line.z() * factor); - if (line.has('E')) - set_axis_max_acceleration(E, line.get_float('E') * factor); + if (line.has_e()) + set_axis_max_acceleration(E, line.e() * factor); } void GCodeTimeEstimator::_processM203(const GCodeReader::GCodeLine& line) @@ -814,66 +831,68 @@ namespace Slic3r { // see http://reprap.org/wiki/G-code#M203:_Set_maximum_feedrate float factor = (dialect == Marlin) ? 1.0f : MMMIN_TO_MMSEC; - if (line.has('X')) - set_axis_max_feedrate(X, line.get_float('X') * factor); + if (line.has_x()) + set_axis_max_feedrate(X, line.x() * factor); - if (line.has('Y')) - set_axis_max_feedrate(Y, line.get_float('Y') * factor); + if (line.has_y()) + set_axis_max_feedrate(Y, line.y() * factor); - if (line.has('Z')) - set_axis_max_feedrate(Z, line.get_float('Z') * factor); + if (line.has_z()) + set_axis_max_feedrate(Z, line.z() * factor); - if (line.has('E')) - set_axis_max_feedrate(E, line.get_float('E') * factor); + if (line.has_e()) + set_axis_max_feedrate(E, line.e() * factor); } void GCodeTimeEstimator::_processM204(const GCodeReader::GCodeLine& line) { - if (line.has('S')) - set_acceleration(line.get_float('S')); + float value; + if (line.has_value('S', value)) + set_acceleration(value); - if (line.has('T')) - set_retract_acceleration(line.get_float('T')); + if (line.has_value('T', value)) + set_retract_acceleration(value); } void GCodeTimeEstimator::_processM205(const GCodeReader::GCodeLine& line) { - if (line.has('X')) + if (line.has_x()) { - float max_jerk = line.get_float('X'); + float max_jerk = line.x(); set_axis_max_jerk(X, max_jerk); set_axis_max_jerk(Y, max_jerk); } - if (line.has('Y')) - set_axis_max_jerk(Y, line.get_float('Y')); + if (line.has_y()) + set_axis_max_jerk(Y, line.y()); - if (line.has('Z')) - set_axis_max_jerk(Z, line.get_float('Z')); + if (line.has_z()) + set_axis_max_jerk(Z, line.z()); - if (line.has('E')) - set_axis_max_jerk(E, line.get_float('E')); + if (line.has_e()) + set_axis_max_jerk(E, line.e()); - if (line.has('S')) - set_minimum_feedrate(line.get_float('S')); + float value; + if (line.has_value('S', value)) + set_minimum_feedrate(value); - if (line.has('T')) - set_minimum_travel_feedrate(line.get_float('T')); + if (line.has_value('T', value)) + set_minimum_travel_feedrate(value); } void GCodeTimeEstimator::_processM566(const GCodeReader::GCodeLine& line) { - if (line.has('X')) - set_axis_max_jerk(X, line.get_float('X') * MMMIN_TO_MMSEC); + if (line.has_x()) + set_axis_max_jerk(X, line.x() * MMMIN_TO_MMSEC); - if (line.has('Y')) - set_axis_max_jerk(Y, line.get_float('Y') * MMMIN_TO_MMSEC); + if (line.has_y()) + set_axis_max_jerk(Y, line.y() * MMMIN_TO_MMSEC); - if (line.has('Z')) - set_axis_max_jerk(Z, line.get_float('Z') * MMMIN_TO_MMSEC); + if (line.has_z()) + set_axis_max_jerk(Z, line.z() * MMMIN_TO_MMSEC); - if (line.has('E')) - set_axis_max_jerk(E, line.get_float('E') * MMMIN_TO_MMSEC); + if (line.has_e()) + set_axis_max_jerk(E, line.e() * MMMIN_TO_MMSEC); } void GCodeTimeEstimator::_forward_pass() diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index 894d00ef35..84c6de5fc0 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -183,6 +183,9 @@ namespace Slic3r { // Adds the given gcode line void add_gcode_line(const std::string& gcode_line); + void add_gcode_block(const char *ptr); + void add_gcode_block(const std::string &str) { this->add_gcode_block(str.c_str()); } + // Calculates the time estimate from the gcode lines added using add_gcode_line() void calculate_time(); diff --git a/xs/src/libslic3r/libslic3r.h b/xs/src/libslic3r/libslic3r.h index 1a02605e1b..7c694b05ef 100644 --- a/xs/src/libslic3r/libslic3r.h +++ b/xs/src/libslic3r/libslic3r.h @@ -102,7 +102,7 @@ inline std::string debug_out_path(const char *name, ...) namespace Slic3r { -enum Axis { X=0, Y, Z }; +enum Axis { X=0, Y, Z, E, F, NUM_AXES }; template inline void append_to(std::vector &dst, const std::vector &src) From 9d98a27b98bf8b27b5d46df14b3f540190364490 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 3 Jan 2018 17:57:37 +0100 Subject: [PATCH 19/33] Fix of compilation on OSX and Linux. By the standard, a temporary value cannot be passed to a reference. --- xs/src/libslic3r/GCodeReader.hpp | 2 +- xs/src/libslic3r/GCodeTimeEstimator.cpp | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/xs/src/libslic3r/GCodeReader.hpp b/xs/src/libslic3r/GCodeReader.hpp index 4a78255208..9076f375df 100644 --- a/xs/src/libslic3r/GCodeReader.hpp +++ b/xs/src/libslic3r/GCodeReader.hpp @@ -84,7 +84,7 @@ public: return end; } template - void parse_line(const std::string &line, Callback &callback) + void parse_line(const std::string &line, Callback callback) { GCodeLine gline; this->parse_line(line.c_str(), gline, callback); } void parse_file(const std::string &file, callback_t callback); diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index 31ee30cc1a..8478eb77de 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -156,12 +156,10 @@ namespace Slic3r { void GCodeTimeEstimator::calculate_time_from_lines(const std::vector& gcode_lines) { + auto action = [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) + { this->_process_gcode_line(reader, line); }; for (const std::string& line : gcode_lines) - { - _parser.parse_line(line, - [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) - { this->_process_gcode_line(reader, line); }); - } + _parser.parse_line(line, action); _calculate_time(); reset(); } @@ -178,11 +176,11 @@ namespace Slic3r { { PROFILE_FUNC(); GCodeReader::GCodeLine gline; + auto action = [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) + { this->_process_gcode_line(reader, line); }; for (; *ptr != 0;) { gline.reset(); - ptr = _parser.parse_line(ptr, gline, - [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) - { this->_process_gcode_line(reader, line); }); + ptr = _parser.parse_line(ptr, gline, action); } } From 998157fc9b6827f52052e7f5c1187f4bec867fe2 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 3 Jan 2018 20:53:39 +0100 Subject: [PATCH 20/33] Fixed an issue with vsprintf and on demand buffer allocation. Improved the GCodeReader to support spaces before the G-code. --- xs/src/libslic3r/GCode.cpp | 28 +++++++++++++++++++--------- xs/src/libslic3r/GCodeReader.cpp | 32 -------------------------------- xs/src/libslic3r/GCodeReader.hpp | 19 +++++++++++++------ 3 files changed, 32 insertions(+), 47 deletions(-) diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index f713015f72..e85b21f80d 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -2017,21 +2017,31 @@ void GCode::_write_format(FILE* file, const char* format, ...) { va_list args; va_start(args, format); - int buflen = -#ifdef _MSC_VER - _vscprintf(format, args); -#else - vsnprintf(nullptr, 0, format, args); -#endif + + int buflen; + { + va_list args2; + va_copy(args2, args); + buflen = + #ifdef _MSC_VER + ::_vscprintf(format, args2) + #else + ::vsnprintf(nullptr, 0, format, args2) + #endif + + 1; + va_end(args2); + } + char buffer[1024]; bool buffer_dynamic = buflen > 1024; char *bufptr = buffer_dynamic ? (char*)malloc(buflen) : buffer; int res = ::vsnprintf(bufptr, buflen, format, args); - if (res >= 0 && bufptr[0] != 0) - _write(file, bufptr, buflen); - va_end(args); + if (res > 0) + _write(file, bufptr, res); if (buffer_dynamic) free(bufptr); + + va_end(args); } std::string GCode::_extrude(const ExtrusionPath &path, std::string description, double speed) diff --git a/xs/src/libslic3r/GCodeReader.cpp b/xs/src/libslic3r/GCodeReader.cpp index 86009fb0fa..d1f56d9158 100644 --- a/xs/src/libslic3r/GCodeReader.cpp +++ b/xs/src/libslic3r/GCodeReader.cpp @@ -28,38 +28,6 @@ void GCodeReader::parse(const std::string &gcode, callback_t callback) this->parse_line(line, callback); } -static inline bool is_whitespace(char c) -{ - return c == ' ' || c == '\t'; -} - -static inline bool is_end_of_line(char c) -{ - return c == '\r' || c == '\n' || c == 0; -} - -static inline bool is_end_of_gcode_line(char c) -{ - return c == ';' || is_end_of_line(c); -} - -static inline bool is_end_of_word(char c) -{ - return is_whitespace(c) || is_end_of_gcode_line(c); -} - -static inline const char* skip_whitespaces(const char *c) -{ - for (; is_whitespace(*c); ++ c); - return c; -} - -static inline const char* skip_word(const char *c) -{ - for (; ! is_end_of_word(*c); ++ c); - return c; -} - const char* GCodeReader::parse_line_internal(const char *ptr, GCodeLine &gline, std::pair &command) { PROFILE_FUNC(); diff --git a/xs/src/libslic3r/GCodeReader.hpp b/xs/src/libslic3r/GCodeReader.hpp index 9076f375df..e546abe0b7 100644 --- a/xs/src/libslic3r/GCodeReader.hpp +++ b/xs/src/libslic3r/GCodeReader.hpp @@ -18,8 +18,10 @@ public: void reset() { m_mask = 0; memset(m_axis, 0, sizeof(m_axis)); m_raw.clear(); } const std::string& raw() const { return m_raw; } - const std::string cmd() const - { size_t pos = m_raw.find_first_of(" \t\n;"); return (pos == std::string::npos) ? m_raw : m_raw.substr(0, pos); } + const std::string cmd() const { + const char *cmd = GCodeReader::skip_whitespaces(m_raw.c_str()); + return std::string(cmd, GCodeReader::skip_word(cmd)); + } const std::string comment() const { size_t pos = m_raw.find(';'); return (pos == std::string::npos) ? "" : m_raw.substr(pos + 1); } @@ -39,11 +41,9 @@ public: return sqrt(x*x + y*y); } bool cmd_is(const char *cmd_test) const { + const char *cmd = GCodeReader::skip_whitespaces(m_raw.c_str()); int len = strlen(cmd_test); - if (strncmp(m_raw.c_str(), cmd_test, len)) - return false; - char c = m_raw.c_str()[len]; - return c == 0 || c == ' ' || c == '\t' || c == ';'; + return strncmp(cmd, cmd_test, len) == 0 && GCodeReader::is_end_of_word(cmd[len]); } bool extruding(const GCodeReader &reader) const { return this->cmd_is("G1") && this->dist_E(reader) > 0; } bool retracting(const GCodeReader &reader) const { return this->cmd_is("G1") && this->dist_E(reader) < 0; } @@ -105,6 +105,13 @@ private: const char* parse_line_internal(const char *ptr, GCodeLine &gline, std::pair &command); void update_coordinates(GCodeLine &gline, std::pair &command); + static bool is_whitespace(char c) { return c == ' ' || c == '\t'; } + static bool is_end_of_line(char c) { return c == '\r' || c == '\n' || c == 0; } + static bool is_end_of_gcode_line(char c) { return c == ';' || is_end_of_line(c); } + static bool is_end_of_word(char c) { return is_whitespace(c) || is_end_of_gcode_line(c); } + static const char* skip_whitespaces(const char *c) { for (; is_whitespace(*c); ++ c); return c; } + static const char* skip_word(const char *c) { for (; ! is_end_of_word(*c); ++ c); return c; } + GCodeConfig m_config; char m_extrusion_axis; float m_position[NUM_AXES]; From 011281df86212cb2adf84f9229a78d31617d250d Mon Sep 17 00:00:00 2001 From: bubnikv Date: Wed, 3 Jan 2018 21:55:32 +0100 Subject: [PATCH 21/33] Fix of the Spiral Vase after the GCodeReader rework. A patch of the GCodeTimeEstimator to avoid crashes. This is not a final fix though. --- xs/src/libslic3r/GCode/SpiralVase.cpp | 6 +++--- xs/src/libslic3r/GCodeReader.cpp | 8 -------- xs/src/libslic3r/GCodeReader.hpp | 18 +++++++++++++++++- xs/src/libslic3r/GCodeTimeEstimator.cpp | 8 ++++++-- 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/xs/src/libslic3r/GCode/SpiralVase.cpp b/xs/src/libslic3r/GCode/SpiralVase.cpp index 892d3b4ccd..8e8ae3075c 100644 --- a/xs/src/libslic3r/GCode/SpiralVase.cpp +++ b/xs/src/libslic3r/GCode/SpiralVase.cpp @@ -17,7 +17,7 @@ std::string SpiralVase::process_layer(const std::string &gcode) // If we're not going to modify G-code, just feed it to the reader // in order to update positions. if (!this->enable) { - this->_reader.parse(gcode, {}); + this->_reader.parse_buffer(gcode); return gcode; } @@ -30,7 +30,7 @@ std::string SpiralVase::process_layer(const std::string &gcode) { //FIXME Performance warning: This copies the GCodeConfig of the reader. GCodeReader r = this->_reader; // clone - r.parse(gcode, [&total_layer_length, &layer_height, &z, &set_z] + r.parse_buffer(gcode, [&total_layer_length, &layer_height, &z, &set_z] (GCodeReader &reader, const GCodeReader::GCodeLine &line) { if (line.cmd_is("G1")) { if (line.extruding(reader)) { @@ -50,7 +50,7 @@ std::string SpiralVase::process_layer(const std::string &gcode) z -= layer_height; std::string new_gcode; - this->_reader.parse(gcode, [&new_gcode, &z, &layer_height, &total_layer_length] + this->_reader.parse_buffer(gcode, [&new_gcode, &z, &layer_height, &total_layer_length] (GCodeReader &reader, GCodeReader::GCodeLine line) { if (line.cmd_is("G1")) { if (line.has_z()) { diff --git a/xs/src/libslic3r/GCodeReader.cpp b/xs/src/libslic3r/GCodeReader.cpp index d1f56d9158..965b7ef8ec 100644 --- a/xs/src/libslic3r/GCodeReader.cpp +++ b/xs/src/libslic3r/GCodeReader.cpp @@ -20,14 +20,6 @@ void GCodeReader::apply_config(const DynamicPrintConfig &config) m_extrusion_axis = m_config.get_extrusion_axis()[0]; } -void GCodeReader::parse(const std::string &gcode, callback_t callback) -{ - std::istringstream ss(gcode); - std::string line; - while (std::getline(ss, line)) - this->parse_line(line, callback); -} - const char* GCodeReader::parse_line_internal(const char *ptr, GCodeLine &gline, std::pair &command) { PROFILE_FUNC(); diff --git a/xs/src/libslic3r/GCodeReader.hpp b/xs/src/libslic3r/GCodeReader.hpp index e546abe0b7..102cbd27ad 100644 --- a/xs/src/libslic3r/GCodeReader.hpp +++ b/xs/src/libslic3r/GCodeReader.hpp @@ -73,7 +73,21 @@ public: GCodeReader() : m_verbose(false), m_extrusion_axis('E') { memset(m_position, 0, sizeof(m_position)); } void apply_config(const GCodeConfig &config); void apply_config(const DynamicPrintConfig &config); - void parse(const std::string &gcode, callback_t callback); + + template + void parse_buffer(const std::string &buffer, Callback callback) + { + const char *ptr = buffer.c_str(); + GCodeLine gline; + while (*ptr != 0) { + gline.reset(); + ptr = this->parse_line(ptr, gline, callback); + } + } + + void parse_buffer(const std::string &buffer) + { this->parse_buffer(buffer, [](GCodeReader&, const GCodeReader::GCodeLine&){}); } + template const char* parse_line(const char *ptr, GCodeLine &gline, Callback &callback) { @@ -83,9 +97,11 @@ public: update_coordinates(gline, cmd); return end; } + template void parse_line(const std::string &line, Callback callback) { GCodeLine gline; this->parse_line(line.c_str(), gline, callback); } + void parse_file(const std::string &file, callback_t callback); float& x() { return m_position[X]; } diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index 8478eb77de..ef0d65d7cf 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -142,7 +142,9 @@ namespace Slic3r { void GCodeTimeEstimator::calculate_time_from_text(const std::string& gcode) { - _parser.parse(gcode, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); + _parser.parse_buffer(gcode, + [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) + { this->_process_gcode_line(reader, line); }); _calculate_time(); reset(); } @@ -921,7 +923,9 @@ namespace Slic3r { void GCodeTimeEstimator::_planner_forward_pass_kernel(Block* prev, Block* curr) { - if (prev == nullptr) + if (prev == nullptr || curr == nullptr) +//FIXME something is fishy here. Review and compare with the firmware. +// if (prev == nullptr) return; // If the previous block is an acceleration block, but it is not long enough to complete the From 3f57e202354068db118d6de406cf6b3bf7b7856d Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 4 Jan 2018 13:00:34 +0100 Subject: [PATCH 22/33] GCodeTimeEstimator: refactoring of forward and reverse passes on blocks --- xs/src/libslic3r/GCodeTimeEstimator.cpp | 106 +++++++++++------------- xs/src/libslic3r/GCodeTimeEstimator.hpp | 4 +- 2 files changed, 49 insertions(+), 61 deletions(-) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index ef0d65d7cf..601fc544f2 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -897,76 +897,64 @@ namespace Slic3r { void GCodeTimeEstimator::_forward_pass() { - Block* block[2] = { nullptr, nullptr }; - - for (Block& b : _blocks) - { - block[0] = block[1]; - block[1] = &b; - _planner_forward_pass_kernel(block[0], block[1]); - } - - _planner_forward_pass_kernel(block[1], nullptr); + if (_blocks.size() > 1) + { + for (unsigned int i = 0; i < (unsigned int)_blocks.size() - 1; ++i) + { + _planner_forward_pass_kernel(_blocks[i], _blocks[i + 1]); + } + } } void GCodeTimeEstimator::_reverse_pass() { - Block* block[2] = { nullptr, nullptr }; - - for (int i = (int)_blocks.size() - 1; i >= 0; --i) - { - block[1] = block[0]; - block[0] = &_blocks[i]; - _planner_reverse_pass_kernel(block[0], block[1]); - } - } - - void GCodeTimeEstimator::_planner_forward_pass_kernel(Block* prev, Block* curr) - { - if (prev == nullptr || curr == nullptr) -//FIXME something is fishy here. Review and compare with the firmware. -// if (prev == nullptr) - return; - - // If the previous block is an acceleration block, but it is not long enough to complete the - // full speed change within the block, we need to adjust the entry speed accordingly. Entry - // speeds have already been reset, maximized, and reverse planned by reverse planner. - // If nominal length is true, max junction speed is guaranteed to be reached. No need to recheck. - if (!prev->flags.nominal_length) - { - if (prev->feedrate.entry < curr->feedrate.entry) + if (_blocks.size() > 1) { - float entry_speed = std::min(curr->feedrate.entry, Block::max_allowable_speed(-prev->acceleration, prev->feedrate.entry, prev->move_length())); - - // Check for junction speed change - if (curr->feedrate.entry != entry_speed) - { - curr->feedrate.entry = entry_speed; - curr->flags.recalculate = true; - } + for (int i = (int)_blocks.size() - 1; i >= 1; --i) + { + _planner_reverse_pass_kernel(_blocks[i - 1], _blocks[i]); + } } - } } - void GCodeTimeEstimator::_planner_reverse_pass_kernel(Block* curr, Block* next) + void GCodeTimeEstimator::_planner_forward_pass_kernel(Block& prev, Block& curr) { - if ((curr == nullptr) || (next == nullptr)) - return; + // If the previous block is an acceleration block, but it is not long enough to complete the + // full speed change within the block, we need to adjust the entry speed accordingly. Entry + // speeds have already been reset, maximized, and reverse planned by reverse planner. + // If nominal length is true, max junction speed is guaranteed to be reached. No need to recheck. + if (!prev.flags.nominal_length) + { + if (prev.feedrate.entry < curr.feedrate.entry) + { + float entry_speed = std::min(curr.feedrate.entry, Block::max_allowable_speed(-prev.acceleration, prev.feedrate.entry, prev.move_length())); - // If entry speed is already at the maximum entry speed, no need to recheck. Block is cruising. - // If not, block in state of acceleration or deceleration. Reset entry speed to maximum and - // check for maximum allowable speed reductions to ensure maximum possible planned speed. - if (curr->feedrate.entry != curr->max_entry_speed) - { - // If nominal length true, max junction speed is guaranteed to be reached. Only compute - // for max allowable speed if block is decelerating and nominal length is false. - if (!curr->flags.nominal_length && (curr->max_entry_speed > next->feedrate.entry)) - curr->feedrate.entry = std::min(curr->max_entry_speed, Block::max_allowable_speed(-curr->acceleration, next->feedrate.entry, curr->move_length())); - else - curr->feedrate.entry = curr->max_entry_speed; + // Check for junction speed change + if (curr.feedrate.entry != entry_speed) + { + curr.feedrate.entry = entry_speed; + curr.flags.recalculate = true; + } + } + } + } - curr->flags.recalculate = true; - } + void GCodeTimeEstimator::_planner_reverse_pass_kernel(Block& curr, Block& next) + { + // If entry speed is already at the maximum entry speed, no need to recheck. Block is cruising. + // If not, block in state of acceleration or deceleration. Reset entry speed to maximum and + // check for maximum allowable speed reductions to ensure maximum possible planned speed. + if (curr.feedrate.entry != curr.max_entry_speed) + { + // If nominal length true, max junction speed is guaranteed to be reached. Only compute + // for max allowable speed if block is decelerating and nominal length is false. + if (!curr.flags.nominal_length && (curr.max_entry_speed > next.feedrate.entry)) + curr.feedrate.entry = std::min(curr.max_entry_speed, Block::max_allowable_speed(-curr.acceleration, next.feedrate.entry, curr.move_length())); + else + curr.feedrate.entry = curr.max_entry_speed; + + curr.flags.recalculate = true; + } } void GCodeTimeEstimator::_recalculate_trapezoids() diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index 84c6de5fc0..1f912b4621 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -305,8 +305,8 @@ namespace Slic3r { void _forward_pass(); void _reverse_pass(); - void _planner_forward_pass_kernel(Block* prev, Block* curr); - void _planner_reverse_pass_kernel(Block* curr, Block* next); + void _planner_forward_pass_kernel(Block& prev, Block& curr); + void _planner_reverse_pass_kernel(Block& curr, Block& next); void _recalculate_trapezoids(); }; From 696d420dc8017422b4a7b5b1c3c1b34f408c887d Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 4 Jan 2018 15:38:06 +0100 Subject: [PATCH 23/33] New feature: Recommended object thin wall thickness hint. --- lib/Slic3r/GUI/Tab.pm | 20 ++++++++++++++++ xs/src/libslic3r/Config.hpp | 2 ++ xs/src/slic3r/GUI/PresetHints.cpp | 38 +++++++++++++++++++++++++++++++ xs/src/slic3r/GUI/PresetHints.hpp | 5 ++++ xs/xsp/GUI_Preset.xsp | 2 ++ 5 files changed, 67 insertions(+) diff --git a/lib/Slic3r/GUI/Tab.pm b/lib/Slic3r/GUI/Tab.pm index 9253cee093..4bd18366bd 100644 --- a/lib/Slic3r/GUI/Tab.pm +++ b/lib/Slic3r/GUI/Tab.pm @@ -586,6 +586,15 @@ sub build { my $optgroup = $page->new_optgroup('Vertical shells'); $optgroup->append_single_option_line('perimeters'); $optgroup->append_single_option_line('spiral_vase'); + my $line = Slic3r::GUI::OptionsGroup::Line->new( + label => '', + full_width => 1, + widget => sub { + my ($parent) = @_; + return $self->{recommended_thin_wall_thickness_description_line} = Slic3r::GUI::OptionsGroup::StaticText->new($parent); + }, + ); + $optgroup->append_line($line); } { my $optgroup = $page->new_optgroup('Horizontal shells'); @@ -1055,9 +1064,20 @@ sub _update { $self->get_field($_)->toggle($have_wipe_tower) for qw(wipe_tower_x wipe_tower_y wipe_tower_width wipe_tower_per_color_wipe); + $self->{recommended_thin_wall_thickness_description_line}->SetText( + Slic3r::GUI::PresetHints::recommended_thin_wall_thickness(wxTheApp->{preset_bundle})); + $self->Thaw; } +# Update on activation to recalculate the estimates if the nozzle diameter changed +# and the extrusion width values were left to zero (automatic, nozzle dependent). +sub OnActivate { + my ($self) = @_; + $self->{recommended_thin_wall_thickness_description_line}->SetText( + Slic3r::GUI::PresetHints::recommended_thin_wall_thickness(wxTheApp->{preset_bundle})); +} + package Slic3r::GUI::Tab::Filament; use base 'Slic3r::GUI::Tab'; use Wx qw(wxTheApp); diff --git a/xs/src/libslic3r/Config.hpp b/xs/src/libslic3r/Config.hpp index c203f3be2c..e04f4df826 100644 --- a/xs/src/libslic3r/Config.hpp +++ b/xs/src/libslic3r/Config.hpp @@ -1161,6 +1161,8 @@ public: const ConfigDef* def() const override { return nullptr; }; template T* opt(const t_config_option_key &opt_key, bool create = false) { return dynamic_cast(this->option(opt_key, create)); } + template const T* opt(const t_config_option_key &opt_key) const + { return dynamic_cast(this->option(opt_key)); } // Overrides ConfigBase::optptr(). Find ando/or create a ConfigOption instance for a given name. ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) override; // Overrides ConfigBase::keys(). Collect names of all configuration values maintained by this configuration store. diff --git a/xs/src/slic3r/GUI/PresetHints.cpp b/xs/src/slic3r/GUI/PresetHints.cpp index 8e23a5c499..36f5743295 100644 --- a/xs/src/slic3r/GUI/PresetHints.cpp +++ b/xs/src/slic3r/GUI/PresetHints.cpp @@ -228,4 +228,42 @@ std::string PresetHints::maximum_volumetric_flow_description(const PresetBundle return out; } +std::string PresetHints::recommended_thin_wall_thickness(const PresetBundle &preset_bundle) +{ + const DynamicPrintConfig &print_config = preset_bundle.prints .get_edited_preset().config; + const DynamicPrintConfig &printer_config = preset_bundle.printers .get_edited_preset().config; + + float layer_height = float(print_config.opt_float("layer_height")); + int num_perimeters = print_config.opt_int("perimeters"); + bool thin_walls = print_config.opt_bool("thin_walls"); + float nozzle_diameter = float(printer_config.opt_float("nozzle_diameter", 0)); + + Flow external_perimeter_flow = Flow::new_from_config_width( + frExternalPerimeter, + *print_config.opt("external_perimeter_extrusion_width"), + nozzle_diameter, layer_height, false); + Flow perimeter_flow = Flow::new_from_config_width( + frPerimeter, + *print_config.opt("perimeter_extrusion_width"), + nozzle_diameter, layer_height, false); + + std::string out; + if (num_perimeters > 0) { + int num_lines = std::min(num_perimeters * 2, 10); + char buf[256]; + sprintf(buf, "Recommended object thin wall thickness for layer height %.2f and ", layer_height); + out += buf; + // Start with the width of two closely spaced + double width = external_perimeter_flow.width + external_perimeter_flow.spacing(); + for (int i = 2; i <= num_lines; thin_walls ? ++ i : i += 2) { + if (i > 2) + out += ", "; + sprintf(buf, "%d lines: %.2lf mm", i, width); + out += buf; + width += perimeter_flow.spacing() * (thin_walls ? 1.f : 2.f); + } + } + return out; +} + }; // namespace Slic3r diff --git a/xs/src/slic3r/GUI/PresetHints.hpp b/xs/src/slic3r/GUI/PresetHints.hpp index 589cc2f98e..39bf0b100b 100644 --- a/xs/src/slic3r/GUI/PresetHints.hpp +++ b/xs/src/slic3r/GUI/PresetHints.hpp @@ -13,11 +13,16 @@ class PresetHints public: // Produce a textual description of the cooling logic of a currently active filament. static std::string cooling_description(const Preset &preset); + // Produce a textual description of the maximum flow achived for the current configuration // (the current printer, filament and print settigns). // This description will be useful for getting a gut feeling for the maximum volumetric // print speed achievable with the extruder. static std::string maximum_volumetric_flow_description(const PresetBundle &preset_bundle); + + // Produce a textual description of a recommended thin wall thickness + // from the provided number of perimeters and the external / internal perimeter width. + static std::string recommended_thin_wall_thickness(const PresetBundle &preset_bundle); }; } // namespace Slic3r diff --git a/xs/xsp/GUI_Preset.xsp b/xs/xsp/GUI_Preset.xsp index 0e6b1504b4..67e1d5fc6d 100644 --- a/xs/xsp/GUI_Preset.xsp +++ b/xs/xsp/GUI_Preset.xsp @@ -184,4 +184,6 @@ PresetCollection::arrayref() %code%{ RETVAL = PresetHints::cooling_description(*preset); %}; static std::string maximum_volumetric_flow_description(PresetBundle *preset) %code%{ RETVAL = PresetHints::maximum_volumetric_flow_description(*preset); %}; + static std::string recommended_thin_wall_thickness(PresetBundle *preset) + %code%{ RETVAL = PresetHints::recommended_thin_wall_thickness(*preset); %}; }; From 69e3ea6581da8377976429adf7f3992ab73774eb Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 5 Jan 2018 09:46:09 +0100 Subject: [PATCH 24/33] GCodeTimeEstimator - simulate firmware st_synchronize() for commands G4, G92, M1 --- xs/src/libslic3r/GCodeTimeEstimator.cpp | 1886 ++++++++++++----------- xs/src/libslic3r/GCodeTimeEstimator.hpp | 610 ++++---- 2 files changed, 1266 insertions(+), 1230 deletions(-) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index 601fc544f2..cc1461db68 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -20,976 +20,1006 @@ static const float PREVIOUS_FEEDRATE_THRESHOLD = 0.0001f; namespace Slic3r { - void GCodeTimeEstimator::Feedrates::reset() - { - feedrate = 0.0f; - safe_feedrate = 0.0f; - ::memset(axis_feedrate, 0, Num_Axis * sizeof(float)); - ::memset(abs_axis_feedrate, 0, Num_Axis * sizeof(float)); - } - - float GCodeTimeEstimator::Block::Trapezoid::acceleration_time(float acceleration) const - { - return acceleration_time_from_distance(feedrate.entry, accelerate_until, acceleration); - } - - float GCodeTimeEstimator::Block::Trapezoid::cruise_time() const - { - return (feedrate.cruise != 0.0f) ? cruise_distance() / feedrate.cruise : 0.0f; - } - - float GCodeTimeEstimator::Block::Trapezoid::deceleration_time(float acceleration) const - { - return acceleration_time_from_distance(feedrate.cruise, (distance - decelerate_after), -acceleration); - } - - float GCodeTimeEstimator::Block::Trapezoid::cruise_distance() const - { - return decelerate_after - accelerate_until; - } - - float GCodeTimeEstimator::Block::Trapezoid::acceleration_time_from_distance(float initial_feedrate, float distance, float acceleration) - { - return (acceleration != 0.0f) ? (speed_from_distance(initial_feedrate, distance, acceleration) - initial_feedrate) / acceleration : 0.0f; - } - - float GCodeTimeEstimator::Block::Trapezoid::speed_from_distance(float initial_feedrate, float distance, float acceleration) - { - return ::sqrt(sqr(initial_feedrate) + 2.0f * acceleration * distance); - } - - float GCodeTimeEstimator::Block::move_length() const - { - float length = ::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z])); - return (length > 0.0f) ? length : std::abs(delta_pos[E]); - } - - float GCodeTimeEstimator::Block::is_extruder_only_move() const - { - return (delta_pos[X] == 0.0f) && (delta_pos[Y] == 0.0f) && (delta_pos[Z] == 0.0f) && (delta_pos[E] != 0.0f); - } - - float GCodeTimeEstimator::Block::is_travel_move() const - { - return delta_pos[E] == 0.0f; - } - - float GCodeTimeEstimator::Block::acceleration_time() const - { - return trapezoid.acceleration_time(acceleration); - } - - float GCodeTimeEstimator::Block::cruise_time() const - { - return trapezoid.cruise_time(); - } - - float GCodeTimeEstimator::Block::deceleration_time() const - { - return trapezoid.deceleration_time(acceleration); - } - - float GCodeTimeEstimator::Block::cruise_distance() const - { - return trapezoid.cruise_distance(); - } - - void GCodeTimeEstimator::Block::calculate_trapezoid() - { - float distance = move_length(); - - trapezoid.distance = distance; - trapezoid.feedrate = feedrate; - - float accelerate_distance = estimate_acceleration_distance(feedrate.entry, feedrate.cruise, acceleration); - float decelerate_distance = estimate_acceleration_distance(feedrate.cruise, feedrate.exit, -acceleration); - float cruise_distance = distance - accelerate_distance - decelerate_distance; - - // Not enough space to reach the nominal feedrate. - // This means no cruising, and we'll have to use intersection_distance() to calculate when to abort acceleration - // and start braking in order to reach the exit_feedrate exactly at the end of this block. - if (cruise_distance < 0.0f) + void GCodeTimeEstimator::Feedrates::reset() { - accelerate_distance = clamp(0.0f, distance, intersection_distance(feedrate.entry, feedrate.exit, acceleration, distance)); - cruise_distance = 0.0f; - trapezoid.feedrate.cruise = Trapezoid::speed_from_distance(feedrate.entry, accelerate_distance, acceleration); + feedrate = 0.0f; + safe_feedrate = 0.0f; + ::memset(axis_feedrate, 0, Num_Axis * sizeof(float)); + ::memset(abs_axis_feedrate, 0, Num_Axis * sizeof(float)); } - trapezoid.accelerate_until = accelerate_distance; - trapezoid.decelerate_after = accelerate_distance + cruise_distance; - } - - float GCodeTimeEstimator::Block::max_allowable_speed(float acceleration, float target_velocity, float distance) - { - return ::sqrt(sqr(target_velocity) - 2.0f * acceleration * distance); - } - - float GCodeTimeEstimator::Block::estimate_acceleration_distance(float initial_rate, float target_rate, float acceleration) - { - return (acceleration == 0.0f) ? 0.0f : (sqr(target_rate) - sqr(initial_rate)) / (2.0f * acceleration); - } - - float GCodeTimeEstimator::Block::intersection_distance(float initial_rate, float final_rate, float acceleration, float distance) - { - return (acceleration == 0.0f) ? 0.0f : (2.0f * acceleration * distance - sqr(initial_rate) + sqr(final_rate)) / (4.0f * acceleration); - } - - GCodeTimeEstimator::GCodeTimeEstimator() - { - reset(); - set_default(); - } - - void GCodeTimeEstimator::calculate_time_from_text(const std::string& gcode) - { - _parser.parse_buffer(gcode, - [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) - { this->_process_gcode_line(reader, line); }); - _calculate_time(); - reset(); - } - - void GCodeTimeEstimator::calculate_time_from_file(const std::string& file) - { - _parser.parse_file(file, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); - _calculate_time(); - reset(); - } - - void GCodeTimeEstimator::calculate_time_from_lines(const std::vector& gcode_lines) - { - auto action = [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) - { this->_process_gcode_line(reader, line); }; - for (const std::string& line : gcode_lines) - _parser.parse_line(line, action); - _calculate_time(); - reset(); - } - - void GCodeTimeEstimator::add_gcode_line(const std::string& gcode_line) - { - PROFILE_FUNC(); - _parser.parse_line(gcode_line, - [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) - { this->_process_gcode_line(reader, line); }); - } - - void GCodeTimeEstimator::add_gcode_block(const char *ptr) - { - PROFILE_FUNC(); - GCodeReader::GCodeLine gline; - auto action = [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) - { this->_process_gcode_line(reader, line); }; - for (; *ptr != 0;) { - gline.reset(); - ptr = _parser.parse_line(ptr, gline, action); - } - } - - void GCodeTimeEstimator::calculate_time() - { - PROFILE_FUNC(); - _calculate_time(); - _reset(); - } - - void GCodeTimeEstimator::set_axis_position(EAxis axis, float position) - { - _state.axis[axis].position = position; - } - - void GCodeTimeEstimator::set_axis_max_feedrate(EAxis axis, float feedrate_mm_sec) - { - _state.axis[axis].max_feedrate = feedrate_mm_sec; - } - - void GCodeTimeEstimator::set_axis_max_acceleration(EAxis axis, float acceleration) - { - _state.axis[axis].max_acceleration = acceleration; - } - - void GCodeTimeEstimator::set_axis_max_jerk(EAxis axis, float jerk) - { - _state.axis[axis].max_jerk = jerk; - } - - float GCodeTimeEstimator::get_axis_position(EAxis axis) const - { - return _state.axis[axis].position; - } - - float GCodeTimeEstimator::get_axis_max_feedrate(EAxis axis) const - { - return _state.axis[axis].max_feedrate; - } - - float GCodeTimeEstimator::get_axis_max_acceleration(EAxis axis) const - { - return _state.axis[axis].max_acceleration; - } - - float GCodeTimeEstimator::get_axis_max_jerk(EAxis axis) const - { - return _state.axis[axis].max_jerk; - } - - void GCodeTimeEstimator::set_feedrate(float feedrate_mm_sec) - { - _state.feedrate = feedrate_mm_sec; - } - - float GCodeTimeEstimator::get_feedrate() const - { - return _state.feedrate; - } - - void GCodeTimeEstimator::set_acceleration(float acceleration_mm_sec2) - { - _state.acceleration = acceleration_mm_sec2; - } - - float GCodeTimeEstimator::get_acceleration() const - { - return _state.acceleration; - } - - void GCodeTimeEstimator::set_retract_acceleration(float acceleration_mm_sec2) - { - _state.retract_acceleration = acceleration_mm_sec2; - } - - float GCodeTimeEstimator::get_retract_acceleration() const - { - return _state.retract_acceleration; - } - - void GCodeTimeEstimator::set_minimum_feedrate(float feedrate_mm_sec) - { - _state.minimum_feedrate = feedrate_mm_sec; - } - - float GCodeTimeEstimator::get_minimum_feedrate() const - { - return _state.minimum_feedrate; - } - - void GCodeTimeEstimator::set_minimum_travel_feedrate(float feedrate_mm_sec) - { - _state.minimum_travel_feedrate = feedrate_mm_sec; - } - - float GCodeTimeEstimator::get_minimum_travel_feedrate() const - { - return _state.minimum_travel_feedrate; - } - - void GCodeTimeEstimator::set_dialect(GCodeTimeEstimator::EDialect dialect) - { - _state.dialect = dialect; - } - - GCodeTimeEstimator::EDialect GCodeTimeEstimator::get_dialect() const - { - return _state.dialect; - } - - void GCodeTimeEstimator::set_units(GCodeTimeEstimator::EUnits units) - { - _state.units = units; - } - - GCodeTimeEstimator::EUnits GCodeTimeEstimator::get_units() const - { - return _state.units; - } - - void GCodeTimeEstimator::set_positioning_xyz_type(GCodeTimeEstimator::EPositioningType type) - { - _state.positioning_xyz_type = type; - } - - GCodeTimeEstimator::EPositioningType GCodeTimeEstimator::get_positioning_xyz_type() const - { - return _state.positioning_xyz_type; - } - - void GCodeTimeEstimator::set_positioning_e_type(GCodeTimeEstimator::EPositioningType type) - { - _state.positioning_e_type = type; - } - - GCodeTimeEstimator::EPositioningType GCodeTimeEstimator::get_positioning_e_type() const - { - return _state.positioning_e_type; - } - - void GCodeTimeEstimator::add_additional_time(float timeSec) - { - _state.additional_time += timeSec; - } - - void GCodeTimeEstimator::set_additional_time(float timeSec) - { - _state.additional_time = timeSec; - } - - float GCodeTimeEstimator::get_additional_time() const - { - return _state.additional_time; - } - - void GCodeTimeEstimator::set_default() - { - set_units(Millimeters); - set_dialect(Unknown); - set_positioning_xyz_type(Absolute); - set_positioning_e_type(Relative); - - set_feedrate(DEFAULT_FEEDRATE); - set_acceleration(DEFAULT_ACCELERATION); - set_retract_acceleration(DEFAULT_RETRACT_ACCELERATION); - set_minimum_feedrate(DEFAULT_MINIMUM_FEEDRATE); - set_minimum_travel_feedrate(DEFAULT_MINIMUM_TRAVEL_FEEDRATE); - - for (unsigned char a = X; a < Num_Axis; ++a) + float GCodeTimeEstimator::Block::Trapezoid::acceleration_time(float acceleration) const { - EAxis axis = (EAxis)a; - set_axis_max_feedrate(axis, DEFAULT_AXIS_MAX_FEEDRATE[a]); - set_axis_max_acceleration(axis, DEFAULT_AXIS_MAX_ACCELERATION[a]); - set_axis_max_jerk(axis, DEFAULT_AXIS_MAX_JERK[a]); + return acceleration_time_from_distance(feedrate.entry, accelerate_until, acceleration); } - } - void GCodeTimeEstimator::reset() - { - _blocks.clear(); - _reset(); - } - - float GCodeTimeEstimator::get_time() const - { - return _time; - } - - std::string GCodeTimeEstimator::get_time_hms() const - { - float timeinsecs = get_time(); - int hours = (int)(timeinsecs / 3600.0f); - timeinsecs -= (float)hours * 3600.0f; - int minutes = (int)(timeinsecs / 60.0f); - timeinsecs -= (float)minutes * 60.0f; - - char buffer[64]; - if (hours > 0) - ::sprintf(buffer, "%dh %dm %ds", hours, minutes, (int)timeinsecs); - else if (minutes > 0) - ::sprintf(buffer, "%dm %ds", minutes, (int)timeinsecs); - else - ::sprintf(buffer, "%ds", (int)timeinsecs); - - return buffer; - } - - void GCodeTimeEstimator::_reset() - { - _curr.reset(); - _prev.reset(); - - set_axis_position(X, 0.0f); - set_axis_position(Y, 0.0f); - set_axis_position(Z, 0.0f); - - set_additional_time(0.0f); - } - - void GCodeTimeEstimator::_calculate_time() - { - _forward_pass(); - _reverse_pass(); - _recalculate_trapezoids(); - - _time = get_additional_time(); - - for (const Block& block : _blocks) + float GCodeTimeEstimator::Block::Trapezoid::cruise_time() const { - _time += block.acceleration_time(); - _time += block.cruise_time(); - _time += block.deceleration_time(); + return (feedrate.cruise != 0.0f) ? cruise_distance() / feedrate.cruise : 0.0f; } - } - void GCodeTimeEstimator::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line) - { - PROFILE_FUNC(); - std::string cmd = line.cmd(); - if (cmd.length() > 1) + float GCodeTimeEstimator::Block::Trapezoid::deceleration_time(float acceleration) const { - switch (::toupper(cmd[0])) - { - case 'G': + return acceleration_time_from_distance(feedrate.cruise, (distance - decelerate_after), -acceleration); + } + + float GCodeTimeEstimator::Block::Trapezoid::cruise_distance() const + { + return decelerate_after - accelerate_until; + } + + float GCodeTimeEstimator::Block::Trapezoid::acceleration_time_from_distance(float initial_feedrate, float distance, float acceleration) + { + return (acceleration != 0.0f) ? (speed_from_distance(initial_feedrate, distance, acceleration) - initial_feedrate) / acceleration : 0.0f; + } + + float GCodeTimeEstimator::Block::Trapezoid::speed_from_distance(float initial_feedrate, float distance, float acceleration) + { + return ::sqrt(sqr(initial_feedrate) + 2.0f * acceleration * distance); + } + + float GCodeTimeEstimator::Block::move_length() const + { + float length = ::sqrt(sqr(delta_pos[X]) + sqr(delta_pos[Y]) + sqr(delta_pos[Z])); + return (length > 0.0f) ? length : std::abs(delta_pos[E]); + } + + float GCodeTimeEstimator::Block::is_extruder_only_move() const + { + return (delta_pos[X] == 0.0f) && (delta_pos[Y] == 0.0f) && (delta_pos[Z] == 0.0f) && (delta_pos[E] != 0.0f); + } + + float GCodeTimeEstimator::Block::is_travel_move() const + { + return delta_pos[E] == 0.0f; + } + + float GCodeTimeEstimator::Block::acceleration_time() const + { + return trapezoid.acceleration_time(acceleration); + } + + float GCodeTimeEstimator::Block::cruise_time() const + { + return trapezoid.cruise_time(); + } + + float GCodeTimeEstimator::Block::deceleration_time() const + { + return trapezoid.deceleration_time(acceleration); + } + + float GCodeTimeEstimator::Block::cruise_distance() const + { + return trapezoid.cruise_distance(); + } + + void GCodeTimeEstimator::Block::calculate_trapezoid() + { + float distance = move_length(); + + trapezoid.distance = distance; + trapezoid.feedrate = feedrate; + + float accelerate_distance = estimate_acceleration_distance(feedrate.entry, feedrate.cruise, acceleration); + float decelerate_distance = estimate_acceleration_distance(feedrate.cruise, feedrate.exit, -acceleration); + float cruise_distance = distance - accelerate_distance - decelerate_distance; + + // Not enough space to reach the nominal feedrate. + // This means no cruising, and we'll have to use intersection_distance() to calculate when to abort acceleration + // and start braking in order to reach the exit_feedrate exactly at the end of this block. + if (cruise_distance < 0.0f) { - switch (::atoi(&cmd[1])) - { - case 1: // Move - { - _processG1(line); - break; - } - case 4: // Dwell - { - _processG4(line); - break; - } - case 20: // Set Units to Inches - { - _processG20(line); - break; - } - case 21: // Set Units to Millimeters - { - _processG21(line); - break; - } - case 28: // Move to Origin (Home) - { - _processG28(line); - break; - } - case 90: // Set to Absolute Positioning - { - _processG90(line); - break; - } - case 91: // Set to Relative Positioning - { - _processG91(line); - break; - } - case 92: // Set Position - { - _processG92(line); - break; - } - } - - break; + accelerate_distance = clamp(0.0f, distance, intersection_distance(feedrate.entry, feedrate.exit, acceleration, distance)); + cruise_distance = 0.0f; + trapezoid.feedrate.cruise = Trapezoid::speed_from_distance(feedrate.entry, accelerate_distance, acceleration); } - case 'M': + + trapezoid.accelerate_until = accelerate_distance; + trapezoid.decelerate_after = accelerate_distance + cruise_distance; + } + + float GCodeTimeEstimator::Block::max_allowable_speed(float acceleration, float target_velocity, float distance) + { + return ::sqrt(sqr(target_velocity) - 2.0f * acceleration * distance); + } + + float GCodeTimeEstimator::Block::estimate_acceleration_distance(float initial_rate, float target_rate, float acceleration) + { + return (acceleration == 0.0f) ? 0.0f : (sqr(target_rate) - sqr(initial_rate)) / (2.0f * acceleration); + } + + float GCodeTimeEstimator::Block::intersection_distance(float initial_rate, float final_rate, float acceleration, float distance) + { + return (acceleration == 0.0f) ? 0.0f : (2.0f * acceleration * distance - sqr(initial_rate) + sqr(final_rate)) / (4.0f * acceleration); + } + + GCodeTimeEstimator::GCodeTimeEstimator() + { + reset(); + set_default(); + } + + void GCodeTimeEstimator::calculate_time_from_text(const std::string& gcode) + { + reset(); + + _parser.parse_buffer(gcode, + [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) + { this->_process_gcode_line(reader, line); }); + + _reset(); + } + + void GCodeTimeEstimator::calculate_time_from_file(const std::string& file) + { + reset(); + + _parser.parse_file(file, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); + _calculate_time(); + + _reset(); + } + + void GCodeTimeEstimator::calculate_time_from_lines(const std::vector& gcode_lines) + { + reset(); + + auto action = [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) + { this->_process_gcode_line(reader, line); }; + for (const std::string& line : gcode_lines) + _parser.parse_line(line, action); + _calculate_time(); + + _reset(); + } + + void GCodeTimeEstimator::add_gcode_line(const std::string& gcode_line) + { + PROFILE_FUNC(); + _parser.parse_line(gcode_line, + [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) + { this->_process_gcode_line(reader, line); }); + } + + void GCodeTimeEstimator::add_gcode_block(const char *ptr) + { + PROFILE_FUNC(); + GCodeReader::GCodeLine gline; + auto action = [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) + { this->_process_gcode_line(reader, line); }; + for (; *ptr != 0;) { + gline.reset(); + ptr = _parser.parse_line(ptr, gline, action); + } + } + + void GCodeTimeEstimator::calculate_time() + { + PROFILE_FUNC(); + _calculate_time(); + _reset(); + } + + void GCodeTimeEstimator::set_axis_position(EAxis axis, float position) + { + _state.axis[axis].position = position; + } + + void GCodeTimeEstimator::set_axis_max_feedrate(EAxis axis, float feedrate_mm_sec) + { + _state.axis[axis].max_feedrate = feedrate_mm_sec; + } + + void GCodeTimeEstimator::set_axis_max_acceleration(EAxis axis, float acceleration) + { + _state.axis[axis].max_acceleration = acceleration; + } + + void GCodeTimeEstimator::set_axis_max_jerk(EAxis axis, float jerk) + { + _state.axis[axis].max_jerk = jerk; + } + + float GCodeTimeEstimator::get_axis_position(EAxis axis) const + { + return _state.axis[axis].position; + } + + float GCodeTimeEstimator::get_axis_max_feedrate(EAxis axis) const + { + return _state.axis[axis].max_feedrate; + } + + float GCodeTimeEstimator::get_axis_max_acceleration(EAxis axis) const + { + return _state.axis[axis].max_acceleration; + } + + float GCodeTimeEstimator::get_axis_max_jerk(EAxis axis) const + { + return _state.axis[axis].max_jerk; + } + + void GCodeTimeEstimator::set_feedrate(float feedrate_mm_sec) + { + _state.feedrate = feedrate_mm_sec; + } + + float GCodeTimeEstimator::get_feedrate() const + { + return _state.feedrate; + } + + void GCodeTimeEstimator::set_acceleration(float acceleration_mm_sec2) + { + _state.acceleration = acceleration_mm_sec2; + } + + float GCodeTimeEstimator::get_acceleration() const + { + return _state.acceleration; + } + + void GCodeTimeEstimator::set_retract_acceleration(float acceleration_mm_sec2) + { + _state.retract_acceleration = acceleration_mm_sec2; + } + + float GCodeTimeEstimator::get_retract_acceleration() const + { + return _state.retract_acceleration; + } + + void GCodeTimeEstimator::set_minimum_feedrate(float feedrate_mm_sec) + { + _state.minimum_feedrate = feedrate_mm_sec; + } + + float GCodeTimeEstimator::get_minimum_feedrate() const + { + return _state.minimum_feedrate; + } + + void GCodeTimeEstimator::set_minimum_travel_feedrate(float feedrate_mm_sec) + { + _state.minimum_travel_feedrate = feedrate_mm_sec; + } + + float GCodeTimeEstimator::get_minimum_travel_feedrate() const + { + return _state.minimum_travel_feedrate; + } + + void GCodeTimeEstimator::set_dialect(GCodeTimeEstimator::EDialect dialect) + { + _state.dialect = dialect; + } + + GCodeTimeEstimator::EDialect GCodeTimeEstimator::get_dialect() const + { + return _state.dialect; + } + + void GCodeTimeEstimator::set_units(GCodeTimeEstimator::EUnits units) + { + _state.units = units; + } + + GCodeTimeEstimator::EUnits GCodeTimeEstimator::get_units() const + { + return _state.units; + } + + void GCodeTimeEstimator::set_positioning_xyz_type(GCodeTimeEstimator::EPositioningType type) + { + _state.positioning_xyz_type = type; + } + + GCodeTimeEstimator::EPositioningType GCodeTimeEstimator::get_positioning_xyz_type() const + { + return _state.positioning_xyz_type; + } + + void GCodeTimeEstimator::set_positioning_e_type(GCodeTimeEstimator::EPositioningType type) + { + _state.positioning_e_type = type; + } + + GCodeTimeEstimator::EPositioningType GCodeTimeEstimator::get_positioning_e_type() const + { + return _state.positioning_e_type; + } + + void GCodeTimeEstimator::add_additional_time(float timeSec) + { + _state.additional_time += timeSec; + } + + void GCodeTimeEstimator::set_additional_time(float timeSec) + { + _state.additional_time = timeSec; + } + + float GCodeTimeEstimator::get_additional_time() const + { + return _state.additional_time; + } + + void GCodeTimeEstimator::set_default() + { + set_units(Millimeters); + set_dialect(Unknown); + set_positioning_xyz_type(Absolute); + set_positioning_e_type(Relative); + + set_feedrate(DEFAULT_FEEDRATE); + set_acceleration(DEFAULT_ACCELERATION); + set_retract_acceleration(DEFAULT_RETRACT_ACCELERATION); + set_minimum_feedrate(DEFAULT_MINIMUM_FEEDRATE); + set_minimum_travel_feedrate(DEFAULT_MINIMUM_TRAVEL_FEEDRATE); + + for (unsigned char a = X; a < Num_Axis; ++a) { - switch (::atoi(&cmd[1])) - { - case 82: // Set extruder to absolute mode - { - _processM82(line); - break; - } - case 83: // Set extruder to relative mode - { - _processM83(line); - break; - } - case 109: // Set Extruder Temperature and Wait - { - _processM109(line); - break; - } - case 201: // Set max printing acceleration - { - _processM201(line); - break; - } - case 203: // Set maximum feedrate - { - _processM203(line); - break; - } - case 204: // Set default acceleration - { - _processM204(line); - break; - } - case 205: // Advanced settings - { - _processM205(line); - break; - } - case 566: // Set allowable instantaneous speed change - { - _processM566(line); - break; - } - } - - break; + EAxis axis = (EAxis)a; + set_axis_max_feedrate(axis, DEFAULT_AXIS_MAX_FEEDRATE[a]); + set_axis_max_acceleration(axis, DEFAULT_AXIS_MAX_ACCELERATION[a]); + set_axis_max_jerk(axis, DEFAULT_AXIS_MAX_JERK[a]); } - } } - } - // Returns the new absolute position on the given axis in dependence of the given parameters - float axis_absolute_position_from_G1_line(GCodeTimeEstimator::EAxis axis, const GCodeReader::GCodeLine& lineG1, GCodeTimeEstimator::EUnits units, GCodeTimeEstimator::EPositioningType type, float current_absolute_position) - { - float lengthsScaleFactor = (units == GCodeTimeEstimator::Inches) ? INCHES_TO_MM : 1.0f; - if (lineG1.has(Slic3r::Axis(axis))) + void GCodeTimeEstimator::reset() { - float ret = lineG1.value(Slic3r::Axis(axis)) * lengthsScaleFactor; - return (type == GCodeTimeEstimator::Absolute) ? ret : current_absolute_position + ret; + _time = 0.0f; + _reset(); } - else - return current_absolute_position; - } - void GCodeTimeEstimator::_processG1(const GCodeReader::GCodeLine& line) - { - // updates axes positions from line - EUnits units = get_units(); - float new_pos[Num_Axis]; - for (unsigned char a = X; a < Num_Axis; ++a) + float GCodeTimeEstimator::get_time() const { - new_pos[a] = axis_absolute_position_from_G1_line((EAxis)a, line, units, (a == E) ? get_positioning_e_type() : get_positioning_xyz_type(), get_axis_position((EAxis)a)); + return _time; } - // updates feedrate from line, if present - if (line.has_f()) - set_feedrate(std::max(line.f() * MMMIN_TO_MMSEC, get_minimum_feedrate())); - - // fills block data - Block block; - - // calculates block movement deltas - float max_abs_delta = 0.0f; - for (unsigned char a = X; a < Num_Axis; ++a) + std::string GCodeTimeEstimator::get_time_hms() const { - block.delta_pos[a] = new_pos[a] - get_axis_position((EAxis)a); - max_abs_delta = std::max(max_abs_delta, std::abs(block.delta_pos[a])); + float timeinsecs = get_time(); + int hours = (int)(timeinsecs / 3600.0f); + timeinsecs -= (float)hours * 3600.0f; + int minutes = (int)(timeinsecs / 60.0f); + timeinsecs -= (float)minutes * 60.0f; + + char buffer[64]; + if (hours > 0) + ::sprintf(buffer, "%dh %dm %ds", hours, minutes, (int)timeinsecs); + else if (minutes > 0) + ::sprintf(buffer, "%dm %ds", minutes, (int)timeinsecs); + else + ::sprintf(buffer, "%ds", (int)timeinsecs); + + return buffer; } - // is it a move ? - if (max_abs_delta == 0.0f) - return; - - // calculates block feedrate - _curr.feedrate = std::max(get_feedrate(), block.is_travel_move() ? get_minimum_travel_feedrate() : get_minimum_feedrate()); - - float distance = block.move_length(); - float invDistance = 1.0f / distance; - - float min_feedrate_factor = 1.0f; - for (unsigned char a = X; a < Num_Axis; ++a) + void GCodeTimeEstimator::_reset() { - _curr.axis_feedrate[a] = _curr.feedrate * block.delta_pos[a] * invDistance; - _curr.abs_axis_feedrate[a] = std::abs(_curr.axis_feedrate[a]); - if (_curr.abs_axis_feedrate[a] > 0.0f) - min_feedrate_factor = std::min(min_feedrate_factor, get_axis_max_feedrate((EAxis)a) / _curr.abs_axis_feedrate[a]); + _blocks.clear(); + + _curr.reset(); + _prev.reset(); + + set_axis_position(X, 0.0f); + set_axis_position(Y, 0.0f); + set_axis_position(Z, 0.0f); + + set_additional_time(0.0f); } + + void GCodeTimeEstimator::_calculate_time() + { + _forward_pass(); + _reverse_pass(); + _recalculate_trapezoids(); + + _time += get_additional_time(); + + for (const Block& block : _blocks) + { + _time += block.acceleration_time(); + _time += block.cruise_time(); + _time += block.deceleration_time(); + } + } + + void GCodeTimeEstimator::_process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line) + { + PROFILE_FUNC(); + std::string cmd = line.cmd(); + if (cmd.length() > 1) + { + switch (::toupper(cmd[0])) + { + case 'G': + { + switch (::atoi(&cmd[1])) + { + case 1: // Move + { + _processG1(line); + break; + } + case 4: // Dwell + { + _processG4(line); + break; + } + case 20: // Set Units to Inches + { + _processG20(line); + break; + } + case 21: // Set Units to Millimeters + { + _processG21(line); + break; + } + case 28: // Move to Origin (Home) + { + _processG28(line); + break; + } + case 90: // Set to Absolute Positioning + { + _processG90(line); + break; + } + case 91: // Set to Relative Positioning + { + _processG91(line); + break; + } + case 92: // Set Position + { + _processG92(line); + break; + } + } + + break; + } + case 'M': + { + switch (::atoi(&cmd[1])) + { + case 1: // Sleep or Conditional stop + { + _processM1(line); + break; + } + case 82: // Set extruder to absolute mode + { + _processM82(line); + break; + } + case 83: // Set extruder to relative mode + { + _processM83(line); + break; + } + case 109: // Set Extruder Temperature and Wait + { + _processM109(line); + break; + } + case 201: // Set max printing acceleration + { + _processM201(line); + break; + } + case 203: // Set maximum feedrate + { + _processM203(line); + break; + } + case 204: // Set default acceleration + { + _processM204(line); + break; + } + case 205: // Advanced settings + { + _processM205(line); + break; + } + case 566: // Set allowable instantaneous speed change + { + _processM566(line); + break; + } + } + + break; + } + } + } + } + + // Returns the new absolute position on the given axis in dependence of the given parameters + float axis_absolute_position_from_G1_line(GCodeTimeEstimator::EAxis axis, const GCodeReader::GCodeLine& lineG1, GCodeTimeEstimator::EUnits units, GCodeTimeEstimator::EPositioningType type, float current_absolute_position) + { + float lengthsScaleFactor = (units == GCodeTimeEstimator::Inches) ? INCHES_TO_MM : 1.0f; + if (lineG1.has(Slic3r::Axis(axis))) + { + float ret = lineG1.value(Slic3r::Axis(axis)) * lengthsScaleFactor; + return (type == GCodeTimeEstimator::Absolute) ? ret : current_absolute_position + ret; + } + else + return current_absolute_position; + } + + void GCodeTimeEstimator::_processG1(const GCodeReader::GCodeLine& line) + { + // updates axes positions from line + EUnits units = get_units(); + float new_pos[Num_Axis]; + for (unsigned char a = X; a < Num_Axis; ++a) + { + new_pos[a] = axis_absolute_position_from_G1_line((EAxis)a, line, units, (a == E) ? get_positioning_e_type() : get_positioning_xyz_type(), get_axis_position((EAxis)a)); + } + + // updates feedrate from line, if present + if (line.has_f()) + set_feedrate(std::max(line.f() * MMMIN_TO_MMSEC, get_minimum_feedrate())); + + // fills block data + Block block; + + // calculates block movement deltas + float max_abs_delta = 0.0f; + for (unsigned char a = X; a < Num_Axis; ++a) + { + block.delta_pos[a] = new_pos[a] - get_axis_position((EAxis)a); + max_abs_delta = std::max(max_abs_delta, std::abs(block.delta_pos[a])); + } + + // is it a move ? + if (max_abs_delta == 0.0f) + return; + + // calculates block feedrate + _curr.feedrate = std::max(get_feedrate(), block.is_travel_move() ? get_minimum_travel_feedrate() : get_minimum_feedrate()); + + float distance = block.move_length(); + float invDistance = 1.0f / distance; + + float min_feedrate_factor = 1.0f; + for (unsigned char a = X; a < Num_Axis; ++a) + { + _curr.axis_feedrate[a] = _curr.feedrate * block.delta_pos[a] * invDistance; + _curr.abs_axis_feedrate[a] = std::abs(_curr.axis_feedrate[a]); + if (_curr.abs_axis_feedrate[a] > 0.0f) + min_feedrate_factor = std::min(min_feedrate_factor, get_axis_max_feedrate((EAxis)a) / _curr.abs_axis_feedrate[a]); + } - block.feedrate.cruise = min_feedrate_factor * _curr.feedrate; + block.feedrate.cruise = min_feedrate_factor * _curr.feedrate; - for (unsigned char a = X; a < Num_Axis; ++a) - { - _curr.axis_feedrate[a] *= min_feedrate_factor; - _curr.abs_axis_feedrate[a] *= min_feedrate_factor; - } - - // calculates block acceleration - float acceleration = block.is_extruder_only_move() ? get_retract_acceleration() : get_acceleration(); - - for (unsigned char a = X; a < Num_Axis; ++a) - { - float axis_max_acceleration = get_axis_max_acceleration((EAxis)a); - if (acceleration * std::abs(block.delta_pos[a]) * invDistance > axis_max_acceleration) - acceleration = axis_max_acceleration; - } - - block.acceleration = acceleration; - - // calculates block exit feedrate - _curr.safe_feedrate = block.feedrate.cruise; - - for (unsigned char a = X; a < Num_Axis; ++a) - { - float axis_max_jerk = get_axis_max_jerk((EAxis)a); - if (_curr.abs_axis_feedrate[a] > axis_max_jerk) - _curr.safe_feedrate = std::min(_curr.safe_feedrate, axis_max_jerk); - } - - block.feedrate.exit = _curr.safe_feedrate; - - // calculates block entry feedrate - float vmax_junction = _curr.safe_feedrate; - if (!_blocks.empty() && (_prev.feedrate > PREVIOUS_FEEDRATE_THRESHOLD)) - { - bool prev_speed_larger = _prev.feedrate > block.feedrate.cruise; - float smaller_speed_factor = prev_speed_larger ? (block.feedrate.cruise / _prev.feedrate) : (_prev.feedrate / block.feedrate.cruise); - // Pick the smaller of the nominal speeds. Higher speed shall not be achieved at the junction during coasting. - vmax_junction = prev_speed_larger ? block.feedrate.cruise : _prev.feedrate; - - float v_factor = 1.0f; - bool limited = false; - - for (unsigned char a = X; a < Num_Axis; ++a) - { - // Limit an axis. We have to differentiate coasting from the reversal of an axis movement, or a full stop. - float v_exit = _prev.axis_feedrate[a]; - float v_entry = _curr.axis_feedrate[a]; - - if (prev_speed_larger) - v_exit *= smaller_speed_factor; - - if (limited) + for (unsigned char a = X; a < Num_Axis; ++a) { - v_exit *= v_factor; - v_entry *= v_factor; + _curr.axis_feedrate[a] *= min_feedrate_factor; + _curr.abs_axis_feedrate[a] *= min_feedrate_factor; } - // Calculate the jerk depending on whether the axis is coasting in the same direction or reversing a direction. - float jerk = - (v_exit > v_entry) ? - (((v_entry > 0.0f) || (v_exit < 0.0f)) ? - // coasting - (v_exit - v_entry) : - // axis reversal - std::max(v_exit, -v_entry)) : - // v_exit <= v_entry - (((v_entry < 0.0f) || (v_exit > 0.0f)) ? - // coasting - (v_entry - v_exit) : - // axis reversal - std::max(-v_exit, v_entry)); + // calculates block acceleration + float acceleration = block.is_extruder_only_move() ? get_retract_acceleration() : get_acceleration(); - float axis_max_jerk = get_axis_max_jerk((EAxis)a); - if (jerk > axis_max_jerk) + for (unsigned char a = X; a < Num_Axis; ++a) { - v_factor *= axis_max_jerk / jerk; - limited = true; + float axis_max_acceleration = get_axis_max_acceleration((EAxis)a); + if (acceleration * std::abs(block.delta_pos[a]) * invDistance > axis_max_acceleration) + acceleration = axis_max_acceleration; } - } - if (limited) - vmax_junction *= v_factor; + block.acceleration = acceleration; - // Now the transition velocity is known, which maximizes the shared exit / entry velocity while - // respecting the jerk factors, it may be possible, that applying separate safe exit / entry velocities will achieve faster prints. - float vmax_junction_threshold = vmax_junction * 0.99f; + // calculates block exit feedrate + _curr.safe_feedrate = block.feedrate.cruise; - // Not coasting. The machine will stop and start the movements anyway, better to start the segment from start. - if ((_prev.safe_feedrate > vmax_junction_threshold) && (_curr.safe_feedrate > vmax_junction_threshold)) - vmax_junction = _curr.safe_feedrate; - } - - float v_allowable = Block::max_allowable_speed(-acceleration, _curr.safe_feedrate, distance); - block.feedrate.entry = std::min(vmax_junction, v_allowable); - - block.max_entry_speed = vmax_junction; - block.flags.nominal_length = (block.feedrate.cruise <= v_allowable); - block.flags.recalculate = true; - block.safe_feedrate = _curr.safe_feedrate; - - // calculates block trapezoid - block.calculate_trapezoid(); - - // updates previous - _prev = _curr; - - // updates axis positions - for (unsigned char a = X; a < Num_Axis; ++a) - { - set_axis_position((EAxis)a, new_pos[a]); - } - - // adds block to blocks list - _blocks.emplace_back(block); - } - - void GCodeTimeEstimator::_processG4(const GCodeReader::GCodeLine& line) - { - EDialect dialect = get_dialect(); - - float value; - if (line.has_value('P', value)) - add_additional_time(value * MILLISEC_TO_SEC); - - // see: http://reprap.org/wiki/G-code#G4:_Dwell - if ((dialect == Repetier) || - (dialect == Marlin) || - (dialect == Smoothieware) || - (dialect == RepRapFirmware)) - { - if (line.has_value('S', value)) - add_additional_time(value); - } - } - - void GCodeTimeEstimator::_processG20(const GCodeReader::GCodeLine& line) - { - set_units(Inches); - } - - void GCodeTimeEstimator::_processG21(const GCodeReader::GCodeLine& line) - { - set_units(Millimeters); - } - - void GCodeTimeEstimator::_processG28(const GCodeReader::GCodeLine& line) - { - // TODO - } - - void GCodeTimeEstimator::_processG90(const GCodeReader::GCodeLine& line) - { - set_positioning_xyz_type(Absolute); - } - - void GCodeTimeEstimator::_processG91(const GCodeReader::GCodeLine& line) - { - // TODO: THERE ARE DIALECT VARIANTS - - set_positioning_xyz_type(Relative); - } - - void GCodeTimeEstimator::_processM82(const GCodeReader::GCodeLine& line) - { - set_positioning_e_type(Absolute); - } - - void GCodeTimeEstimator::_processM83(const GCodeReader::GCodeLine& line) - { - set_positioning_e_type(Relative); - } - - void GCodeTimeEstimator::_processG92(const GCodeReader::GCodeLine& line) - { - float lengthsScaleFactor = (get_units() == Inches) ? INCHES_TO_MM : 1.0f; - bool anyFound = false; - - if (line.has_x()) - { - set_axis_position(X, line.x() * lengthsScaleFactor); - anyFound = true; - } - - if (line.has_y()) - { - set_axis_position(Y, line.y() * lengthsScaleFactor); - anyFound = true; - } - - if (line.has_z()) - { - set_axis_position(Z, line.z() * lengthsScaleFactor); - anyFound = true; - } - - if (line.has_e()) - { - set_axis_position(E, line.e() * lengthsScaleFactor); - anyFound = true; - } - - if (!anyFound) - { - for (unsigned char a = X; a < Num_Axis; ++a) - { - set_axis_position((EAxis)a, 0.0f); - } - } - } - - void GCodeTimeEstimator::_processM109(const GCodeReader::GCodeLine& line) - { - // TODO - } - - void GCodeTimeEstimator::_processM201(const GCodeReader::GCodeLine& line) - { - EDialect dialect = get_dialect(); - - // see http://reprap.org/wiki/G-code#M201:_Set_max_printing_acceleration - float factor = ((dialect != RepRapFirmware) && (get_units() == GCodeTimeEstimator::Inches)) ? INCHES_TO_MM : 1.0f; - - if (line.has_x()) - set_axis_max_acceleration(X, line.x() * factor); - - if (line.has_y()) - set_axis_max_acceleration(Y, line.y() * factor); - - if (line.has_z()) - set_axis_max_acceleration(Z, line.z() * factor); - - if (line.has_e()) - set_axis_max_acceleration(E, line.e() * factor); - } - - void GCodeTimeEstimator::_processM203(const GCodeReader::GCodeLine& line) - { - EDialect dialect = get_dialect(); - - // see http://reprap.org/wiki/G-code#M203:_Set_maximum_feedrate - if (dialect == Repetier) - return; - - // see http://reprap.org/wiki/G-code#M203:_Set_maximum_feedrate - float factor = (dialect == Marlin) ? 1.0f : MMMIN_TO_MMSEC; - - if (line.has_x()) - set_axis_max_feedrate(X, line.x() * factor); - - if (line.has_y()) - set_axis_max_feedrate(Y, line.y() * factor); - - if (line.has_z()) - set_axis_max_feedrate(Z, line.z() * factor); - - if (line.has_e()) - set_axis_max_feedrate(E, line.e() * factor); - } - - void GCodeTimeEstimator::_processM204(const GCodeReader::GCodeLine& line) - { - float value; - if (line.has_value('S', value)) - set_acceleration(value); - - if (line.has_value('T', value)) - set_retract_acceleration(value); - } - - void GCodeTimeEstimator::_processM205(const GCodeReader::GCodeLine& line) - { - if (line.has_x()) - { - float max_jerk = line.x(); - set_axis_max_jerk(X, max_jerk); - set_axis_max_jerk(Y, max_jerk); - } - - if (line.has_y()) - set_axis_max_jerk(Y, line.y()); - - if (line.has_z()) - set_axis_max_jerk(Z, line.z()); - - if (line.has_e()) - set_axis_max_jerk(E, line.e()); - - float value; - if (line.has_value('S', value)) - set_minimum_feedrate(value); - - if (line.has_value('T', value)) - set_minimum_travel_feedrate(value); - } - - void GCodeTimeEstimator::_processM566(const GCodeReader::GCodeLine& line) - { - if (line.has_x()) - set_axis_max_jerk(X, line.x() * MMMIN_TO_MMSEC); - - if (line.has_y()) - set_axis_max_jerk(Y, line.y() * MMMIN_TO_MMSEC); - - if (line.has_z()) - set_axis_max_jerk(Z, line.z() * MMMIN_TO_MMSEC); - - if (line.has_e()) - set_axis_max_jerk(E, line.e() * MMMIN_TO_MMSEC); - } - - void GCodeTimeEstimator::_forward_pass() - { - if (_blocks.size() > 1) - { - for (unsigned int i = 0; i < (unsigned int)_blocks.size() - 1; ++i) - { - _planner_forward_pass_kernel(_blocks[i], _blocks[i + 1]); - } - } - } - - void GCodeTimeEstimator::_reverse_pass() - { - if (_blocks.size() > 1) - { - for (int i = (int)_blocks.size() - 1; i >= 1; --i) - { - _planner_reverse_pass_kernel(_blocks[i - 1], _blocks[i]); - } - } - } - - void GCodeTimeEstimator::_planner_forward_pass_kernel(Block& prev, Block& curr) - { - // If the previous block is an acceleration block, but it is not long enough to complete the - // full speed change within the block, we need to adjust the entry speed accordingly. Entry - // speeds have already been reset, maximized, and reverse planned by reverse planner. - // If nominal length is true, max junction speed is guaranteed to be reached. No need to recheck. - if (!prev.flags.nominal_length) - { - if (prev.feedrate.entry < curr.feedrate.entry) - { - float entry_speed = std::min(curr.feedrate.entry, Block::max_allowable_speed(-prev.acceleration, prev.feedrate.entry, prev.move_length())); - - // Check for junction speed change - if (curr.feedrate.entry != entry_speed) - { - curr.feedrate.entry = entry_speed; - curr.flags.recalculate = true; - } - } - } - } - - void GCodeTimeEstimator::_planner_reverse_pass_kernel(Block& curr, Block& next) - { - // If entry speed is already at the maximum entry speed, no need to recheck. Block is cruising. - // If not, block in state of acceleration or deceleration. Reset entry speed to maximum and - // check for maximum allowable speed reductions to ensure maximum possible planned speed. - if (curr.feedrate.entry != curr.max_entry_speed) - { - // If nominal length true, max junction speed is guaranteed to be reached. Only compute - // for max allowable speed if block is decelerating and nominal length is false. - if (!curr.flags.nominal_length && (curr.max_entry_speed > next.feedrate.entry)) - curr.feedrate.entry = std::min(curr.max_entry_speed, Block::max_allowable_speed(-curr.acceleration, next.feedrate.entry, curr.move_length())); - else - curr.feedrate.entry = curr.max_entry_speed; - - curr.flags.recalculate = true; - } - } - - void GCodeTimeEstimator::_recalculate_trapezoids() - { - Block* curr = nullptr; - Block* next = nullptr; - - for (Block& b : _blocks) - { - curr = next; - next = &b; - - if (curr != nullptr) - { - // Recalculate if current block entry or exit junction speed has changed. - if (curr->flags.recalculate || next->flags.recalculate) + for (unsigned char a = X; a < Num_Axis; ++a) { - // NOTE: Entry and exit factors always > 0 by all previous logic operations. - Block block = *curr; - block.feedrate.exit = next->feedrate.entry; - block.calculate_trapezoid(); - curr->trapezoid = block.trapezoid; - curr->flags.recalculate = false; // Reset current only to ensure next trapezoid is computed + float axis_max_jerk = get_axis_max_jerk((EAxis)a); + if (_curr.abs_axis_feedrate[a] > axis_max_jerk) + _curr.safe_feedrate = std::min(_curr.safe_feedrate, axis_max_jerk); } - } + + block.feedrate.exit = _curr.safe_feedrate; + + // calculates block entry feedrate + float vmax_junction = _curr.safe_feedrate; + if (!_blocks.empty() && (_prev.feedrate > PREVIOUS_FEEDRATE_THRESHOLD)) + { + bool prev_speed_larger = _prev.feedrate > block.feedrate.cruise; + float smaller_speed_factor = prev_speed_larger ? (block.feedrate.cruise / _prev.feedrate) : (_prev.feedrate / block.feedrate.cruise); + // Pick the smaller of the nominal speeds. Higher speed shall not be achieved at the junction during coasting. + vmax_junction = prev_speed_larger ? block.feedrate.cruise : _prev.feedrate; + + float v_factor = 1.0f; + bool limited = false; + + for (unsigned char a = X; a < Num_Axis; ++a) + { + // Limit an axis. We have to differentiate coasting from the reversal of an axis movement, or a full stop. + float v_exit = _prev.axis_feedrate[a]; + float v_entry = _curr.axis_feedrate[a]; + + if (prev_speed_larger) + v_exit *= smaller_speed_factor; + + if (limited) + { + v_exit *= v_factor; + v_entry *= v_factor; + } + + // Calculate the jerk depending on whether the axis is coasting in the same direction or reversing a direction. + float jerk = + (v_exit > v_entry) ? + (((v_entry > 0.0f) || (v_exit < 0.0f)) ? + // coasting + (v_exit - v_entry) : + // axis reversal + std::max(v_exit, -v_entry)) : + // v_exit <= v_entry + (((v_entry < 0.0f) || (v_exit > 0.0f)) ? + // coasting + (v_entry - v_exit) : + // axis reversal + std::max(-v_exit, v_entry)); + + float axis_max_jerk = get_axis_max_jerk((EAxis)a); + if (jerk > axis_max_jerk) + { + v_factor *= axis_max_jerk / jerk; + limited = true; + } + } + + if (limited) + vmax_junction *= v_factor; + + // Now the transition velocity is known, which maximizes the shared exit / entry velocity while + // respecting the jerk factors, it may be possible, that applying separate safe exit / entry velocities will achieve faster prints. + float vmax_junction_threshold = vmax_junction * 0.99f; + + // Not coasting. The machine will stop and start the movements anyway, better to start the segment from start. + if ((_prev.safe_feedrate > vmax_junction_threshold) && (_curr.safe_feedrate > vmax_junction_threshold)) + vmax_junction = _curr.safe_feedrate; + } + + float v_allowable = Block::max_allowable_speed(-acceleration, _curr.safe_feedrate, distance); + block.feedrate.entry = std::min(vmax_junction, v_allowable); + + block.max_entry_speed = vmax_junction; + block.flags.nominal_length = (block.feedrate.cruise <= v_allowable); + block.flags.recalculate = true; + block.safe_feedrate = _curr.safe_feedrate; + + // calculates block trapezoid + block.calculate_trapezoid(); + + // updates previous + _prev = _curr; + + // updates axis positions + for (unsigned char a = X; a < Num_Axis; ++a) + { + set_axis_position((EAxis)a, new_pos[a]); + } + + // adds block to blocks list + _blocks.emplace_back(block); } - // Last/newest block in buffer. Always recalculated. - if (next != nullptr) + void GCodeTimeEstimator::_processG4(const GCodeReader::GCodeLine& line) { - Block block = *next; - block.feedrate.exit = next->safe_feedrate; - block.calculate_trapezoid(); - next->trapezoid = block.trapezoid; - next->flags.recalculate = false; + EDialect dialect = get_dialect(); + + float value; + if (line.has_value('P', value)) + add_additional_time(value * MILLISEC_TO_SEC); + + // see: http://reprap.org/wiki/G-code#G4:_Dwell + if ((dialect == Repetier) || + (dialect == Marlin) || + (dialect == Smoothieware) || + (dialect == RepRapFirmware)) + { + if (line.has_value('S', value)) + add_additional_time(value); + } + + _simulate_st_synchronize(); + } + + void GCodeTimeEstimator::_processG20(const GCodeReader::GCodeLine& line) + { + set_units(Inches); + } + + void GCodeTimeEstimator::_processG21(const GCodeReader::GCodeLine& line) + { + set_units(Millimeters); + } + + void GCodeTimeEstimator::_processG28(const GCodeReader::GCodeLine& line) + { + // TODO + } + + void GCodeTimeEstimator::_processG90(const GCodeReader::GCodeLine& line) + { + set_positioning_xyz_type(Absolute); + } + + void GCodeTimeEstimator::_processG91(const GCodeReader::GCodeLine& line) + { + // TODO: THERE ARE DIALECT VARIANTS + + set_positioning_xyz_type(Relative); + } + + void GCodeTimeEstimator::_processG92(const GCodeReader::GCodeLine& line) + { + float lengthsScaleFactor = (get_units() == Inches) ? INCHES_TO_MM : 1.0f; + bool anyFound = false; + + if (line.has_x()) + { + set_axis_position(X, line.x() * lengthsScaleFactor); + anyFound = true; + } + + if (line.has_y()) + { + set_axis_position(Y, line.y() * lengthsScaleFactor); + anyFound = true; + } + + if (line.has_z()) + { + set_axis_position(Z, line.z() * lengthsScaleFactor); + anyFound = true; + } + + if (line.has_e()) + { + set_axis_position(E, line.e() * lengthsScaleFactor); + anyFound = true; + } + else + _simulate_st_synchronize(); + + if (!anyFound) + { + for (unsigned char a = X; a < Num_Axis; ++a) + { + set_axis_position((EAxis)a, 0.0f); + } + } + } + + void GCodeTimeEstimator::_processM1(const GCodeReader::GCodeLine& line) + { + _simulate_st_synchronize(); + } + + void GCodeTimeEstimator::_processM82(const GCodeReader::GCodeLine& line) + { + set_positioning_e_type(Absolute); + } + + void GCodeTimeEstimator::_processM83(const GCodeReader::GCodeLine& line) + { + set_positioning_e_type(Relative); + } + + void GCodeTimeEstimator::_processM109(const GCodeReader::GCodeLine& line) + { + // TODO + } + + void GCodeTimeEstimator::_processM201(const GCodeReader::GCodeLine& line) + { + EDialect dialect = get_dialect(); + + // see http://reprap.org/wiki/G-code#M201:_Set_max_printing_acceleration + float factor = ((dialect != RepRapFirmware) && (get_units() == GCodeTimeEstimator::Inches)) ? INCHES_TO_MM : 1.0f; + + if (line.has_x()) + set_axis_max_acceleration(X, line.x() * factor); + + if (line.has_y()) + set_axis_max_acceleration(Y, line.y() * factor); + + if (line.has_z()) + set_axis_max_acceleration(Z, line.z() * factor); + + if (line.has_e()) + set_axis_max_acceleration(E, line.e() * factor); + } + + void GCodeTimeEstimator::_processM203(const GCodeReader::GCodeLine& line) + { + EDialect dialect = get_dialect(); + + // see http://reprap.org/wiki/G-code#M203:_Set_maximum_feedrate + if (dialect == Repetier) + return; + + // see http://reprap.org/wiki/G-code#M203:_Set_maximum_feedrate + float factor = (dialect == Marlin) ? 1.0f : MMMIN_TO_MMSEC; + + if (line.has_x()) + set_axis_max_feedrate(X, line.x() * factor); + + if (line.has_y()) + set_axis_max_feedrate(Y, line.y() * factor); + + if (line.has_z()) + set_axis_max_feedrate(Z, line.z() * factor); + + if (line.has_e()) + set_axis_max_feedrate(E, line.e() * factor); + } + + void GCodeTimeEstimator::_processM204(const GCodeReader::GCodeLine& line) + { + float value; + if (line.has_value('S', value)) + set_acceleration(value); + + if (line.has_value('T', value)) + set_retract_acceleration(value); + } + + void GCodeTimeEstimator::_processM205(const GCodeReader::GCodeLine& line) + { + if (line.has_x()) + { + float max_jerk = line.x(); + set_axis_max_jerk(X, max_jerk); + set_axis_max_jerk(Y, max_jerk); + } + + if (line.has_y()) + set_axis_max_jerk(Y, line.y()); + + if (line.has_z()) + set_axis_max_jerk(Z, line.z()); + + if (line.has_e()) + set_axis_max_jerk(E, line.e()); + + float value; + if (line.has_value('S', value)) + set_minimum_feedrate(value); + + if (line.has_value('T', value)) + set_minimum_travel_feedrate(value); + } + + void GCodeTimeEstimator::_processM566(const GCodeReader::GCodeLine& line) + { + if (line.has_x()) + set_axis_max_jerk(X, line.x() * MMMIN_TO_MMSEC); + + if (line.has_y()) + set_axis_max_jerk(Y, line.y() * MMMIN_TO_MMSEC); + + if (line.has_z()) + set_axis_max_jerk(Z, line.z() * MMMIN_TO_MMSEC); + + if (line.has_e()) + set_axis_max_jerk(E, line.e() * MMMIN_TO_MMSEC); + } + + void GCodeTimeEstimator::_simulate_st_synchronize() + { + _calculate_time(); + _reset(); + } + + void GCodeTimeEstimator::_forward_pass() + { + if (_blocks.size() > 1) + { + for (unsigned int i = 0; i < (unsigned int)_blocks.size() - 1; ++i) + { + _planner_forward_pass_kernel(_blocks[i], _blocks[i + 1]); + } + } + } + + void GCodeTimeEstimator::_reverse_pass() + { + if (_blocks.size() > 1) + { + for (int i = (int)_blocks.size() - 1; i >= 1; --i) + { + _planner_reverse_pass_kernel(_blocks[i - 1], _blocks[i]); + } + } + } + + void GCodeTimeEstimator::_planner_forward_pass_kernel(Block& prev, Block& curr) + { + // If the previous block is an acceleration block, but it is not long enough to complete the + // full speed change within the block, we need to adjust the entry speed accordingly. Entry + // speeds have already been reset, maximized, and reverse planned by reverse planner. + // If nominal length is true, max junction speed is guaranteed to be reached. No need to recheck. + if (!prev.flags.nominal_length) + { + if (prev.feedrate.entry < curr.feedrate.entry) + { + float entry_speed = std::min(curr.feedrate.entry, Block::max_allowable_speed(-prev.acceleration, prev.feedrate.entry, prev.move_length())); + + // Check for junction speed change + if (curr.feedrate.entry != entry_speed) + { + curr.feedrate.entry = entry_speed; + curr.flags.recalculate = true; + } + } + } + } + + void GCodeTimeEstimator::_planner_reverse_pass_kernel(Block& curr, Block& next) + { + // If entry speed is already at the maximum entry speed, no need to recheck. Block is cruising. + // If not, block in state of acceleration or deceleration. Reset entry speed to maximum and + // check for maximum allowable speed reductions to ensure maximum possible planned speed. + if (curr.feedrate.entry != curr.max_entry_speed) + { + // If nominal length true, max junction speed is guaranteed to be reached. Only compute + // for max allowable speed if block is decelerating and nominal length is false. + if (!curr.flags.nominal_length && (curr.max_entry_speed > next.feedrate.entry)) + curr.feedrate.entry = std::min(curr.max_entry_speed, Block::max_allowable_speed(-curr.acceleration, next.feedrate.entry, curr.move_length())); + else + curr.feedrate.entry = curr.max_entry_speed; + + curr.flags.recalculate = true; + } + } + + void GCodeTimeEstimator::_recalculate_trapezoids() + { + Block* curr = nullptr; + Block* next = nullptr; + + for (Block& b : _blocks) + { + curr = next; + next = &b; + + if (curr != nullptr) + { + // Recalculate if current block entry or exit junction speed has changed. + if (curr->flags.recalculate || next->flags.recalculate) + { + // NOTE: Entry and exit factors always > 0 by all previous logic operations. + Block block = *curr; + block.feedrate.exit = next->feedrate.entry; + block.calculate_trapezoid(); + curr->trapezoid = block.trapezoid; + curr->flags.recalculate = false; // Reset current only to ensure next trapezoid is computed + } + } + } + + // Last/newest block in buffer. Always recalculated. + if (next != nullptr) + { + Block block = *next; + block.feedrate.exit = next->safe_feedrate; + block.calculate_trapezoid(); + next->trapezoid = block.trapezoid; + next->flags.recalculate = false; + } } - } } diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index 1f912b4621..2ec283da7b 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -6,311 +6,317 @@ namespace Slic3r { - class GCodeTimeEstimator - { - public: - enum EUnits : unsigned char + class GCodeTimeEstimator { - Millimeters, - Inches + public: + enum EUnits : unsigned char + { + Millimeters, + Inches + }; + + enum EAxis : unsigned char + { + X, + Y, + Z, + E, + Num_Axis + }; + + enum EDialect : unsigned char + { + Unknown, + Marlin, + Repetier, + Smoothieware, + RepRapFirmware, + Teacup, + Num_Dialects + }; + + enum EPositioningType : unsigned char + { + Absolute, + Relative + }; + + private: + struct Axis + { + float position; // mm + float max_feedrate; // mm/s + float max_acceleration; // mm/s^2 + float max_jerk; // mm/s + }; + + struct Feedrates + { + float feedrate; // mm/s + float axis_feedrate[Num_Axis]; // mm/s + float abs_axis_feedrate[Num_Axis]; // mm/s + float safe_feedrate; // mm/s + + void reset(); + }; + + struct State + { + EDialect dialect; + EUnits units; + EPositioningType positioning_xyz_type; + EPositioningType positioning_e_type; + Axis axis[Num_Axis]; + float feedrate; // mm/s + float acceleration; // mm/s^2 + float retract_acceleration; // mm/s^2 + float additional_time; // s + float minimum_feedrate; // mm/s + float minimum_travel_feedrate; // mm/s + }; + + public: + struct Block + { + struct FeedrateProfile + { + float entry; // mm/s + float cruise; // mm/s + float exit; // mm/s + }; + + struct Trapezoid + { + float distance; // mm + float accelerate_until; // mm + float decelerate_after; // mm + FeedrateProfile feedrate; + + float acceleration_time(float acceleration) const; + float cruise_time() const; + float deceleration_time(float acceleration) const; + float cruise_distance() const; + + // This function gives the time needed to accelerate from an initial speed to reach a final distance. + static float acceleration_time_from_distance(float initial_feedrate, float distance, float acceleration); + + // This function gives the final speed while accelerating at the given constant acceleration from the given initial speed along the given distance. + static float speed_from_distance(float initial_feedrate, float distance, float acceleration); + }; + + struct Flags + { + bool recalculate; + bool nominal_length; + }; + + Flags flags; + + float delta_pos[Num_Axis]; // mm + float acceleration; // mm/s^2 + float max_entry_speed; // mm/s + float safe_feedrate; // mm/s + + FeedrateProfile feedrate; + Trapezoid trapezoid; + + // Returns the length of the move covered by this block, in mm + float move_length() const; + + // Returns true if this block is a retract/unretract move only + float is_extruder_only_move() const; + + // Returns true if this block is a move with no extrusion + float is_travel_move() const; + + // Returns the time spent accelerating toward cruise speed, in seconds + float acceleration_time() const; + + // Returns the time spent at cruise speed, in seconds + float cruise_time() const; + + // Returns the time spent decelerating from cruise speed, in seconds + float deceleration_time() const; + + // Returns the distance covered at cruise speed, in mm + float cruise_distance() const; + + // Calculates this block's trapezoid + void calculate_trapezoid(); + + // Calculates the maximum allowable speed at this point when you must be able to reach target_velocity using the + // acceleration within the allotted distance. + static float max_allowable_speed(float acceleration, float target_velocity, float distance); + + // Calculates the distance (not time) it takes to accelerate from initial_rate to target_rate using the given acceleration: + static float estimate_acceleration_distance(float initial_rate, float target_rate, float acceleration); + + // This function gives you the point at which you must start braking (at the rate of -acceleration) if + // you started at speed initial_rate and accelerated until this point and want to end at the final_rate after + // a total travel of distance. This can be used to compute the intersection point between acceleration and + // deceleration in the cases where the trapezoid has no plateau (i.e. never reaches maximum speed) + static float intersection_distance(float initial_rate, float final_rate, float acceleration, float distance); + }; + + typedef std::vector BlocksList; + + private: + GCodeReader _parser; + State _state; + Feedrates _curr; + Feedrates _prev; + BlocksList _blocks; + float _time; // s + + public: + GCodeTimeEstimator(); + + // Calculates the time estimate from the given gcode in string format + void calculate_time_from_text(const std::string& gcode); + + // Calculates the time estimate from the gcode contained in the file with the given filename + void calculate_time_from_file(const std::string& file); + + // Calculates the time estimate from the gcode contained in given list of gcode lines + void calculate_time_from_lines(const std::vector& gcode_lines); + + // Adds the given gcode line + void add_gcode_line(const std::string& gcode_line); + + void add_gcode_block(const char *ptr); + void add_gcode_block(const std::string &str) { this->add_gcode_block(str.c_str()); } + + // Calculates the time estimate from the gcode lines added using add_gcode_line() + void calculate_time(); + + // Set current position on the given axis with the given value + void set_axis_position(EAxis axis, float position); + + void set_axis_max_feedrate(EAxis axis, float feedrate_mm_sec); + void set_axis_max_acceleration(EAxis axis, float acceleration); + void set_axis_max_jerk(EAxis axis, float jerk); + + // Returns current position on the given axis + float get_axis_position(EAxis axis) const; + + float get_axis_max_feedrate(EAxis axis) const; + float get_axis_max_acceleration(EAxis axis) const; + float get_axis_max_jerk(EAxis axis) const; + + void set_feedrate(float feedrate_mm_sec); + float get_feedrate() const; + + void set_acceleration(float acceleration_mm_sec2); + float get_acceleration() const; + + void set_retract_acceleration(float acceleration_mm_sec2); + float get_retract_acceleration() const; + + void set_minimum_feedrate(float feedrate_mm_sec); + float get_minimum_feedrate() const; + + void set_minimum_travel_feedrate(float feedrate_mm_sec); + float get_minimum_travel_feedrate() const; + + void set_dialect(EDialect dialect); + EDialect get_dialect() const; + + void set_units(EUnits units); + EUnits get_units() const; + + void set_positioning_xyz_type(EPositioningType type); + EPositioningType get_positioning_xyz_type() const; + + void set_positioning_e_type(EPositioningType type); + EPositioningType get_positioning_e_type() const; + + void add_additional_time(float timeSec); + void set_additional_time(float timeSec); + float get_additional_time() const; + + void set_default(); + + // Call this method before to start adding lines using add_gcode_line() when reusing an instance of GCodeTimeEstimator + void reset(); + + // Returns the estimated time, in seconds + float get_time() const; + + // Returns the estimated time, in format HHh MMm SSs + std::string get_time_hms() const; + + private: + void _reset(); + + // Calculates the time estimate + void _calculate_time(); + + // Processes the given gcode line + void _process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line); + + // Move + void _processG1(const GCodeReader::GCodeLine& line); + + // Dwell + void _processG4(const GCodeReader::GCodeLine& line); + + // Set Units to Inches + void _processG20(const GCodeReader::GCodeLine& line); + + // Set Units to Millimeters + void _processG21(const GCodeReader::GCodeLine& line); + + // Move to Origin (Home) + void _processG28(const GCodeReader::GCodeLine& line); + + // Set to Absolute Positioning + void _processG90(const GCodeReader::GCodeLine& line); + + // Set to Relative Positioning + void _processG91(const GCodeReader::GCodeLine& line); + + // Set Position + void _processG92(const GCodeReader::GCodeLine& line); + + // Sleep or Conditional stop + void _processM1(const GCodeReader::GCodeLine& line); + + // Set extruder to absolute mode + void _processM82(const GCodeReader::GCodeLine& line); + + // Set extruder to relative mode + void _processM83(const GCodeReader::GCodeLine& line); + + // Set Extruder Temperature and Wait + void _processM109(const GCodeReader::GCodeLine& line); + + // Set max printing acceleration + void _processM201(const GCodeReader::GCodeLine& line); + + // Set maximum feedrate + void _processM203(const GCodeReader::GCodeLine& line); + + // Set default acceleration + void _processM204(const GCodeReader::GCodeLine& line); + + // Advanced settings + void _processM205(const GCodeReader::GCodeLine& line); + + // Set allowable instantaneous speed change + void _processM566(const GCodeReader::GCodeLine& line); + + // Simulates firmware st_synchronize() call + void _simulate_st_synchronize(); + + void _forward_pass(); + void _reverse_pass(); + + void _planner_forward_pass_kernel(Block& prev, Block& curr); + void _planner_reverse_pass_kernel(Block& curr, Block& next); + + void _recalculate_trapezoids(); }; - enum EAxis : unsigned char - { - X, - Y, - Z, - E, - Num_Axis - }; - - enum EDialect : unsigned char - { - Unknown, - Marlin, - Repetier, - Smoothieware, - RepRapFirmware, - Teacup, - Num_Dialects - }; - - enum EPositioningType : unsigned char - { - Absolute, - Relative - }; - - private: - struct Axis - { - float position; // mm - float max_feedrate; // mm/s - float max_acceleration; // mm/s^2 - float max_jerk; // mm/s - }; - - struct Feedrates - { - float feedrate; // mm/s - float axis_feedrate[Num_Axis]; // mm/s - float abs_axis_feedrate[Num_Axis]; // mm/s - float safe_feedrate; // mm/s - - void reset(); - }; - - struct State - { - EDialect dialect; - EUnits units; - EPositioningType positioning_xyz_type; - EPositioningType positioning_e_type; - Axis axis[Num_Axis]; - float feedrate; // mm/s - float acceleration; // mm/s^2 - float retract_acceleration; // mm/s^2 - float additional_time; // s - float minimum_feedrate; // mm/s - float minimum_travel_feedrate; // mm/s - }; - - public: - struct Block - { - struct FeedrateProfile - { - float entry; // mm/s - float cruise; // mm/s - float exit; // mm/s - }; - - struct Trapezoid - { - float distance; // mm - float accelerate_until; // mm - float decelerate_after; // mm - FeedrateProfile feedrate; - - float acceleration_time(float acceleration) const; - float cruise_time() const; - float deceleration_time(float acceleration) const; - float cruise_distance() const; - - // This function gives the time needed to accelerate from an initial speed to reach a final distance. - static float acceleration_time_from_distance(float initial_feedrate, float distance, float acceleration); - - // This function gives the final speed while accelerating at the given constant acceleration from the given initial speed along the given distance. - static float speed_from_distance(float initial_feedrate, float distance, float acceleration); - }; - - struct Flags - { - bool recalculate; - bool nominal_length; - }; - - Flags flags; - - float delta_pos[Num_Axis]; // mm - float acceleration; // mm/s^2 - float max_entry_speed; // mm/s - float safe_feedrate; // mm/s - - FeedrateProfile feedrate; - Trapezoid trapezoid; - - // Returns the length of the move covered by this block, in mm - float move_length() const; - - // Returns true if this block is a retract/unretract move only - float is_extruder_only_move() const; - - // Returns true if this block is a move with no extrusion - float is_travel_move() const; - - // Returns the time spent accelerating toward cruise speed, in seconds - float acceleration_time() const; - - // Returns the time spent at cruise speed, in seconds - float cruise_time() const; - - // Returns the time spent decelerating from cruise speed, in seconds - float deceleration_time() const; - - // Returns the distance covered at cruise speed, in mm - float cruise_distance() const; - - // Calculates this block's trapezoid - void calculate_trapezoid(); - - // Calculates the maximum allowable speed at this point when you must be able to reach target_velocity using the - // acceleration within the allotted distance. - static float max_allowable_speed(float acceleration, float target_velocity, float distance); - - // Calculates the distance (not time) it takes to accelerate from initial_rate to target_rate using the given acceleration: - static float estimate_acceleration_distance(float initial_rate, float target_rate, float acceleration); - - // This function gives you the point at which you must start braking (at the rate of -acceleration) if - // you started at speed initial_rate and accelerated until this point and want to end at the final_rate after - // a total travel of distance. This can be used to compute the intersection point between acceleration and - // deceleration in the cases where the trapezoid has no plateau (i.e. never reaches maximum speed) - static float intersection_distance(float initial_rate, float final_rate, float acceleration, float distance); - }; - - typedef std::vector BlocksList; - - private: - GCodeReader _parser; - State _state; - Feedrates _curr; - Feedrates _prev; - BlocksList _blocks; - float _time; // s - - public: - GCodeTimeEstimator(); - - // Calculates the time estimate from the given gcode in string format - void calculate_time_from_text(const std::string& gcode); - - // Calculates the time estimate from the gcode contained in the file with the given filename - void calculate_time_from_file(const std::string& file); - - // Calculates the time estimate from the gcode contained in given list of gcode lines - void calculate_time_from_lines(const std::vector& gcode_lines); - - // Adds the given gcode line - void add_gcode_line(const std::string& gcode_line); - - void add_gcode_block(const char *ptr); - void add_gcode_block(const std::string &str) { this->add_gcode_block(str.c_str()); } - - // Calculates the time estimate from the gcode lines added using add_gcode_line() - void calculate_time(); - - // Set current position on the given axis with the given value - void set_axis_position(EAxis axis, float position); - - void set_axis_max_feedrate(EAxis axis, float feedrate_mm_sec); - void set_axis_max_acceleration(EAxis axis, float acceleration); - void set_axis_max_jerk(EAxis axis, float jerk); - - // Returns current position on the given axis - float get_axis_position(EAxis axis) const; - - float get_axis_max_feedrate(EAxis axis) const; - float get_axis_max_acceleration(EAxis axis) const; - float get_axis_max_jerk(EAxis axis) const; - - void set_feedrate(float feedrate_mm_sec); - float get_feedrate() const; - - void set_acceleration(float acceleration_mm_sec2); - float get_acceleration() const; - - void set_retract_acceleration(float acceleration_mm_sec2); - float get_retract_acceleration() const; - - void set_minimum_feedrate(float feedrate_mm_sec); - float get_minimum_feedrate() const; - - void set_minimum_travel_feedrate(float feedrate_mm_sec); - float get_minimum_travel_feedrate() const; - - void set_dialect(EDialect dialect); - EDialect get_dialect() const; - - void set_units(EUnits units); - EUnits get_units() const; - - void set_positioning_xyz_type(EPositioningType type); - EPositioningType get_positioning_xyz_type() const; - - void set_positioning_e_type(EPositioningType type); - EPositioningType get_positioning_e_type() const; - - void add_additional_time(float timeSec); - void set_additional_time(float timeSec); - float get_additional_time() const; - - void set_default(); - - // Call this method before to start adding lines using add_gcode_line() when reusing an instance of GCodeTimeEstimator - void reset(); - - // Returns the estimated time, in seconds - float get_time() const; - - // Returns the estimated time, in format HHh MMm SSs - std::string get_time_hms() const; - - private: - void _reset(); - - // Calculates the time estimate - void _calculate_time(); - - // Processes the given gcode line - void _process_gcode_line(GCodeReader&, const GCodeReader::GCodeLine& line); - - // Move - void _processG1(const GCodeReader::GCodeLine& line); - - // Dwell - void _processG4(const GCodeReader::GCodeLine& line); - - // Set Units to Inches - void _processG20(const GCodeReader::GCodeLine& line); - - // Set Units to Millimeters - void _processG21(const GCodeReader::GCodeLine& line); - - // Move to Origin (Home) - void _processG28(const GCodeReader::GCodeLine& line); - - // Set to Absolute Positioning - void _processG90(const GCodeReader::GCodeLine& line); - - // Set to Relative Positioning - void _processG91(const GCodeReader::GCodeLine& line); - - // Set Position - void _processG92(const GCodeReader::GCodeLine& line); - - // Set extruder to absolute mode - void _processM82(const GCodeReader::GCodeLine& line); - - // Set extruder to relative mode - void _processM83(const GCodeReader::GCodeLine& line); - - // Set Extruder Temperature and Wait - void _processM109(const GCodeReader::GCodeLine& line); - - // Set max printing acceleration - void _processM201(const GCodeReader::GCodeLine& line); - - // Set maximum feedrate - void _processM203(const GCodeReader::GCodeLine& line); - - // Set default acceleration - void _processM204(const GCodeReader::GCodeLine& line); - - // Advanced settings - void _processM205(const GCodeReader::GCodeLine& line); - - // Set allowable instantaneous speed change - void _processM566(const GCodeReader::GCodeLine& line); - - void _forward_pass(); - void _reverse_pass(); - - void _planner_forward_pass_kernel(Block& prev, Block& curr); - void _planner_reverse_pass_kernel(Block& curr, Block& next); - - void _recalculate_trapezoids(); - }; - } /* namespace Slic3r */ #endif /* slic3r_GCodeTimeEstimator_hpp_ */ From ae0688f351752525a6acdacfbe2c85461b1ba45e Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Fri, 5 Jan 2018 10:35:04 +0100 Subject: [PATCH 25/33] GCodeTimeEstimator - added processing of commands M221 (Set extrude factor override percentage) --- xs/src/libslic3r/GCodeTimeEstimator.cpp | 28 +++++++++++++++++++++++++ xs/src/libslic3r/GCodeTimeEstimator.hpp | 7 +++++++ 2 files changed, 35 insertions(+) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index cc1461db68..2ebeb9fd29 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -15,6 +15,7 @@ static const float DEFAULT_AXIS_MAX_ACCELERATION[] = { 9000.0f, 9000.0f, 500.0f, static const float DEFAULT_AXIS_MAX_JERK[] = { 10.0f, 10.0f, 0.2f, 2.5f }; // from Prusa Firmware (Configuration.h) static const float DEFAULT_MINIMUM_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) static const float DEFAULT_MINIMUM_TRAVEL_FEEDRATE = 0.0f; // from Prusa Firmware (Configuration_adv.h) +static const float DEFAULT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE = 1.0f; // 100 percent static const float PREVIOUS_FEEDRATE_THRESHOLD = 0.0001f; @@ -291,6 +292,16 @@ namespace Slic3r { return _state.minimum_travel_feedrate; } + void GCodeTimeEstimator::set_extrude_factor_override_percentage(float percentage) + { + _state.extrude_factor_override_percentage = percentage; + } + + float GCodeTimeEstimator::get_extrude_factor_override_percentage() const + { + return _state.extrude_factor_override_percentage; + } + void GCodeTimeEstimator::set_dialect(GCodeTimeEstimator::EDialect dialect) { _state.dialect = dialect; @@ -358,6 +369,7 @@ namespace Slic3r { set_retract_acceleration(DEFAULT_RETRACT_ACCELERATION); set_minimum_feedrate(DEFAULT_MINIMUM_FEEDRATE); set_minimum_travel_feedrate(DEFAULT_MINIMUM_TRAVEL_FEEDRATE); + set_extrude_factor_override_percentage(DEFAULT_EXTRUDE_FACTOR_OVERRIDE_PERCENTAGE); for (unsigned char a = X; a < Num_Axis; ++a) { @@ -528,6 +540,11 @@ namespace Slic3r { _processM205(line); break; } + case 221: // Set extrude factor override percentage + { + _processM221(line); + break; + } case 566: // Set allowable instantaneous speed change { _processM566(line); @@ -593,6 +610,9 @@ namespace Slic3r { for (unsigned char a = X; a < Num_Axis; ++a) { _curr.axis_feedrate[a] = _curr.feedrate * block.delta_pos[a] * invDistance; + if (a == E) + _curr.axis_feedrate[a] *= get_extrude_factor_override_percentage(); + _curr.abs_axis_feedrate[a] = std::abs(_curr.axis_feedrate[a]); if (_curr.abs_axis_feedrate[a] > 0.0f) min_feedrate_factor = std::min(min_feedrate_factor, get_axis_max_feedrate((EAxis)a) / _curr.abs_axis_feedrate[a]); @@ -904,6 +924,14 @@ namespace Slic3r { set_minimum_travel_feedrate(value); } + void GCodeTimeEstimator::_processM221(const GCodeReader::GCodeLine& line) + { + float value_s; + float value_t; + if (line.has_value('S', value_s) && !line.has_value('T', value_t)) + set_extrude_factor_override_percentage(value_s * 0.01f); + } + void GCodeTimeEstimator::_processM566(const GCodeReader::GCodeLine& line) { if (line.has_x()) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index 2ec283da7b..46f8669724 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -73,6 +73,7 @@ namespace Slic3r { float additional_time; // s float minimum_feedrate; // mm/s float minimum_travel_feedrate; // mm/s + float extrude_factor_override_percentage; }; public: @@ -218,6 +219,9 @@ namespace Slic3r { void set_minimum_travel_feedrate(float feedrate_mm_sec); float get_minimum_travel_feedrate() const; + void set_extrude_factor_override_percentage(float percentage); + float get_extrude_factor_override_percentage() const; + void set_dialect(EDialect dialect); EDialect get_dialect() const; @@ -302,6 +306,9 @@ namespace Slic3r { // Advanced settings void _processM205(const GCodeReader::GCodeLine& line); + // Set extrude factor override percentage + void _processM221(const GCodeReader::GCodeLine& line); + // Set allowable instantaneous speed change void _processM566(const GCodeReader::GCodeLine& line); From 40a6125d73b74fe961df1d90ff26439335720a42 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 5 Jan 2018 15:59:05 +0100 Subject: [PATCH 26/33] Updated printer profiles. --- ...inal Prusa i3 MK2, MK2S, MK2MM and MK3.ini | 160 +++---- resources/profiles/Original Prusa i3 MK3.ini | 452 +++++++----------- 2 files changed, 253 insertions(+), 359 deletions(-) diff --git a/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini b/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini index 0ee20e8ead..160bece781 100644 --- a/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini +++ b/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini @@ -1,4 +1,4 @@ -# generated by Slic3r Prusa Edition 1.38.4 on 2017-12-21 at 17:47:55 +# generated by Slic3r Prusa Edition 1.38.4.17-prusa3d-win32 on 2018-01-04 at 17:24:45 [print:0.05mm DETAIL] avoid_crossing_perimeters = 0 @@ -248,7 +248,7 @@ gcode_comments = 0 infill_acceleration = 800 infill_every_layers = 1 infill_extruder = 1 -infill_extrusion_width = 0.5 +infill_extrusion_width = 0.45 infill_first = 0 infill_only_where_needed = 0 infill_overlap = 25% @@ -307,7 +307,7 @@ support_material_with_sheath = 0 support_material_xy_spacing = 60% thin_walls = 0 threads = 4 -top_infill_extrusion_width = 0.45 +top_infill_extrusion_width = 0.4 top_solid_infill_speed = 20 top_solid_layers = 15 travel_speed = 180 @@ -532,7 +532,7 @@ xy_size_compensation = 0 [print:0.10mm DETAIL MK3] avoid_crossing_perimeters = 0 -bottom_solid_layers = 4 +bottom_solid_layers = 7 bridge_acceleration = 1000 bridge_angle = 0 bridge_flow_ratio = 0.8 @@ -548,7 +548,7 @@ elefant_foot_compensation = 0 ensure_vertical_shell_thickness = 1 external_fill_pattern = rectilinear external_perimeter_extrusion_width = 0.45 -external_perimeter_speed = 40 +external_perimeter_speed = 35 external_perimeters_first = 0 extra_perimeters = 0 extruder_clearance_height = 20 @@ -586,7 +586,7 @@ overhangs = 0 perimeter_acceleration = 800 perimeter_extruder = 1 perimeter_extrusion_width = 0.45 -perimeter_speed = 60 +perimeter_speed = 45 perimeters = 2 post_process = print_settings_id = @@ -627,7 +627,7 @@ thin_walls = 0 threads = 4 top_infill_extrusion_width = 0.4 top_solid_infill_speed = 50 -top_solid_layers = 5 +top_solid_layers = 9 travel_speed = 250 wipe_tower = 0 wipe_tower_per_color_wipe = 15 @@ -1062,7 +1062,7 @@ xy_size_compensation = 0 [print:0.15mm OPTIMAL MK3] avoid_crossing_perimeters = 0 -bottom_solid_layers = 4 +bottom_solid_layers = 5 bridge_acceleration = 1000 bridge_angle = 0 bridge_flow_ratio = 0.8 @@ -1078,7 +1078,7 @@ elefant_foot_compensation = 0 ensure_vertical_shell_thickness = 1 external_fill_pattern = rectilinear external_perimeter_extrusion_width = 0.45 -external_perimeter_speed = 40 +external_perimeter_speed = 35 external_perimeters_first = 0 extra_perimeters = 0 extruder_clearance_height = 20 @@ -1116,7 +1116,7 @@ overhangs = 0 perimeter_acceleration = 800 perimeter_extruder = 1 perimeter_extrusion_width = 0.45 -perimeter_speed = 60 +perimeter_speed = 45 perimeters = 2 post_process = print_settings_id = @@ -1157,7 +1157,7 @@ thin_walls = 0 threads = 4 top_infill_extrusion_width = 0.4 top_solid_infill_speed = 50 -top_solid_layers = 5 +top_solid_layers = 7 travel_speed = 250 wipe_tower = 1 wipe_tower_per_color_wipe = 15 @@ -1714,7 +1714,7 @@ elefant_foot_compensation = 0 ensure_vertical_shell_thickness = 1 external_fill_pattern = rectilinear external_perimeter_extrusion_width = 0.45 -external_perimeter_speed = 40 +external_perimeter_speed = 35 external_perimeters_first = 0 extra_perimeters = 0 extruder_clearance_height = 20 @@ -1752,7 +1752,7 @@ overhangs = 0 perimeter_acceleration = 800 perimeter_extruder = 1 perimeter_extrusion_width = 0.45 -perimeter_speed = 60 +perimeter_speed = 45 perimeters = 2 post_process = print_settings_id = @@ -2243,16 +2243,16 @@ dont_support_bridges = 1 elefant_foot_compensation = 0 ensure_vertical_shell_thickness = 1 external_fill_pattern = rectilinear -external_perimeter_extrusion_width = 0.6 -external_perimeter_speed = 40 +external_perimeter_extrusion_width = 0.45 +external_perimeter_speed = 35 external_perimeters_first = 0 extra_perimeters = 0 extruder_clearance_height = 20 extruder_clearance_radius = 20 extrusion_width = 0.45 fill_angle = 45 -fill_density = 20% -fill_pattern = cubic +fill_density = 10% +fill_pattern = rectilinear first_layer_acceleration = 1000 first_layer_extrusion_width = 0.42 first_layer_height = 0.2 @@ -2262,7 +2262,7 @@ gcode_comments = 0 infill_acceleration = 3500 infill_every_layers = 1 infill_extruder = 1 -infill_extrusion_width = 0.7 +infill_extrusion_width = 0.45 infill_first = 0 infill_only_where_needed = 0 infill_overlap = 25% @@ -2282,7 +2282,7 @@ overhangs = 0 perimeter_acceleration = 800 perimeter_extruder = 1 perimeter_extrusion_width = 0.45 -perimeter_speed = 60 +perimeter_speed = 45 perimeters = 2 post_process = print_settings_id = @@ -2296,7 +2296,7 @@ small_perimeter_speed = 20 solid_infill_below_area = 0 solid_infill_every_layers = 0 solid_infill_extruder = 1 -solid_infill_extrusion_width = 0.7 +solid_infill_extrusion_width = 0.45 solid_infill_speed = 200 spiral_vase = 0 standby_temperature_delta = -5 @@ -2544,7 +2544,7 @@ wipe_tower_x = 180 wipe_tower_y = 140 xy_size_compensation = 0 -[filament:ColorFabb Brass Bronze 1.75mm] +[filament:ColorFabb Brass Bronze] bed_temperature = 60 bridge_fan_speed = 100 compatible_printers = @@ -2567,13 +2567,13 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 210 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 210 -[filament:ColorFabb HT 1.75mm] +[filament:ColorFabb HT] bed_temperature = 105 bridge_fan_speed = 30 compatible_printers = @@ -2598,7 +2598,7 @@ first_layer_temperature = 270 max_fan_speed = 20 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 270 @@ -2625,13 +2625,13 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 215 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 210 -[filament:ColorFabb Woodfil 1.75mm] +[filament:ColorFabb Woodfil] bed_temperature = 60 bridge_fan_speed = 100 compatible_printers = @@ -2654,13 +2654,13 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 200 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 200 -[filament:ColorFabb XT 1.75mm] +[filament:ColorFabb XT] bed_temperature = 90 bridge_fan_speed = 50 compatible_printers = @@ -2685,11 +2685,11 @@ first_layer_temperature = 260 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 270 -[filament:ColorFabb XT-CF20 1.75mm] +[filament:ColorFabb XT-CF20] bed_temperature = 90 bridge_fan_speed = 50 compatible_printers = @@ -2714,11 +2714,11 @@ first_layer_temperature = 260 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 260 -[filament:ColorFabb nGen 1.75mm] +[filament:ColorFabb nGen] bed_temperature = 85 bridge_fan_speed = 40 compatible_printers = @@ -2743,7 +2743,7 @@ first_layer_temperature = 240 max_fan_speed = 35 min_fan_speed = 20 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 240 @@ -2772,7 +2772,7 @@ first_layer_temperature = 260 max_fan_speed = 35 min_fan_speed = 20 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 260 @@ -2801,11 +2801,11 @@ first_layer_temperature = 230 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 240 -[filament:E3D PC-ABS 1.75mm] +[filament:E3D PC-ABS] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -2830,11 +2830,11 @@ first_layer_temperature = 270 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 270 -[filament:Fillamentum ABS 1.75mm] +[filament:Fillamentum ABS] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -2859,11 +2859,11 @@ first_layer_temperature = 240 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 240 -[filament:Fillamentum ASA 1.75mm] +[filament:Fillamentum ASA] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -2888,7 +2888,7 @@ first_layer_temperature = 265 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 265 @@ -2917,7 +2917,7 @@ first_layer_temperature = 260 max_fan_speed = 80 min_fan_speed = 80 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 260 @@ -2944,13 +2944,13 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 190 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 190 -[filament:Generic ABS 1.75mm] +[filament:Generic ABS] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -2975,11 +2975,11 @@ first_layer_temperature = 255 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 255 -[filament:Generic PET 1.75mm] +[filament:Generic PET] bed_temperature = 90 bridge_fan_speed = 50 compatible_printers = @@ -3004,11 +3004,11 @@ first_layer_temperature = 230 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 240 -[filament:Generic PLA 1.75mm] +[filament:Generic PLA] bed_temperature = 60 bridge_fan_speed = 100 compatible_printers = @@ -3031,9 +3031,9 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 215 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 210 @@ -3062,7 +3062,7 @@ first_layer_temperature = 270 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 270 @@ -3089,13 +3089,13 @@ filament_type = PVA first_layer_bed_temperature = 60 first_layer_temperature = 195 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 195 -[filament:Prusa ABS 1.75mm] +[filament:Prusa ABS] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -3120,11 +3120,11 @@ first_layer_temperature = 255 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 255 -[filament:Prusa HIPS 1.75mm] +[filament:Prusa HIPS] bed_temperature = 100 bridge_fan_speed = 50 compatible_printers = @@ -3149,11 +3149,11 @@ first_layer_temperature = 220 max_fan_speed = 20 min_fan_speed = 20 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 220 -[filament:Prusa PET 1.75mm] +[filament:Prusa PET] bed_temperature = 90 bridge_fan_speed = 50 compatible_printers = @@ -3178,11 +3178,11 @@ first_layer_temperature = 230 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 240 -[filament:Prusa PLA 1.75mm] +[filament:Prusa PLA] bed_temperature = 60 bridge_fan_speed = 100 compatible_printers = @@ -3205,9 +3205,9 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 215 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 210 @@ -3236,11 +3236,11 @@ first_layer_temperature = 220 max_fan_speed = 90 min_fan_speed = 70 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 230 -[filament:Taulman Bridge 1.75mm] +[filament:Taulman Bridge] bed_temperature = 50 bridge_fan_speed = 40 compatible_printers = @@ -3265,11 +3265,11 @@ first_layer_temperature = 240 max_fan_speed = 5 min_fan_speed = 0 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 250 -[filament:Taulman T-Glase 1.75mm] +[filament:Taulman T-Glase] bed_temperature = 90 bridge_fan_speed = 40 compatible_printers = @@ -3294,7 +3294,7 @@ first_layer_temperature = 240 max_fan_speed = 5 min_fan_speed = 0 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 240 @@ -3321,9 +3321,9 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 215 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 210 @@ -3352,7 +3352,7 @@ first_layer_temperature = 220 max_fan_speed = 100 min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 220 @@ -3641,7 +3641,7 @@ bed_shape = 0x0,250x0,250x210,0x210 before_layer_gcode = ;BEFORE_LAYER_CHANGE\n;[layer_z]\n\n between_objects_gcode = deretract_speed = 0 -end_gcode = G4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors +end_gcode = G4 ; wait\nM221 S100\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors extruder_colour = #FFFF00 extruder_offset = 0x0 gcode_flavor = reprap @@ -3656,7 +3656,7 @@ retract_before_travel = 1 retract_before_wipe = 0% retract_layer_change = 1 retract_length = 0.8 -retract_length_toolchange = 3 +retract_length_toolchange = 4 retract_lift = 0.6 retract_lift_above = 0 retract_lift_below = 209 @@ -3666,7 +3666,7 @@ retract_speed = 35 serial_port = serial_speed = 250000 single_extruder_multi_material = 0 -start_gcode = M115 U3.1.1-RC4 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M115 U3.1.1-RC4 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S95 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 @@ -3676,6 +3676,6 @@ wipe = 1 z_offset = 0 [presets] -print = 0.15mm 100mms Linear Advance -printer = Original Prusa i3 MK2 -filament = Prusa PLA 1.75mm +print = 0.20mm NORMAL MK3 +printer = Original Prusa i3 MK3 +filament = Prusa PLA diff --git a/resources/profiles/Original Prusa i3 MK3.ini b/resources/profiles/Original Prusa i3 MK3.ini index e82c7c3cf2..a4e0694ec8 100644 --- a/resources/profiles/Original Prusa i3 MK3.ini +++ b/resources/profiles/Original Prusa i3 MK3.ini @@ -1,4 +1,4 @@ -# generated by Slic3r Prusa Edition 1.38.4 on 2017-12-21 at 20:14:54 +# generated by Slic3r Prusa Edition 1.38.6 on 2018-01-05 at 15:21:29 [print:0.05mm DETAIL] avoid_crossing_perimeters = 0 @@ -238,7 +238,7 @@ extruder_clearance_radius = 20 extrusion_width = 0.45 fill_angle = 45 fill_density = 25% -fill_pattern = cubic +fill_pattern = grid first_layer_acceleration = 500 first_layer_extrusion_width = 0.42 first_layer_height = 0.2 @@ -248,7 +248,7 @@ gcode_comments = 0 infill_acceleration = 800 infill_every_layers = 1 infill_extruder = 1 -infill_extrusion_width = 0.5 +infill_extrusion_width = 0.45 infill_first = 0 infill_only_where_needed = 0 infill_overlap = 25% @@ -307,7 +307,7 @@ support_material_with_sheath = 0 support_material_xy_spacing = 60% thin_walls = 0 threads = 4 -top_infill_extrusion_width = 0.45 +top_infill_extrusion_width = 0.4 top_solid_infill_speed = 20 top_solid_layers = 15 travel_speed = 180 @@ -548,7 +548,7 @@ elefant_foot_compensation = 0 ensure_vertical_shell_thickness = 1 external_fill_pattern = rectilinear external_perimeter_extrusion_width = 0.45 -external_perimeter_speed = 40 +external_perimeter_speed = 35 external_perimeters_first = 0 extra_perimeters = 0 extruder_clearance_height = 20 @@ -556,7 +556,7 @@ extruder_clearance_radius = 20 extrusion_width = 0.45 fill_angle = 45 fill_density = 20% -fill_pattern = cubic +fill_pattern = grid first_layer_acceleration = 1000 first_layer_extrusion_width = 0.42 first_layer_height = 0.2 @@ -586,7 +586,7 @@ overhangs = 0 perimeter_acceleration = 800 perimeter_extruder = 1 perimeter_extrusion_width = 0.45 -perimeter_speed = 60 +perimeter_speed = 45 perimeters = 2 post_process = print_settings_id = @@ -1078,7 +1078,7 @@ elefant_foot_compensation = 0 ensure_vertical_shell_thickness = 1 external_fill_pattern = rectilinear external_perimeter_extrusion_width = 0.45 -external_perimeter_speed = 40 +external_perimeter_speed = 35 external_perimeters_first = 0 extra_perimeters = 0 extruder_clearance_height = 20 @@ -1086,7 +1086,7 @@ extruder_clearance_radius = 20 extrusion_width = 0.45 fill_angle = 45 fill_density = 20% -fill_pattern = cubic +fill_pattern = grid first_layer_acceleration = 1000 first_layer_extrusion_width = 0.42 first_layer_height = 0.2 @@ -1116,7 +1116,7 @@ overhangs = 0 perimeter_acceleration = 800 perimeter_extruder = 1 perimeter_extrusion_width = 0.45 -perimeter_speed = 60 +perimeter_speed = 45 perimeters = 2 post_process = print_settings_id = @@ -1484,6 +1484,112 @@ wipe_tower_x = 180 wipe_tower_y = 140 xy_size_compensation = 0 +[print:0.20mm FAST MK3] +avoid_crossing_perimeters = 0 +bottom_solid_layers = 4 +bridge_acceleration = 1000 +bridge_angle = 0 +bridge_flow_ratio = 0.8 +bridge_speed = 30 +brim_width = 0 +clip_multipart_objects = 1 +compatible_printers = +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ +complete_objects = 0 +default_acceleration = 1000 +dont_support_bridges = 1 +elefant_foot_compensation = 0 +ensure_vertical_shell_thickness = 1 +external_fill_pattern = rectilinear +external_perimeter_extrusion_width = 0.45 +external_perimeter_speed = 35 +external_perimeters_first = 0 +extra_perimeters = 0 +extruder_clearance_height = 20 +extruder_clearance_radius = 20 +extrusion_width = 0.45 +fill_angle = 45 +fill_density = 20% +fill_pattern = grid +first_layer_acceleration = 1000 +first_layer_extrusion_width = 0.42 +first_layer_height = 0.2 +first_layer_speed = 30 +gap_fill_speed = 40 +gcode_comments = 0 +infill_acceleration = 3500 +infill_every_layers = 1 +infill_extruder = 1 +infill_extrusion_width = 0.45 +infill_first = 0 +infill_only_where_needed = 0 +infill_overlap = 25% +infill_speed = 200 +interface_shells = 0 +layer_height = 0.2 +max_print_speed = 250 +max_volumetric_extrusion_rate_slope_negative = 0 +max_volumetric_extrusion_rate_slope_positive = 0 +max_volumetric_speed = 0 +min_skirt_length = 4 +notes = +only_retract_when_crossing_perimeters = 0 +ooze_prevention = 0 +output_filename_format = [input_filename_base].gcode +overhangs = 0 +perimeter_acceleration = 800 +perimeter_extruder = 1 +perimeter_extrusion_width = 0.45 +perimeter_speed = 45 +perimeters = 2 +post_process = +print_settings_id = +raft_layers = 0 +resolution = 0 +seam_position = nearest +skirt_distance = 2 +skirt_height = 3 +skirts = 1 +small_perimeter_speed = 20 +solid_infill_below_area = 0 +solid_infill_every_layers = 0 +solid_infill_extruder = 1 +solid_infill_extrusion_width = 0.45 +solid_infill_speed = 200 +spiral_vase = 0 +standby_temperature_delta = -5 +support_material = 0 +support_material_angle = 0 +support_material_buildplate_only = 0 +support_material_contact_distance = 0.15 +support_material_enforce_layers = 0 +support_material_extruder = 0 +support_material_extrusion_width = 0.35 +support_material_interface_contact_loops = 0 +support_material_interface_extruder = 0 +support_material_interface_layers = 2 +support_material_interface_spacing = 0.2 +support_material_interface_speed = 100% +support_material_pattern = rectilinear +support_material_spacing = 2 +support_material_speed = 50 +support_material_synchronize_layers = 0 +support_material_threshold = 45 +support_material_with_sheath = 0 +support_material_xy_spacing = 60% +thin_walls = 0 +threads = 4 +top_infill_extrusion_width = 0.4 +top_solid_infill_speed = 50 +top_solid_layers = 5 +travel_speed = 250 +wipe_tower = 1 +wipe_tower_per_color_wipe = 15 +wipe_tower_width = 60 +wipe_tower_x = 180 +wipe_tower_y = 140 +xy_size_compensation = 0 + [print:0.20mm NORMAL] avoid_crossing_perimeters = 0 bottom_solid_layers = 4 @@ -1696,112 +1802,6 @@ wipe_tower_x = 180 wipe_tower_y = 140 xy_size_compensation = 0 -[print:0.20mm NORMAL MK3] -avoid_crossing_perimeters = 0 -bottom_solid_layers = 4 -bridge_acceleration = 1000 -bridge_angle = 0 -bridge_flow_ratio = 0.8 -bridge_speed = 30 -brim_width = 0 -clip_multipart_objects = 1 -compatible_printers = -compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ -complete_objects = 0 -default_acceleration = 1000 -dont_support_bridges = 1 -elefant_foot_compensation = 0 -ensure_vertical_shell_thickness = 1 -external_fill_pattern = rectilinear -external_perimeter_extrusion_width = 0.45 -external_perimeter_speed = 40 -external_perimeters_first = 0 -extra_perimeters = 0 -extruder_clearance_height = 20 -extruder_clearance_radius = 20 -extrusion_width = 0.45 -fill_angle = 45 -fill_density = 20% -fill_pattern = cubic -first_layer_acceleration = 1000 -first_layer_extrusion_width = 0.42 -first_layer_height = 0.2 -first_layer_speed = 30 -gap_fill_speed = 40 -gcode_comments = 0 -infill_acceleration = 3500 -infill_every_layers = 1 -infill_extruder = 1 -infill_extrusion_width = 0.45 -infill_first = 0 -infill_only_where_needed = 0 -infill_overlap = 25% -infill_speed = 200 -interface_shells = 0 -layer_height = 0.2 -max_print_speed = 250 -max_volumetric_extrusion_rate_slope_negative = 0 -max_volumetric_extrusion_rate_slope_positive = 0 -max_volumetric_speed = 0 -min_skirt_length = 4 -notes = -only_retract_when_crossing_perimeters = 0 -ooze_prevention = 0 -output_filename_format = [input_filename_base].gcode -overhangs = 0 -perimeter_acceleration = 800 -perimeter_extruder = 1 -perimeter_extrusion_width = 0.45 -perimeter_speed = 60 -perimeters = 2 -post_process = -print_settings_id = -raft_layers = 0 -resolution = 0 -seam_position = nearest -skirt_distance = 2 -skirt_height = 3 -skirts = 1 -small_perimeter_speed = 20 -solid_infill_below_area = 0 -solid_infill_every_layers = 0 -solid_infill_extruder = 1 -solid_infill_extrusion_width = 0.45 -solid_infill_speed = 200 -spiral_vase = 0 -standby_temperature_delta = -5 -support_material = 0 -support_material_angle = 0 -support_material_buildplate_only = 0 -support_material_contact_distance = 0.15 -support_material_enforce_layers = 0 -support_material_extruder = 0 -support_material_extrusion_width = 0.35 -support_material_interface_contact_loops = 0 -support_material_interface_extruder = 0 -support_material_interface_layers = 2 -support_material_interface_spacing = 0.2 -support_material_interface_speed = 100% -support_material_pattern = rectilinear -support_material_spacing = 2 -support_material_speed = 50 -support_material_synchronize_layers = 0 -support_material_threshold = 45 -support_material_with_sheath = 0 -support_material_xy_spacing = 60% -thin_walls = 0 -threads = 4 -top_infill_extrusion_width = 0.4 -top_solid_infill_speed = 50 -top_solid_layers = 5 -travel_speed = 250 -wipe_tower = 1 -wipe_tower_per_color_wipe = 15 -wipe_tower_width = 60 -wipe_tower_x = 180 -wipe_tower_y = 140 -xy_size_compensation = 0 - [print:0.20mm NORMAL SOLUBLE FULL] avoid_crossing_perimeters = 0 bottom_solid_layers = 4 @@ -2226,112 +2226,6 @@ wipe_tower_x = 180 wipe_tower_y = 140 xy_size_compensation = 0 -[print:0.35mm FAST MK3] -avoid_crossing_perimeters = 0 -bottom_solid_layers = 4 -bridge_acceleration = 1000 -bridge_angle = 0 -bridge_flow_ratio = 0.8 -bridge_speed = 30 -brim_width = 0 -clip_multipart_objects = 1 -compatible_printers = -compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ -complete_objects = 0 -default_acceleration = 1000 -dont_support_bridges = 1 -elefant_foot_compensation = 0 -ensure_vertical_shell_thickness = 1 -external_fill_pattern = rectilinear -external_perimeter_extrusion_width = 0.6 -external_perimeter_speed = 40 -external_perimeters_first = 0 -extra_perimeters = 0 -extruder_clearance_height = 20 -extruder_clearance_radius = 20 -extrusion_width = 0.45 -fill_angle = 45 -fill_density = 20% -fill_pattern = cubic -first_layer_acceleration = 1000 -first_layer_extrusion_width = 0.42 -first_layer_height = 0.2 -first_layer_speed = 30 -gap_fill_speed = 40 -gcode_comments = 0 -infill_acceleration = 3500 -infill_every_layers = 1 -infill_extruder = 1 -infill_extrusion_width = 0.7 -infill_first = 0 -infill_only_where_needed = 0 -infill_overlap = 25% -infill_speed = 200 -interface_shells = 0 -layer_height = 0.35 -max_print_speed = 250 -max_volumetric_extrusion_rate_slope_negative = 0 -max_volumetric_extrusion_rate_slope_positive = 0 -max_volumetric_speed = 0 -min_skirt_length = 4 -notes = -only_retract_when_crossing_perimeters = 0 -ooze_prevention = 0 -output_filename_format = [input_filename_base].gcode -overhangs = 0 -perimeter_acceleration = 800 -perimeter_extruder = 1 -perimeter_extrusion_width = 0.45 -perimeter_speed = 60 -perimeters = 2 -post_process = -print_settings_id = -raft_layers = 0 -resolution = 0 -seam_position = nearest -skirt_distance = 2 -skirt_height = 3 -skirts = 1 -small_perimeter_speed = 20 -solid_infill_below_area = 0 -solid_infill_every_layers = 0 -solid_infill_extruder = 1 -solid_infill_extrusion_width = 0.7 -solid_infill_speed = 200 -spiral_vase = 0 -standby_temperature_delta = -5 -support_material = 0 -support_material_angle = 0 -support_material_buildplate_only = 0 -support_material_contact_distance = 0.15 -support_material_enforce_layers = 0 -support_material_extruder = 0 -support_material_extrusion_width = 0.35 -support_material_interface_contact_loops = 0 -support_material_interface_extruder = 0 -support_material_interface_layers = 2 -support_material_interface_spacing = 0.2 -support_material_interface_speed = 100% -support_material_pattern = rectilinear -support_material_spacing = 2 -support_material_speed = 50 -support_material_synchronize_layers = 0 -support_material_threshold = 45 -support_material_with_sheath = 0 -support_material_xy_spacing = 60% -thin_walls = 0 -threads = 4 -top_infill_extrusion_width = 0.45 -top_solid_infill_speed = 50 -top_solid_layers = 4 -travel_speed = 250 -wipe_tower = 1 -wipe_tower_per_color_wipe = 15 -wipe_tower_width = 60 -wipe_tower_x = 180 -wipe_tower_y = 140 -xy_size_compensation = 0 - [print:0.35mm FAST sol full 0.6 nozzle] avoid_crossing_perimeters = 0 bottom_solid_layers = 3 @@ -2544,7 +2438,7 @@ wipe_tower_x = 180 wipe_tower_y = 140 xy_size_compensation = 0 -[filament:ColorFabb Brass Bronze 1.75mm] +[filament:ColorFabb Brass Bronze] bed_temperature = 60 bridge_fan_speed = 100 compatible_printers = @@ -2567,13 +2461,13 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 210 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 210 -[filament:ColorFabb HT 1.75mm] +[filament:ColorFabb HT] bed_temperature = 105 bridge_fan_speed = 30 compatible_printers = @@ -2598,7 +2492,7 @@ first_layer_temperature = 270 max_fan_speed = 20 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 270 @@ -2625,13 +2519,13 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 215 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 210 -[filament:ColorFabb Woodfil 1.75mm] +[filament:ColorFabb Woodfil] bed_temperature = 60 bridge_fan_speed = 100 compatible_printers = @@ -2654,13 +2548,13 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 200 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 200 -[filament:ColorFabb XT 1.75mm] +[filament:ColorFabb XT] bed_temperature = 90 bridge_fan_speed = 50 compatible_printers = @@ -2685,11 +2579,11 @@ first_layer_temperature = 260 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 270 -[filament:ColorFabb XT-CF20 1.75mm] +[filament:ColorFabb XT-CF20] bed_temperature = 90 bridge_fan_speed = 50 compatible_printers = @@ -2714,11 +2608,11 @@ first_layer_temperature = 260 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 260 -[filament:ColorFabb nGen 1.75mm] +[filament:ColorFabb nGen] bed_temperature = 85 bridge_fan_speed = 40 compatible_printers = @@ -2743,7 +2637,7 @@ first_layer_temperature = 240 max_fan_speed = 35 min_fan_speed = 20 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 240 @@ -2772,7 +2666,7 @@ first_layer_temperature = 260 max_fan_speed = 35 min_fan_speed = 20 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 260 @@ -2801,11 +2695,11 @@ first_layer_temperature = 230 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 240 -[filament:E3D PC-ABS 1.75mm] +[filament:E3D PC-ABS] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -2830,11 +2724,11 @@ first_layer_temperature = 270 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 270 -[filament:Fillamentum ABS 1.75mm] +[filament:Fillamentum ABS] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -2859,11 +2753,11 @@ first_layer_temperature = 240 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 240 -[filament:Fillamentum ASA 1.75mm] +[filament:Fillamentum ASA] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -2888,7 +2782,7 @@ first_layer_temperature = 265 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 265 @@ -2917,7 +2811,7 @@ first_layer_temperature = 260 max_fan_speed = 80 min_fan_speed = 80 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 260 @@ -2944,13 +2838,13 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 190 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 190 -[filament:Generic ABS 1.75mm] +[filament:Generic ABS] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -2975,11 +2869,11 @@ first_layer_temperature = 255 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 255 -[filament:Generic PET 1.75mm] +[filament:Generic PET] bed_temperature = 90 bridge_fan_speed = 50 compatible_printers = @@ -3004,11 +2898,11 @@ first_layer_temperature = 230 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 240 -[filament:Generic PLA 1.75mm] +[filament:Generic PLA] bed_temperature = 60 bridge_fan_speed = 100 compatible_printers = @@ -3031,9 +2925,9 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 215 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 210 @@ -3062,7 +2956,7 @@ first_layer_temperature = 270 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 270 @@ -3089,13 +2983,13 @@ filament_type = PVA first_layer_bed_temperature = 60 first_layer_temperature = 195 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 195 -[filament:Prusa ABS 1.75mm] +[filament:Prusa ABS] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -3120,11 +3014,11 @@ first_layer_temperature = 255 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 255 -[filament:Prusa HIPS 1.75mm] +[filament:Prusa HIPS] bed_temperature = 100 bridge_fan_speed = 50 compatible_printers = @@ -3149,11 +3043,11 @@ first_layer_temperature = 220 max_fan_speed = 20 min_fan_speed = 20 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 220 -[filament:Prusa PET 1.75mm] +[filament:Prusa PET] bed_temperature = 90 bridge_fan_speed = 50 compatible_printers = @@ -3178,11 +3072,11 @@ first_layer_temperature = 230 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 240 -[filament:Prusa PLA 1.75mm] +[filament:Prusa PLA] bed_temperature = 60 bridge_fan_speed = 100 compatible_printers = @@ -3205,9 +3099,9 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 215 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 210 @@ -3236,11 +3130,11 @@ first_layer_temperature = 220 max_fan_speed = 90 min_fan_speed = 70 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 230 -[filament:Taulman Bridge 1.75mm] +[filament:Taulman Bridge] bed_temperature = 50 bridge_fan_speed = 40 compatible_printers = @@ -3265,11 +3159,11 @@ first_layer_temperature = 240 max_fan_speed = 5 min_fan_speed = 0 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 250 -[filament:Taulman T-Glase 1.75mm] +[filament:Taulman T-Glase] bed_temperature = 90 bridge_fan_speed = 40 compatible_printers = @@ -3294,7 +3188,7 @@ first_layer_temperature = 240 max_fan_speed = 5 min_fan_speed = 0 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 240 @@ -3321,9 +3215,9 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 215 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 210 @@ -3352,7 +3246,7 @@ first_layer_temperature = 220 max_fan_speed = 100 min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 220 @@ -3361,7 +3255,7 @@ bed_shape = 0x0,250x0,250x210,0x210 before_layer_gcode = ;BEFORE_LAYER_CHANGE\n;[layer_z]\n\n between_objects_gcode = deretract_speed = 0 -end_gcode = G4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors +end_gcode = G4 ; wait\nM221 S100\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors extruder_colour = #FFFF00 extruder_offset = 0x0 gcode_flavor = reprap @@ -3386,7 +3280,7 @@ retract_speed = 35 serial_port = serial_speed = 250000 single_extruder_multi_material = 0 -start_gcode = M115 U3.1.1-RC4 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M115 U3.1.1-RC4 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S95 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 @@ -3398,4 +3292,4 @@ z_offset = 0 [presets] print = 0.15mm OPTIMAL MK3 printer = Original Prusa i3 MK3 -filament = Prusa PLA 1.75mm +filament = Prusa PLA From 7012c04005dae7e0f47a773e52c2c52dfba5eeab Mon Sep 17 00:00:00 2001 From: bubnikv Date: Fri, 5 Jan 2018 16:10:23 +0100 Subject: [PATCH 27/33] Updated the printer profiles. --- .../Original Prusa i3 MK2 and MK2S.ini | 450 +++++++---------- ...inal Prusa i3 MK2, MK2S, MK2MM and MK3.ini | 338 +++++-------- .../profiles/Original Prusa i3 MK2MM.ini | 454 +++++++----------- 3 files changed, 462 insertions(+), 780 deletions(-) diff --git a/resources/profiles/Original Prusa i3 MK2 and MK2S.ini b/resources/profiles/Original Prusa i3 MK2 and MK2S.ini index c70b07b03b..5cdb020f59 100644 --- a/resources/profiles/Original Prusa i3 MK2 and MK2S.ini +++ b/resources/profiles/Original Prusa i3 MK2 and MK2S.ini @@ -1,4 +1,4 @@ -# generated by Slic3r Prusa Edition 1.38.4 on 2017-12-21 at 17:48:59 +# generated by Slic3r Prusa Edition 1.38.6 on 2018-01-05 at 16:05:06 [print:0.05mm DETAIL] avoid_crossing_perimeters = 0 @@ -238,7 +238,7 @@ extruder_clearance_radius = 20 extrusion_width = 0.45 fill_angle = 45 fill_density = 25% -fill_pattern = cubic +fill_pattern = grid first_layer_acceleration = 500 first_layer_extrusion_width = 0.42 first_layer_height = 0.2 @@ -248,7 +248,7 @@ gcode_comments = 0 infill_acceleration = 800 infill_every_layers = 1 infill_extruder = 1 -infill_extrusion_width = 0.5 +infill_extrusion_width = 0.45 infill_first = 0 infill_only_where_needed = 0 infill_overlap = 25% @@ -307,7 +307,7 @@ support_material_with_sheath = 0 support_material_xy_spacing = 60% thin_walls = 0 threads = 4 -top_infill_extrusion_width = 0.45 +top_infill_extrusion_width = 0.4 top_solid_infill_speed = 20 top_solid_layers = 15 travel_speed = 180 @@ -548,7 +548,7 @@ elefant_foot_compensation = 0 ensure_vertical_shell_thickness = 1 external_fill_pattern = rectilinear external_perimeter_extrusion_width = 0.45 -external_perimeter_speed = 40 +external_perimeter_speed = 35 external_perimeters_first = 0 extra_perimeters = 0 extruder_clearance_height = 20 @@ -556,7 +556,7 @@ extruder_clearance_radius = 20 extrusion_width = 0.45 fill_angle = 45 fill_density = 20% -fill_pattern = cubic +fill_pattern = grid first_layer_acceleration = 1000 first_layer_extrusion_width = 0.42 first_layer_height = 0.2 @@ -586,7 +586,7 @@ overhangs = 0 perimeter_acceleration = 800 perimeter_extruder = 1 perimeter_extrusion_width = 0.45 -perimeter_speed = 60 +perimeter_speed = 45 perimeters = 2 post_process = print_settings_id = @@ -1078,7 +1078,7 @@ elefant_foot_compensation = 0 ensure_vertical_shell_thickness = 1 external_fill_pattern = rectilinear external_perimeter_extrusion_width = 0.45 -external_perimeter_speed = 40 +external_perimeter_speed = 35 external_perimeters_first = 0 extra_perimeters = 0 extruder_clearance_height = 20 @@ -1086,7 +1086,7 @@ extruder_clearance_radius = 20 extrusion_width = 0.45 fill_angle = 45 fill_density = 20% -fill_pattern = cubic +fill_pattern = grid first_layer_acceleration = 1000 first_layer_extrusion_width = 0.42 first_layer_height = 0.2 @@ -1116,7 +1116,7 @@ overhangs = 0 perimeter_acceleration = 800 perimeter_extruder = 1 perimeter_extrusion_width = 0.45 -perimeter_speed = 60 +perimeter_speed = 45 perimeters = 2 post_process = print_settings_id = @@ -1484,6 +1484,112 @@ wipe_tower_x = 180 wipe_tower_y = 140 xy_size_compensation = 0 +[print:0.20mm FAST MK3] +avoid_crossing_perimeters = 0 +bottom_solid_layers = 4 +bridge_acceleration = 1000 +bridge_angle = 0 +bridge_flow_ratio = 0.8 +bridge_speed = 30 +brim_width = 0 +clip_multipart_objects = 1 +compatible_printers = +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ +complete_objects = 0 +default_acceleration = 1000 +dont_support_bridges = 1 +elefant_foot_compensation = 0 +ensure_vertical_shell_thickness = 1 +external_fill_pattern = rectilinear +external_perimeter_extrusion_width = 0.45 +external_perimeter_speed = 35 +external_perimeters_first = 0 +extra_perimeters = 0 +extruder_clearance_height = 20 +extruder_clearance_radius = 20 +extrusion_width = 0.45 +fill_angle = 45 +fill_density = 20% +fill_pattern = grid +first_layer_acceleration = 1000 +first_layer_extrusion_width = 0.42 +first_layer_height = 0.2 +first_layer_speed = 30 +gap_fill_speed = 40 +gcode_comments = 0 +infill_acceleration = 3500 +infill_every_layers = 1 +infill_extruder = 1 +infill_extrusion_width = 0.45 +infill_first = 0 +infill_only_where_needed = 0 +infill_overlap = 25% +infill_speed = 200 +interface_shells = 0 +layer_height = 0.2 +max_print_speed = 250 +max_volumetric_extrusion_rate_slope_negative = 0 +max_volumetric_extrusion_rate_slope_positive = 0 +max_volumetric_speed = 0 +min_skirt_length = 4 +notes = +only_retract_when_crossing_perimeters = 0 +ooze_prevention = 0 +output_filename_format = [input_filename_base].gcode +overhangs = 0 +perimeter_acceleration = 800 +perimeter_extruder = 1 +perimeter_extrusion_width = 0.45 +perimeter_speed = 45 +perimeters = 2 +post_process = +print_settings_id = +raft_layers = 0 +resolution = 0 +seam_position = nearest +skirt_distance = 2 +skirt_height = 3 +skirts = 1 +small_perimeter_speed = 20 +solid_infill_below_area = 0 +solid_infill_every_layers = 0 +solid_infill_extruder = 1 +solid_infill_extrusion_width = 0.45 +solid_infill_speed = 200 +spiral_vase = 0 +standby_temperature_delta = -5 +support_material = 0 +support_material_angle = 0 +support_material_buildplate_only = 0 +support_material_contact_distance = 0.15 +support_material_enforce_layers = 0 +support_material_extruder = 0 +support_material_extrusion_width = 0.35 +support_material_interface_contact_loops = 0 +support_material_interface_extruder = 0 +support_material_interface_layers = 2 +support_material_interface_spacing = 0.2 +support_material_interface_speed = 100% +support_material_pattern = rectilinear +support_material_spacing = 2 +support_material_speed = 50 +support_material_synchronize_layers = 0 +support_material_threshold = 45 +support_material_with_sheath = 0 +support_material_xy_spacing = 60% +thin_walls = 0 +threads = 4 +top_infill_extrusion_width = 0.4 +top_solid_infill_speed = 50 +top_solid_layers = 5 +travel_speed = 250 +wipe_tower = 1 +wipe_tower_per_color_wipe = 15 +wipe_tower_width = 60 +wipe_tower_x = 180 +wipe_tower_y = 140 +xy_size_compensation = 0 + [print:0.20mm NORMAL] avoid_crossing_perimeters = 0 bottom_solid_layers = 4 @@ -1696,112 +1802,6 @@ wipe_tower_x = 180 wipe_tower_y = 140 xy_size_compensation = 0 -[print:0.20mm NORMAL MK3] -avoid_crossing_perimeters = 0 -bottom_solid_layers = 4 -bridge_acceleration = 1000 -bridge_angle = 0 -bridge_flow_ratio = 0.8 -bridge_speed = 30 -brim_width = 0 -clip_multipart_objects = 1 -compatible_printers = -compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ -complete_objects = 0 -default_acceleration = 1000 -dont_support_bridges = 1 -elefant_foot_compensation = 0 -ensure_vertical_shell_thickness = 1 -external_fill_pattern = rectilinear -external_perimeter_extrusion_width = 0.45 -external_perimeter_speed = 40 -external_perimeters_first = 0 -extra_perimeters = 0 -extruder_clearance_height = 20 -extruder_clearance_radius = 20 -extrusion_width = 0.45 -fill_angle = 45 -fill_density = 20% -fill_pattern = cubic -first_layer_acceleration = 1000 -first_layer_extrusion_width = 0.42 -first_layer_height = 0.2 -first_layer_speed = 30 -gap_fill_speed = 40 -gcode_comments = 0 -infill_acceleration = 3500 -infill_every_layers = 1 -infill_extruder = 1 -infill_extrusion_width = 0.45 -infill_first = 0 -infill_only_where_needed = 0 -infill_overlap = 25% -infill_speed = 200 -interface_shells = 0 -layer_height = 0.2 -max_print_speed = 250 -max_volumetric_extrusion_rate_slope_negative = 0 -max_volumetric_extrusion_rate_slope_positive = 0 -max_volumetric_speed = 0 -min_skirt_length = 4 -notes = -only_retract_when_crossing_perimeters = 0 -ooze_prevention = 0 -output_filename_format = [input_filename_base].gcode -overhangs = 0 -perimeter_acceleration = 800 -perimeter_extruder = 1 -perimeter_extrusion_width = 0.45 -perimeter_speed = 60 -perimeters = 2 -post_process = -print_settings_id = -raft_layers = 0 -resolution = 0 -seam_position = nearest -skirt_distance = 2 -skirt_height = 3 -skirts = 1 -small_perimeter_speed = 20 -solid_infill_below_area = 0 -solid_infill_every_layers = 0 -solid_infill_extruder = 1 -solid_infill_extrusion_width = 0.45 -solid_infill_speed = 200 -spiral_vase = 0 -standby_temperature_delta = -5 -support_material = 0 -support_material_angle = 0 -support_material_buildplate_only = 0 -support_material_contact_distance = 0.15 -support_material_enforce_layers = 0 -support_material_extruder = 0 -support_material_extrusion_width = 0.35 -support_material_interface_contact_loops = 0 -support_material_interface_extruder = 0 -support_material_interface_layers = 2 -support_material_interface_spacing = 0.2 -support_material_interface_speed = 100% -support_material_pattern = rectilinear -support_material_spacing = 2 -support_material_speed = 50 -support_material_synchronize_layers = 0 -support_material_threshold = 45 -support_material_with_sheath = 0 -support_material_xy_spacing = 60% -thin_walls = 0 -threads = 4 -top_infill_extrusion_width = 0.4 -top_solid_infill_speed = 50 -top_solid_layers = 5 -travel_speed = 250 -wipe_tower = 1 -wipe_tower_per_color_wipe = 15 -wipe_tower_width = 60 -wipe_tower_x = 180 -wipe_tower_y = 140 -xy_size_compensation = 0 - [print:0.20mm NORMAL SOLUBLE FULL] avoid_crossing_perimeters = 0 bottom_solid_layers = 4 @@ -2226,112 +2226,6 @@ wipe_tower_x = 180 wipe_tower_y = 140 xy_size_compensation = 0 -[print:0.35mm FAST MK3] -avoid_crossing_perimeters = 0 -bottom_solid_layers = 4 -bridge_acceleration = 1000 -bridge_angle = 0 -bridge_flow_ratio = 0.8 -bridge_speed = 30 -brim_width = 0 -clip_multipart_objects = 1 -compatible_printers = -compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ -complete_objects = 0 -default_acceleration = 1000 -dont_support_bridges = 1 -elefant_foot_compensation = 0 -ensure_vertical_shell_thickness = 1 -external_fill_pattern = rectilinear -external_perimeter_extrusion_width = 0.6 -external_perimeter_speed = 40 -external_perimeters_first = 0 -extra_perimeters = 0 -extruder_clearance_height = 20 -extruder_clearance_radius = 20 -extrusion_width = 0.45 -fill_angle = 45 -fill_density = 20% -fill_pattern = cubic -first_layer_acceleration = 1000 -first_layer_extrusion_width = 0.42 -first_layer_height = 0.2 -first_layer_speed = 30 -gap_fill_speed = 40 -gcode_comments = 0 -infill_acceleration = 3500 -infill_every_layers = 1 -infill_extruder = 1 -infill_extrusion_width = 0.7 -infill_first = 0 -infill_only_where_needed = 0 -infill_overlap = 25% -infill_speed = 200 -interface_shells = 0 -layer_height = 0.35 -max_print_speed = 250 -max_volumetric_extrusion_rate_slope_negative = 0 -max_volumetric_extrusion_rate_slope_positive = 0 -max_volumetric_speed = 0 -min_skirt_length = 4 -notes = -only_retract_when_crossing_perimeters = 0 -ooze_prevention = 0 -output_filename_format = [input_filename_base].gcode -overhangs = 0 -perimeter_acceleration = 800 -perimeter_extruder = 1 -perimeter_extrusion_width = 0.45 -perimeter_speed = 60 -perimeters = 2 -post_process = -print_settings_id = -raft_layers = 0 -resolution = 0 -seam_position = nearest -skirt_distance = 2 -skirt_height = 3 -skirts = 1 -small_perimeter_speed = 20 -solid_infill_below_area = 0 -solid_infill_every_layers = 0 -solid_infill_extruder = 1 -solid_infill_extrusion_width = 0.7 -solid_infill_speed = 200 -spiral_vase = 0 -standby_temperature_delta = -5 -support_material = 0 -support_material_angle = 0 -support_material_buildplate_only = 0 -support_material_contact_distance = 0.15 -support_material_enforce_layers = 0 -support_material_extruder = 0 -support_material_extrusion_width = 0.35 -support_material_interface_contact_loops = 0 -support_material_interface_extruder = 0 -support_material_interface_layers = 2 -support_material_interface_spacing = 0.2 -support_material_interface_speed = 100% -support_material_pattern = rectilinear -support_material_spacing = 2 -support_material_speed = 50 -support_material_synchronize_layers = 0 -support_material_threshold = 45 -support_material_with_sheath = 0 -support_material_xy_spacing = 60% -thin_walls = 0 -threads = 4 -top_infill_extrusion_width = 0.45 -top_solid_infill_speed = 50 -top_solid_layers = 4 -travel_speed = 250 -wipe_tower = 1 -wipe_tower_per_color_wipe = 15 -wipe_tower_width = 60 -wipe_tower_x = 180 -wipe_tower_y = 140 -xy_size_compensation = 0 - [print:0.35mm FAST sol full 0.6 nozzle] avoid_crossing_perimeters = 0 bottom_solid_layers = 3 @@ -2544,7 +2438,7 @@ wipe_tower_x = 180 wipe_tower_y = 140 xy_size_compensation = 0 -[filament:ColorFabb Brass Bronze 1.75mm] +[filament:ColorFabb Brass Bronze] bed_temperature = 60 bridge_fan_speed = 100 compatible_printers = @@ -2567,13 +2461,13 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 210 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 210 -[filament:ColorFabb HT 1.75mm] +[filament:ColorFabb HT] bed_temperature = 105 bridge_fan_speed = 30 compatible_printers = @@ -2598,7 +2492,7 @@ first_layer_temperature = 270 max_fan_speed = 20 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 270 @@ -2625,13 +2519,13 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 215 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 210 -[filament:ColorFabb Woodfil 1.75mm] +[filament:ColorFabb Woodfil] bed_temperature = 60 bridge_fan_speed = 100 compatible_printers = @@ -2654,13 +2548,13 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 200 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 200 -[filament:ColorFabb XT 1.75mm] +[filament:ColorFabb XT] bed_temperature = 90 bridge_fan_speed = 50 compatible_printers = @@ -2685,11 +2579,11 @@ first_layer_temperature = 260 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 270 -[filament:ColorFabb XT-CF20 1.75mm] +[filament:ColorFabb XT-CF20] bed_temperature = 90 bridge_fan_speed = 50 compatible_printers = @@ -2714,11 +2608,11 @@ first_layer_temperature = 260 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 260 -[filament:ColorFabb nGen 1.75mm] +[filament:ColorFabb nGen] bed_temperature = 85 bridge_fan_speed = 40 compatible_printers = @@ -2743,7 +2637,7 @@ first_layer_temperature = 240 max_fan_speed = 35 min_fan_speed = 20 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 240 @@ -2772,7 +2666,7 @@ first_layer_temperature = 260 max_fan_speed = 35 min_fan_speed = 20 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 260 @@ -2801,11 +2695,11 @@ first_layer_temperature = 230 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 240 -[filament:E3D PC-ABS 1.75mm] +[filament:E3D PC-ABS] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -2830,11 +2724,11 @@ first_layer_temperature = 270 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 270 -[filament:Fillamentum ABS 1.75mm] +[filament:Fillamentum ABS] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -2859,11 +2753,11 @@ first_layer_temperature = 240 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 240 -[filament:Fillamentum ASA 1.75mm] +[filament:Fillamentum ASA] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -2888,7 +2782,7 @@ first_layer_temperature = 265 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 265 @@ -2917,7 +2811,7 @@ first_layer_temperature = 260 max_fan_speed = 80 min_fan_speed = 80 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 260 @@ -2944,13 +2838,13 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 190 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 190 -[filament:Generic ABS 1.75mm] +[filament:Generic ABS] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -2975,11 +2869,11 @@ first_layer_temperature = 255 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 255 -[filament:Generic PET 1.75mm] +[filament:Generic PET] bed_temperature = 90 bridge_fan_speed = 50 compatible_printers = @@ -3004,11 +2898,11 @@ first_layer_temperature = 230 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 240 -[filament:Generic PLA 1.75mm] +[filament:Generic PLA] bed_temperature = 60 bridge_fan_speed = 100 compatible_printers = @@ -3031,9 +2925,9 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 215 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 210 @@ -3062,7 +2956,7 @@ first_layer_temperature = 270 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 270 @@ -3089,13 +2983,13 @@ filament_type = PVA first_layer_bed_temperature = 60 first_layer_temperature = 195 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 195 -[filament:Prusa ABS 1.75mm] +[filament:Prusa ABS] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -3120,11 +3014,11 @@ first_layer_temperature = 255 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 255 -[filament:Prusa HIPS 1.75mm] +[filament:Prusa HIPS] bed_temperature = 100 bridge_fan_speed = 50 compatible_printers = @@ -3149,11 +3043,11 @@ first_layer_temperature = 220 max_fan_speed = 20 min_fan_speed = 20 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 220 -[filament:Prusa PET 1.75mm] +[filament:Prusa PET] bed_temperature = 90 bridge_fan_speed = 50 compatible_printers = @@ -3178,11 +3072,11 @@ first_layer_temperature = 230 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 240 -[filament:Prusa PLA 1.75mm] +[filament:Prusa PLA] bed_temperature = 60 bridge_fan_speed = 100 compatible_printers = @@ -3205,9 +3099,9 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 215 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 210 @@ -3236,11 +3130,11 @@ first_layer_temperature = 220 max_fan_speed = 90 min_fan_speed = 70 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 230 -[filament:Taulman Bridge 1.75mm] +[filament:Taulman Bridge] bed_temperature = 50 bridge_fan_speed = 40 compatible_printers = @@ -3265,11 +3159,11 @@ first_layer_temperature = 240 max_fan_speed = 5 min_fan_speed = 0 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 250 -[filament:Taulman T-Glase 1.75mm] +[filament:Taulman T-Glase] bed_temperature = 90 bridge_fan_speed = 40 compatible_printers = @@ -3294,7 +3188,7 @@ first_layer_temperature = 240 max_fan_speed = 5 min_fan_speed = 0 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 240 @@ -3321,9 +3215,9 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 215 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 210 @@ -3352,7 +3246,7 @@ first_layer_temperature = 220 max_fan_speed = 100 min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 220 @@ -3477,6 +3371,6 @@ wipe = 1 z_offset = 0 [presets] -print = 0.15mm 100mms Linear Advance +print = 0.15mm OPTIMAL printer = Original Prusa i3 MK2 -filament = Prusa PLA 1.75mm +filament = Prusa PLA diff --git a/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini b/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini index 160bece781..9513eee365 100644 --- a/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini +++ b/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini @@ -1,4 +1,4 @@ -# generated by Slic3r Prusa Edition 1.38.4.17-prusa3d-win32 on 2018-01-04 at 17:24:45 +# generated by Slic3r Prusa Edition 1.38.6 on 2018-01-05 at 16:03:38 [print:0.05mm DETAIL] avoid_crossing_perimeters = 0 @@ -238,7 +238,7 @@ extruder_clearance_radius = 20 extrusion_width = 0.45 fill_angle = 45 fill_density = 25% -fill_pattern = cubic +fill_pattern = grid first_layer_acceleration = 500 first_layer_extrusion_width = 0.42 first_layer_height = 0.2 @@ -532,7 +532,7 @@ xy_size_compensation = 0 [print:0.10mm DETAIL MK3] avoid_crossing_perimeters = 0 -bottom_solid_layers = 7 +bottom_solid_layers = 4 bridge_acceleration = 1000 bridge_angle = 0 bridge_flow_ratio = 0.8 @@ -556,7 +556,7 @@ extruder_clearance_radius = 20 extrusion_width = 0.45 fill_angle = 45 fill_density = 20% -fill_pattern = cubic +fill_pattern = grid first_layer_acceleration = 1000 first_layer_extrusion_width = 0.42 first_layer_height = 0.2 @@ -627,7 +627,7 @@ thin_walls = 0 threads = 4 top_infill_extrusion_width = 0.4 top_solid_infill_speed = 50 -top_solid_layers = 9 +top_solid_layers = 5 travel_speed = 250 wipe_tower = 0 wipe_tower_per_color_wipe = 15 @@ -1062,7 +1062,7 @@ xy_size_compensation = 0 [print:0.15mm OPTIMAL MK3] avoid_crossing_perimeters = 0 -bottom_solid_layers = 5 +bottom_solid_layers = 4 bridge_acceleration = 1000 bridge_angle = 0 bridge_flow_ratio = 0.8 @@ -1086,7 +1086,7 @@ extruder_clearance_radius = 20 extrusion_width = 0.45 fill_angle = 45 fill_density = 20% -fill_pattern = cubic +fill_pattern = grid first_layer_acceleration = 1000 first_layer_extrusion_width = 0.42 first_layer_height = 0.2 @@ -1157,7 +1157,7 @@ thin_walls = 0 threads = 4 top_infill_extrusion_width = 0.4 top_solid_infill_speed = 50 -top_solid_layers = 7 +top_solid_layers = 5 travel_speed = 250 wipe_tower = 1 wipe_tower_per_color_wipe = 15 @@ -1484,6 +1484,112 @@ wipe_tower_x = 180 wipe_tower_y = 140 xy_size_compensation = 0 +[print:0.20mm FAST MK3] +avoid_crossing_perimeters = 0 +bottom_solid_layers = 4 +bridge_acceleration = 1000 +bridge_angle = 0 +bridge_flow_ratio = 0.8 +bridge_speed = 30 +brim_width = 0 +clip_multipart_objects = 1 +compatible_printers = +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ +complete_objects = 0 +default_acceleration = 1000 +dont_support_bridges = 1 +elefant_foot_compensation = 0 +ensure_vertical_shell_thickness = 1 +external_fill_pattern = rectilinear +external_perimeter_extrusion_width = 0.45 +external_perimeter_speed = 35 +external_perimeters_first = 0 +extra_perimeters = 0 +extruder_clearance_height = 20 +extruder_clearance_radius = 20 +extrusion_width = 0.45 +fill_angle = 45 +fill_density = 20% +fill_pattern = grid +first_layer_acceleration = 1000 +first_layer_extrusion_width = 0.42 +first_layer_height = 0.2 +first_layer_speed = 30 +gap_fill_speed = 40 +gcode_comments = 0 +infill_acceleration = 3500 +infill_every_layers = 1 +infill_extruder = 1 +infill_extrusion_width = 0.45 +infill_first = 0 +infill_only_where_needed = 0 +infill_overlap = 25% +infill_speed = 200 +interface_shells = 0 +layer_height = 0.2 +max_print_speed = 250 +max_volumetric_extrusion_rate_slope_negative = 0 +max_volumetric_extrusion_rate_slope_positive = 0 +max_volumetric_speed = 0 +min_skirt_length = 4 +notes = +only_retract_when_crossing_perimeters = 0 +ooze_prevention = 0 +output_filename_format = [input_filename_base].gcode +overhangs = 0 +perimeter_acceleration = 800 +perimeter_extruder = 1 +perimeter_extrusion_width = 0.45 +perimeter_speed = 45 +perimeters = 2 +post_process = +print_settings_id = +raft_layers = 0 +resolution = 0 +seam_position = nearest +skirt_distance = 2 +skirt_height = 3 +skirts = 1 +small_perimeter_speed = 20 +solid_infill_below_area = 0 +solid_infill_every_layers = 0 +solid_infill_extruder = 1 +solid_infill_extrusion_width = 0.45 +solid_infill_speed = 200 +spiral_vase = 0 +standby_temperature_delta = -5 +support_material = 0 +support_material_angle = 0 +support_material_buildplate_only = 0 +support_material_contact_distance = 0.15 +support_material_enforce_layers = 0 +support_material_extruder = 0 +support_material_extrusion_width = 0.35 +support_material_interface_contact_loops = 0 +support_material_interface_extruder = 0 +support_material_interface_layers = 2 +support_material_interface_spacing = 0.2 +support_material_interface_speed = 100% +support_material_pattern = rectilinear +support_material_spacing = 2 +support_material_speed = 50 +support_material_synchronize_layers = 0 +support_material_threshold = 45 +support_material_with_sheath = 0 +support_material_xy_spacing = 60% +thin_walls = 0 +threads = 4 +top_infill_extrusion_width = 0.4 +top_solid_infill_speed = 50 +top_solid_layers = 5 +travel_speed = 250 +wipe_tower = 1 +wipe_tower_per_color_wipe = 15 +wipe_tower_width = 60 +wipe_tower_x = 180 +wipe_tower_y = 140 +xy_size_compensation = 0 + [print:0.20mm NORMAL] avoid_crossing_perimeters = 0 bottom_solid_layers = 4 @@ -1696,112 +1802,6 @@ wipe_tower_x = 180 wipe_tower_y = 140 xy_size_compensation = 0 -[print:0.20mm NORMAL MK3] -avoid_crossing_perimeters = 0 -bottom_solid_layers = 4 -bridge_acceleration = 1000 -bridge_angle = 0 -bridge_flow_ratio = 0.8 -bridge_speed = 30 -brim_width = 0 -clip_multipart_objects = 1 -compatible_printers = -compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ -complete_objects = 0 -default_acceleration = 1000 -dont_support_bridges = 1 -elefant_foot_compensation = 0 -ensure_vertical_shell_thickness = 1 -external_fill_pattern = rectilinear -external_perimeter_extrusion_width = 0.45 -external_perimeter_speed = 35 -external_perimeters_first = 0 -extra_perimeters = 0 -extruder_clearance_height = 20 -extruder_clearance_radius = 20 -extrusion_width = 0.45 -fill_angle = 45 -fill_density = 20% -fill_pattern = cubic -first_layer_acceleration = 1000 -first_layer_extrusion_width = 0.42 -first_layer_height = 0.2 -first_layer_speed = 30 -gap_fill_speed = 40 -gcode_comments = 0 -infill_acceleration = 3500 -infill_every_layers = 1 -infill_extruder = 1 -infill_extrusion_width = 0.45 -infill_first = 0 -infill_only_where_needed = 0 -infill_overlap = 25% -infill_speed = 200 -interface_shells = 0 -layer_height = 0.2 -max_print_speed = 250 -max_volumetric_extrusion_rate_slope_negative = 0 -max_volumetric_extrusion_rate_slope_positive = 0 -max_volumetric_speed = 0 -min_skirt_length = 4 -notes = -only_retract_when_crossing_perimeters = 0 -ooze_prevention = 0 -output_filename_format = [input_filename_base].gcode -overhangs = 0 -perimeter_acceleration = 800 -perimeter_extruder = 1 -perimeter_extrusion_width = 0.45 -perimeter_speed = 45 -perimeters = 2 -post_process = -print_settings_id = -raft_layers = 0 -resolution = 0 -seam_position = nearest -skirt_distance = 2 -skirt_height = 3 -skirts = 1 -small_perimeter_speed = 20 -solid_infill_below_area = 0 -solid_infill_every_layers = 0 -solid_infill_extruder = 1 -solid_infill_extrusion_width = 0.45 -solid_infill_speed = 200 -spiral_vase = 0 -standby_temperature_delta = -5 -support_material = 0 -support_material_angle = 0 -support_material_buildplate_only = 0 -support_material_contact_distance = 0.15 -support_material_enforce_layers = 0 -support_material_extruder = 0 -support_material_extrusion_width = 0.35 -support_material_interface_contact_loops = 0 -support_material_interface_extruder = 0 -support_material_interface_layers = 2 -support_material_interface_spacing = 0.2 -support_material_interface_speed = 100% -support_material_pattern = rectilinear -support_material_spacing = 2 -support_material_speed = 50 -support_material_synchronize_layers = 0 -support_material_threshold = 45 -support_material_with_sheath = 0 -support_material_xy_spacing = 60% -thin_walls = 0 -threads = 4 -top_infill_extrusion_width = 0.4 -top_solid_infill_speed = 50 -top_solid_layers = 5 -travel_speed = 250 -wipe_tower = 1 -wipe_tower_per_color_wipe = 15 -wipe_tower_width = 60 -wipe_tower_x = 180 -wipe_tower_y = 140 -xy_size_compensation = 0 - [print:0.20mm NORMAL SOLUBLE FULL] avoid_crossing_perimeters = 0 bottom_solid_layers = 4 @@ -2226,112 +2226,6 @@ wipe_tower_x = 180 wipe_tower_y = 140 xy_size_compensation = 0 -[print:0.35mm FAST MK3] -avoid_crossing_perimeters = 0 -bottom_solid_layers = 4 -bridge_acceleration = 1000 -bridge_angle = 0 -bridge_flow_ratio = 0.8 -bridge_speed = 30 -brim_width = 0 -clip_multipart_objects = 1 -compatible_printers = -compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ -complete_objects = 0 -default_acceleration = 1000 -dont_support_bridges = 1 -elefant_foot_compensation = 0 -ensure_vertical_shell_thickness = 1 -external_fill_pattern = rectilinear -external_perimeter_extrusion_width = 0.45 -external_perimeter_speed = 35 -external_perimeters_first = 0 -extra_perimeters = 0 -extruder_clearance_height = 20 -extruder_clearance_radius = 20 -extrusion_width = 0.45 -fill_angle = 45 -fill_density = 10% -fill_pattern = rectilinear -first_layer_acceleration = 1000 -first_layer_extrusion_width = 0.42 -first_layer_height = 0.2 -first_layer_speed = 30 -gap_fill_speed = 40 -gcode_comments = 0 -infill_acceleration = 3500 -infill_every_layers = 1 -infill_extruder = 1 -infill_extrusion_width = 0.45 -infill_first = 0 -infill_only_where_needed = 0 -infill_overlap = 25% -infill_speed = 200 -interface_shells = 0 -layer_height = 0.35 -max_print_speed = 250 -max_volumetric_extrusion_rate_slope_negative = 0 -max_volumetric_extrusion_rate_slope_positive = 0 -max_volumetric_speed = 0 -min_skirt_length = 4 -notes = -only_retract_when_crossing_perimeters = 0 -ooze_prevention = 0 -output_filename_format = [input_filename_base].gcode -overhangs = 0 -perimeter_acceleration = 800 -perimeter_extruder = 1 -perimeter_extrusion_width = 0.45 -perimeter_speed = 45 -perimeters = 2 -post_process = -print_settings_id = -raft_layers = 0 -resolution = 0 -seam_position = nearest -skirt_distance = 2 -skirt_height = 3 -skirts = 1 -small_perimeter_speed = 20 -solid_infill_below_area = 0 -solid_infill_every_layers = 0 -solid_infill_extruder = 1 -solid_infill_extrusion_width = 0.45 -solid_infill_speed = 200 -spiral_vase = 0 -standby_temperature_delta = -5 -support_material = 0 -support_material_angle = 0 -support_material_buildplate_only = 0 -support_material_contact_distance = 0.15 -support_material_enforce_layers = 0 -support_material_extruder = 0 -support_material_extrusion_width = 0.35 -support_material_interface_contact_loops = 0 -support_material_interface_extruder = 0 -support_material_interface_layers = 2 -support_material_interface_spacing = 0.2 -support_material_interface_speed = 100% -support_material_pattern = rectilinear -support_material_spacing = 2 -support_material_speed = 50 -support_material_synchronize_layers = 0 -support_material_threshold = 45 -support_material_with_sheath = 0 -support_material_xy_spacing = 60% -thin_walls = 0 -threads = 4 -top_infill_extrusion_width = 0.45 -top_solid_infill_speed = 50 -top_solid_layers = 4 -travel_speed = 250 -wipe_tower = 1 -wipe_tower_per_color_wipe = 15 -wipe_tower_width = 60 -wipe_tower_x = 180 -wipe_tower_y = 140 -xy_size_compensation = 0 - [print:0.35mm FAST sol full 0.6 nozzle] avoid_crossing_perimeters = 0 bottom_solid_layers = 3 @@ -3656,7 +3550,7 @@ retract_before_travel = 1 retract_before_wipe = 0% retract_layer_change = 1 retract_length = 0.8 -retract_length_toolchange = 4 +retract_length_toolchange = 3 retract_lift = 0.6 retract_lift_above = 0 retract_lift_below = 209 @@ -3676,6 +3570,6 @@ wipe = 1 z_offset = 0 [presets] -print = 0.20mm NORMAL MK3 +print = 0.05mm DETAIL MK3 printer = Original Prusa i3 MK3 filament = Prusa PLA diff --git a/resources/profiles/Original Prusa i3 MK2MM.ini b/resources/profiles/Original Prusa i3 MK2MM.ini index abcb90ec41..aba80c992c 100644 --- a/resources/profiles/Original Prusa i3 MK2MM.ini +++ b/resources/profiles/Original Prusa i3 MK2MM.ini @@ -1,4 +1,4 @@ -# generated by Slic3r Prusa Edition 1.38.4 on 2017-12-21 at 19:24:41 +# generated by Slic3r Prusa Edition 1.38.6 on 2018-01-05 at 16:05:58 [print:0.05mm DETAIL] avoid_crossing_perimeters = 0 @@ -238,7 +238,7 @@ extruder_clearance_radius = 20 extrusion_width = 0.45 fill_angle = 45 fill_density = 25% -fill_pattern = cubic +fill_pattern = grid first_layer_acceleration = 500 first_layer_extrusion_width = 0.42 first_layer_height = 0.2 @@ -248,7 +248,7 @@ gcode_comments = 0 infill_acceleration = 800 infill_every_layers = 1 infill_extruder = 1 -infill_extrusion_width = 0.5 +infill_extrusion_width = 0.45 infill_first = 0 infill_only_where_needed = 0 infill_overlap = 25% @@ -307,7 +307,7 @@ support_material_with_sheath = 0 support_material_xy_spacing = 60% thin_walls = 0 threads = 4 -top_infill_extrusion_width = 0.45 +top_infill_extrusion_width = 0.4 top_solid_infill_speed = 20 top_solid_layers = 15 travel_speed = 180 @@ -548,7 +548,7 @@ elefant_foot_compensation = 0 ensure_vertical_shell_thickness = 1 external_fill_pattern = rectilinear external_perimeter_extrusion_width = 0.45 -external_perimeter_speed = 40 +external_perimeter_speed = 35 external_perimeters_first = 0 extra_perimeters = 0 extruder_clearance_height = 20 @@ -556,7 +556,7 @@ extruder_clearance_radius = 20 extrusion_width = 0.45 fill_angle = 45 fill_density = 20% -fill_pattern = cubic +fill_pattern = grid first_layer_acceleration = 1000 first_layer_extrusion_width = 0.42 first_layer_height = 0.2 @@ -586,7 +586,7 @@ overhangs = 0 perimeter_acceleration = 800 perimeter_extruder = 1 perimeter_extrusion_width = 0.45 -perimeter_speed = 60 +perimeter_speed = 45 perimeters = 2 post_process = print_settings_id = @@ -1078,7 +1078,7 @@ elefant_foot_compensation = 0 ensure_vertical_shell_thickness = 1 external_fill_pattern = rectilinear external_perimeter_extrusion_width = 0.45 -external_perimeter_speed = 40 +external_perimeter_speed = 35 external_perimeters_first = 0 extra_perimeters = 0 extruder_clearance_height = 20 @@ -1086,7 +1086,7 @@ extruder_clearance_radius = 20 extrusion_width = 0.45 fill_angle = 45 fill_density = 20% -fill_pattern = cubic +fill_pattern = grid first_layer_acceleration = 1000 first_layer_extrusion_width = 0.42 first_layer_height = 0.2 @@ -1116,7 +1116,7 @@ overhangs = 0 perimeter_acceleration = 800 perimeter_extruder = 1 perimeter_extrusion_width = 0.45 -perimeter_speed = 60 +perimeter_speed = 45 perimeters = 2 post_process = print_settings_id = @@ -1484,6 +1484,112 @@ wipe_tower_x = 180 wipe_tower_y = 140 xy_size_compensation = 0 +[print:0.20mm FAST MK3] +avoid_crossing_perimeters = 0 +bottom_solid_layers = 4 +bridge_acceleration = 1000 +bridge_angle = 0 +bridge_flow_ratio = 0.8 +bridge_speed = 30 +brim_width = 0 +clip_multipart_objects = 1 +compatible_printers = +compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ +complete_objects = 0 +default_acceleration = 1000 +dont_support_bridges = 1 +elefant_foot_compensation = 0 +ensure_vertical_shell_thickness = 1 +external_fill_pattern = rectilinear +external_perimeter_extrusion_width = 0.45 +external_perimeter_speed = 35 +external_perimeters_first = 0 +extra_perimeters = 0 +extruder_clearance_height = 20 +extruder_clearance_radius = 20 +extrusion_width = 0.45 +fill_angle = 45 +fill_density = 20% +fill_pattern = grid +first_layer_acceleration = 1000 +first_layer_extrusion_width = 0.42 +first_layer_height = 0.2 +first_layer_speed = 30 +gap_fill_speed = 40 +gcode_comments = 0 +infill_acceleration = 3500 +infill_every_layers = 1 +infill_extruder = 1 +infill_extrusion_width = 0.45 +infill_first = 0 +infill_only_where_needed = 0 +infill_overlap = 25% +infill_speed = 200 +interface_shells = 0 +layer_height = 0.2 +max_print_speed = 250 +max_volumetric_extrusion_rate_slope_negative = 0 +max_volumetric_extrusion_rate_slope_positive = 0 +max_volumetric_speed = 0 +min_skirt_length = 4 +notes = +only_retract_when_crossing_perimeters = 0 +ooze_prevention = 0 +output_filename_format = [input_filename_base].gcode +overhangs = 0 +perimeter_acceleration = 800 +perimeter_extruder = 1 +perimeter_extrusion_width = 0.45 +perimeter_speed = 45 +perimeters = 2 +post_process = +print_settings_id = +raft_layers = 0 +resolution = 0 +seam_position = nearest +skirt_distance = 2 +skirt_height = 3 +skirts = 1 +small_perimeter_speed = 20 +solid_infill_below_area = 0 +solid_infill_every_layers = 0 +solid_infill_extruder = 1 +solid_infill_extrusion_width = 0.45 +solid_infill_speed = 200 +spiral_vase = 0 +standby_temperature_delta = -5 +support_material = 0 +support_material_angle = 0 +support_material_buildplate_only = 0 +support_material_contact_distance = 0.15 +support_material_enforce_layers = 0 +support_material_extruder = 0 +support_material_extrusion_width = 0.35 +support_material_interface_contact_loops = 0 +support_material_interface_extruder = 0 +support_material_interface_layers = 2 +support_material_interface_spacing = 0.2 +support_material_interface_speed = 100% +support_material_pattern = rectilinear +support_material_spacing = 2 +support_material_speed = 50 +support_material_synchronize_layers = 0 +support_material_threshold = 45 +support_material_with_sheath = 0 +support_material_xy_spacing = 60% +thin_walls = 0 +threads = 4 +top_infill_extrusion_width = 0.4 +top_solid_infill_speed = 50 +top_solid_layers = 5 +travel_speed = 250 +wipe_tower = 1 +wipe_tower_per_color_wipe = 15 +wipe_tower_width = 60 +wipe_tower_x = 180 +wipe_tower_y = 140 +xy_size_compensation = 0 + [print:0.20mm NORMAL] avoid_crossing_perimeters = 0 bottom_solid_layers = 4 @@ -1696,112 +1802,6 @@ wipe_tower_x = 180 wipe_tower_y = 140 xy_size_compensation = 0 -[print:0.20mm NORMAL MK3] -avoid_crossing_perimeters = 0 -bottom_solid_layers = 4 -bridge_acceleration = 1000 -bridge_angle = 0 -bridge_flow_ratio = 0.8 -bridge_speed = 30 -brim_width = 0 -clip_multipart_objects = 1 -compatible_printers = -compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ -complete_objects = 0 -default_acceleration = 1000 -dont_support_bridges = 1 -elefant_foot_compensation = 0 -ensure_vertical_shell_thickness = 1 -external_fill_pattern = rectilinear -external_perimeter_extrusion_width = 0.45 -external_perimeter_speed = 40 -external_perimeters_first = 0 -extra_perimeters = 0 -extruder_clearance_height = 20 -extruder_clearance_radius = 20 -extrusion_width = 0.45 -fill_angle = 45 -fill_density = 20% -fill_pattern = cubic -first_layer_acceleration = 1000 -first_layer_extrusion_width = 0.42 -first_layer_height = 0.2 -first_layer_speed = 30 -gap_fill_speed = 40 -gcode_comments = 0 -infill_acceleration = 3500 -infill_every_layers = 1 -infill_extruder = 1 -infill_extrusion_width = 0.45 -infill_first = 0 -infill_only_where_needed = 0 -infill_overlap = 25% -infill_speed = 200 -interface_shells = 0 -layer_height = 0.2 -max_print_speed = 250 -max_volumetric_extrusion_rate_slope_negative = 0 -max_volumetric_extrusion_rate_slope_positive = 0 -max_volumetric_speed = 0 -min_skirt_length = 4 -notes = -only_retract_when_crossing_perimeters = 0 -ooze_prevention = 0 -output_filename_format = [input_filename_base].gcode -overhangs = 0 -perimeter_acceleration = 800 -perimeter_extruder = 1 -perimeter_extrusion_width = 0.45 -perimeter_speed = 60 -perimeters = 2 -post_process = -print_settings_id = -raft_layers = 0 -resolution = 0 -seam_position = nearest -skirt_distance = 2 -skirt_height = 3 -skirts = 1 -small_perimeter_speed = 20 -solid_infill_below_area = 0 -solid_infill_every_layers = 0 -solid_infill_extruder = 1 -solid_infill_extrusion_width = 0.45 -solid_infill_speed = 200 -spiral_vase = 0 -standby_temperature_delta = -5 -support_material = 0 -support_material_angle = 0 -support_material_buildplate_only = 0 -support_material_contact_distance = 0.15 -support_material_enforce_layers = 0 -support_material_extruder = 0 -support_material_extrusion_width = 0.35 -support_material_interface_contact_loops = 0 -support_material_interface_extruder = 0 -support_material_interface_layers = 2 -support_material_interface_spacing = 0.2 -support_material_interface_speed = 100% -support_material_pattern = rectilinear -support_material_spacing = 2 -support_material_speed = 50 -support_material_synchronize_layers = 0 -support_material_threshold = 45 -support_material_with_sheath = 0 -support_material_xy_spacing = 60% -thin_walls = 0 -threads = 4 -top_infill_extrusion_width = 0.4 -top_solid_infill_speed = 50 -top_solid_layers = 5 -travel_speed = 250 -wipe_tower = 1 -wipe_tower_per_color_wipe = 15 -wipe_tower_width = 60 -wipe_tower_x = 180 -wipe_tower_y = 140 -xy_size_compensation = 0 - [print:0.20mm NORMAL SOLUBLE FULL] avoid_crossing_perimeters = 0 bottom_solid_layers = 4 @@ -2226,112 +2226,6 @@ wipe_tower_x = 180 wipe_tower_y = 140 xy_size_compensation = 0 -[print:0.35mm FAST MK3] -avoid_crossing_perimeters = 0 -bottom_solid_layers = 4 -bridge_acceleration = 1000 -bridge_angle = 0 -bridge_flow_ratio = 0.8 -bridge_speed = 30 -brim_width = 0 -clip_multipart_objects = 1 -compatible_printers = -compatible_printers_condition = printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK3.*/ -complete_objects = 0 -default_acceleration = 1000 -dont_support_bridges = 1 -elefant_foot_compensation = 0 -ensure_vertical_shell_thickness = 1 -external_fill_pattern = rectilinear -external_perimeter_extrusion_width = 0.6 -external_perimeter_speed = 40 -external_perimeters_first = 0 -extra_perimeters = 0 -extruder_clearance_height = 20 -extruder_clearance_radius = 20 -extrusion_width = 0.45 -fill_angle = 45 -fill_density = 20% -fill_pattern = cubic -first_layer_acceleration = 1000 -first_layer_extrusion_width = 0.42 -first_layer_height = 0.2 -first_layer_speed = 30 -gap_fill_speed = 40 -gcode_comments = 0 -infill_acceleration = 3500 -infill_every_layers = 1 -infill_extruder = 1 -infill_extrusion_width = 0.7 -infill_first = 0 -infill_only_where_needed = 0 -infill_overlap = 25% -infill_speed = 200 -interface_shells = 0 -layer_height = 0.35 -max_print_speed = 250 -max_volumetric_extrusion_rate_slope_negative = 0 -max_volumetric_extrusion_rate_slope_positive = 0 -max_volumetric_speed = 0 -min_skirt_length = 4 -notes = -only_retract_when_crossing_perimeters = 0 -ooze_prevention = 0 -output_filename_format = [input_filename_base].gcode -overhangs = 0 -perimeter_acceleration = 800 -perimeter_extruder = 1 -perimeter_extrusion_width = 0.45 -perimeter_speed = 60 -perimeters = 2 -post_process = -print_settings_id = -raft_layers = 0 -resolution = 0 -seam_position = nearest -skirt_distance = 2 -skirt_height = 3 -skirts = 1 -small_perimeter_speed = 20 -solid_infill_below_area = 0 -solid_infill_every_layers = 0 -solid_infill_extruder = 1 -solid_infill_extrusion_width = 0.7 -solid_infill_speed = 200 -spiral_vase = 0 -standby_temperature_delta = -5 -support_material = 0 -support_material_angle = 0 -support_material_buildplate_only = 0 -support_material_contact_distance = 0.15 -support_material_enforce_layers = 0 -support_material_extruder = 0 -support_material_extrusion_width = 0.35 -support_material_interface_contact_loops = 0 -support_material_interface_extruder = 0 -support_material_interface_layers = 2 -support_material_interface_spacing = 0.2 -support_material_interface_speed = 100% -support_material_pattern = rectilinear -support_material_spacing = 2 -support_material_speed = 50 -support_material_synchronize_layers = 0 -support_material_threshold = 45 -support_material_with_sheath = 0 -support_material_xy_spacing = 60% -thin_walls = 0 -threads = 4 -top_infill_extrusion_width = 0.45 -top_solid_infill_speed = 50 -top_solid_layers = 4 -travel_speed = 250 -wipe_tower = 1 -wipe_tower_per_color_wipe = 15 -wipe_tower_width = 60 -wipe_tower_x = 180 -wipe_tower_y = 140 -xy_size_compensation = 0 - [print:0.35mm FAST sol full 0.6 nozzle] avoid_crossing_perimeters = 0 bottom_solid_layers = 3 @@ -2544,7 +2438,7 @@ wipe_tower_x = 180 wipe_tower_y = 140 xy_size_compensation = 0 -[filament:ColorFabb Brass Bronze 1.75mm] +[filament:ColorFabb Brass Bronze] bed_temperature = 60 bridge_fan_speed = 100 compatible_printers = @@ -2567,13 +2461,13 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 210 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 210 -[filament:ColorFabb HT 1.75mm] +[filament:ColorFabb HT] bed_temperature = 105 bridge_fan_speed = 30 compatible_printers = @@ -2598,7 +2492,7 @@ first_layer_temperature = 270 max_fan_speed = 20 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 270 @@ -2625,13 +2519,13 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 215 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 210 -[filament:ColorFabb Woodfil 1.75mm] +[filament:ColorFabb Woodfil] bed_temperature = 60 bridge_fan_speed = 100 compatible_printers = @@ -2654,13 +2548,13 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 200 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 200 -[filament:ColorFabb XT 1.75mm] +[filament:ColorFabb XT] bed_temperature = 90 bridge_fan_speed = 50 compatible_printers = @@ -2685,11 +2579,11 @@ first_layer_temperature = 260 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 270 -[filament:ColorFabb XT-CF20 1.75mm] +[filament:ColorFabb XT-CF20] bed_temperature = 90 bridge_fan_speed = 50 compatible_printers = @@ -2714,11 +2608,11 @@ first_layer_temperature = 260 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 260 -[filament:ColorFabb nGen 1.75mm] +[filament:ColorFabb nGen] bed_temperature = 85 bridge_fan_speed = 40 compatible_printers = @@ -2743,7 +2637,7 @@ first_layer_temperature = 240 max_fan_speed = 35 min_fan_speed = 20 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 240 @@ -2772,7 +2666,7 @@ first_layer_temperature = 260 max_fan_speed = 35 min_fan_speed = 20 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 260 @@ -2801,11 +2695,11 @@ first_layer_temperature = 230 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 240 -[filament:E3D PC-ABS 1.75mm] +[filament:E3D PC-ABS] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -2830,11 +2724,11 @@ first_layer_temperature = 270 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 270 -[filament:Fillamentum ABS 1.75mm] +[filament:Fillamentum ABS] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -2859,11 +2753,11 @@ first_layer_temperature = 240 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 240 -[filament:Fillamentum ASA 1.75mm] +[filament:Fillamentum ASA] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -2888,7 +2782,7 @@ first_layer_temperature = 265 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 265 @@ -2917,7 +2811,7 @@ first_layer_temperature = 260 max_fan_speed = 80 min_fan_speed = 80 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 260 @@ -2944,13 +2838,13 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 190 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 190 -[filament:Generic ABS 1.75mm] +[filament:Generic ABS] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -2975,11 +2869,11 @@ first_layer_temperature = 255 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 255 -[filament:Generic PET 1.75mm] +[filament:Generic PET] bed_temperature = 90 bridge_fan_speed = 50 compatible_printers = @@ -3004,11 +2898,11 @@ first_layer_temperature = 230 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 240 -[filament:Generic PLA 1.75mm] +[filament:Generic PLA] bed_temperature = 60 bridge_fan_speed = 100 compatible_printers = @@ -3031,9 +2925,9 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 215 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 210 @@ -3062,7 +2956,7 @@ first_layer_temperature = 270 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 270 @@ -3089,13 +2983,13 @@ filament_type = PVA first_layer_bed_temperature = 60 first_layer_temperature = 195 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 195 -[filament:Prusa ABS 1.75mm] +[filament:Prusa ABS] bed_temperature = 100 bridge_fan_speed = 30 compatible_printers = @@ -3120,11 +3014,11 @@ first_layer_temperature = 255 max_fan_speed = 30 min_fan_speed = 10 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 255 -[filament:Prusa HIPS 1.75mm] +[filament:Prusa HIPS] bed_temperature = 100 bridge_fan_speed = 50 compatible_printers = @@ -3149,11 +3043,11 @@ first_layer_temperature = 220 max_fan_speed = 20 min_fan_speed = 20 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 220 -[filament:Prusa PET 1.75mm] +[filament:Prusa PET] bed_temperature = 90 bridge_fan_speed = 50 compatible_printers = @@ -3178,11 +3072,11 @@ first_layer_temperature = 230 max_fan_speed = 50 min_fan_speed = 30 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}45{endif}; Filament gcode" temperature = 240 -[filament:Prusa PLA 1.75mm] +[filament:Prusa PLA] bed_temperature = 60 bridge_fan_speed = 100 compatible_printers = @@ -3205,9 +3099,9 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 215 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 210 @@ -3236,11 +3130,11 @@ first_layer_temperature = 220 max_fan_speed = 90 min_fan_speed = 70 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 230 -[filament:Taulman Bridge 1.75mm] +[filament:Taulman Bridge] bed_temperature = 50 bridge_fan_speed = 40 compatible_printers = @@ -3265,11 +3159,11 @@ first_layer_temperature = 240 max_fan_speed = 5 min_fan_speed = 0 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 250 -[filament:Taulman T-Glase 1.75mm] +[filament:Taulman T-Glase] bed_temperature = 90 bridge_fan_speed = 40 compatible_printers = @@ -3294,7 +3188,7 @@ first_layer_temperature = 240 max_fan_speed = 5 min_fan_speed = 0 min_print_speed = 5 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}30{endif}; Filament gcode" temperature = 240 @@ -3321,9 +3215,9 @@ filament_type = PLA first_layer_bed_temperature = 60 first_layer_temperature = 215 max_fan_speed = 100 -min_fan_speed = 85 +min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 210 @@ -3352,7 +3246,7 @@ first_layer_temperature = 220 max_fan_speed = 100 min_fan_speed = 100 min_print_speed = 15 -slowdown_below_layer_time = 10 +slowdown_below_layer_time = 20 start_filament_gcode = "M900 K{if printer_notes=~/.*PRINTER_HAS_BOWDEN.*/}200{else}10{endif}; Filament gcode" temperature = 220 @@ -3519,7 +3413,7 @@ z_offset = 0 [presets] print = 0.15mm OPTIMAL printer = Original Prusa i3 MK2 MultiMaterial -filament = Prusa PLA 1.75mm -filament_1 = Prusa PLA 1.75mm -filament_2 = Prusa PLA 1.75mm -filament_3 = Prusa PLA 1.75mm +filament = Prusa PLA +filament_1 = Prusa PLA +filament_2 = Prusa PLA +filament_3 = Prusa PLA From 60a6e7ba8e88e43a9b5234cac0855d2b77875988 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Sat, 6 Jan 2018 15:23:02 +0100 Subject: [PATCH 28/33] Included the velocity, acceleration and jerk settings into the Prusa3D printer profiles. --- .../Original Prusa i3 MK2 and MK2S.ini | 8 ++++---- ...inal Prusa i3 MK2, MK2S, MK2MM and MK3.ini | 20 +++++++++---------- .../profiles/Original Prusa i3 MK2MM.ini | 10 +++++----- resources/profiles/Original Prusa i3 MK3.ini | 4 ++-- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/resources/profiles/Original Prusa i3 MK2 and MK2S.ini b/resources/profiles/Original Prusa i3 MK2 and MK2S.ini index 5cdb020f59..d7b116f7ef 100644 --- a/resources/profiles/Original Prusa i3 MK2 and MK2S.ini +++ b/resources/profiles/Original Prusa i3 MK2 and MK2S.ini @@ -1,4 +1,4 @@ -# generated by Slic3r Prusa Edition 1.38.6 on 2018-01-05 at 16:05:06 +# generated by Slic3r Prusa Edition 1.39.0 on 2018-01-06 at 15:10:57 [print:0.05mm DETAIL] avoid_crossing_perimeters = 0 @@ -3281,7 +3281,7 @@ retract_speed = 35 serial_port = serial_speed = 250000 single_extruder_multi_material = 0 -start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 @@ -3321,7 +3321,7 @@ retract_speed = 50 serial_port = serial_speed = 250000 single_extruder_multi_material = 0 -start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 @@ -3361,7 +3361,7 @@ retract_speed = 35 serial_port = serial_speed = 250000 single_extruder_multi_material = 0 -start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 diff --git a/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini b/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini index 9513eee365..03f48e6f2f 100644 --- a/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini +++ b/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini @@ -1,4 +1,4 @@ -# generated by Slic3r Prusa Edition 1.38.6 on 2018-01-05 at 16:03:38 +# generated by Slic3r Prusa Edition 1.39.0 on 2018-01-06 at 15:09:55 [print:0.05mm DETAIL] avoid_crossing_perimeters = 0 @@ -3281,7 +3281,7 @@ retract_speed = 35 serial_port = serial_speed = 250000 single_extruder_multi_material = 0 -start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 @@ -3321,7 +3321,7 @@ retract_speed = 50 serial_port = serial_speed = 250000 single_extruder_multi_material = 0 -start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 @@ -3361,7 +3361,7 @@ retract_speed = 35 serial_port = serial_speed = 250000 single_extruder_multi_material = 0 -start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 +start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 @@ -3401,7 +3401,7 @@ retract_speed = 80 serial_port = serial_speed = 250000 single_extruder_multi_material = 1 -start_gcode = M115 U3.1.0 ; tell printer latest fw version\n; Start G-Code sequence START\nT?\nM104 S[first_layer_temperature]\nM140 S[first_layer_bed_temperature]\nM109 S[first_layer_temperature]\nM190 S[first_layer_bed_temperature]\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\nG92 E0.0 +start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\n; Start G-Code sequence START\nT?\nM104 S[first_layer_temperature]\nM140 S[first_layer_bed_temperature]\nM109 S[first_layer_temperature]\nM190 S[first_layer_bed_temperature]\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\nG92 E0.0 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 @@ -3441,7 +3441,7 @@ retract_speed = 80 serial_port = serial_speed = 250000 single_extruder_multi_material = 1 -start_gcode = M115 U3.1.0 ; tell printer latest fw version\n; Start G-Code sequence START\nT?\nM104 S[first_layer_temperature]\nM140 S[first_layer_bed_temperature]\nM109 S[first_layer_temperature]\nM190 S[first_layer_bed_temperature]\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\nG92 E0.0 +start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\n; Start G-Code sequence START\nT?\nM104 S[first_layer_temperature]\nM140 S[first_layer_bed_temperature]\nM109 S[first_layer_temperature]\nM190 S[first_layer_bed_temperature]\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\nG92 E0.0 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 @@ -3481,7 +3481,7 @@ retract_speed = 80,80,80,80 serial_port = serial_speed = 250000 single_extruder_multi_material = 1 -start_gcode = M115 U3.1.0 ; tell printer latest fw version\n; Start G-Code sequence START\nT[initial_tool]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100 ; set max feedrate\nM92 E140 ; E-steps per filament milimeter\n{if not has_wipe_tower}\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\n{endif}\nG92 E0.0 +start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\n; Start G-Code sequence START\nT[initial_tool]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100 ; set max feedrate\nM92 E140 ; E-steps per filament milimeter\n{if not has_wipe_tower}\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\n{endif}\nG92 E0.0 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 @@ -3521,7 +3521,7 @@ retract_speed = 80,80,80,80 serial_port = serial_speed = 250000 single_extruder_multi_material = 1 -start_gcode = M115 U3.1.0 ; tell printer latest fw version\n; Start G-Code sequence START\nT[initial_tool]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\n{if not has_wipe_tower}\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\n{endif}\nG92 E0.0 +start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\n; Start G-Code sequence START\nT[initial_tool]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\n{if not has_wipe_tower}\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\n{endif}\nG92 E0.0 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 @@ -3560,7 +3560,7 @@ retract_speed = 35 serial_port = serial_speed = 250000 single_extruder_multi_material = 0 -start_gcode = M115 U3.1.1-RC4 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S95 +start_gcode = M115 U3.1.1-RC4 ; tell printer latest fw version\nM201 X1000 Y1000 Z200 E5000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1250 T1250 ; sets acceleration (S) and retract acceleration (T)\nM205 X15 Y15 Z0.4 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S95 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 @@ -3570,6 +3570,6 @@ wipe = 1 z_offset = 0 [presets] -print = 0.05mm DETAIL MK3 +print = 0.15mm OPTIMAL MK3 printer = Original Prusa i3 MK3 filament = Prusa PLA diff --git a/resources/profiles/Original Prusa i3 MK2MM.ini b/resources/profiles/Original Prusa i3 MK2MM.ini index aba80c992c..9776c065e7 100644 --- a/resources/profiles/Original Prusa i3 MK2MM.ini +++ b/resources/profiles/Original Prusa i3 MK2MM.ini @@ -1,4 +1,4 @@ -# generated by Slic3r Prusa Edition 1.38.6 on 2018-01-05 at 16:05:58 +# generated by Slic3r Prusa Edition 1.39.0 on 2018-01-06 at 15:12:06 [print:0.05mm DETAIL] avoid_crossing_perimeters = 0 @@ -3281,7 +3281,7 @@ retract_speed = 80 serial_port = serial_speed = 250000 single_extruder_multi_material = 1 -start_gcode = M115 U3.1.0 ; tell printer latest fw version\n; Start G-Code sequence START\nT?\nM104 S[first_layer_temperature]\nM140 S[first_layer_bed_temperature]\nM109 S[first_layer_temperature]\nM190 S[first_layer_bed_temperature]\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\nG92 E0.0 +start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\n; Start G-Code sequence START\nT?\nM104 S[first_layer_temperature]\nM140 S[first_layer_bed_temperature]\nM109 S[first_layer_temperature]\nM190 S[first_layer_bed_temperature]\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\nG92 E0.0 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 @@ -3321,7 +3321,7 @@ retract_speed = 80 serial_port = serial_speed = 250000 single_extruder_multi_material = 1 -start_gcode = M115 U3.1.0 ; tell printer latest fw version\n; Start G-Code sequence START\nT?\nM104 S[first_layer_temperature]\nM140 S[first_layer_bed_temperature]\nM109 S[first_layer_temperature]\nM190 S[first_layer_bed_temperature]\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\nG92 E0.0 +start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\n; Start G-Code sequence START\nT?\nM104 S[first_layer_temperature]\nM140 S[first_layer_bed_temperature]\nM109 S[first_layer_temperature]\nM190 S[first_layer_bed_temperature]\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\nG92 E0.0 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 @@ -3361,7 +3361,7 @@ retract_speed = 80,80,80,80 serial_port = serial_speed = 250000 single_extruder_multi_material = 1 -start_gcode = M115 U3.1.0 ; tell printer latest fw version\n; Start G-Code sequence START\nT[initial_tool]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100 ; set max feedrate\nM92 E140 ; E-steps per filament milimeter\n{if not has_wipe_tower}\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\n{endif}\nG92 E0.0 +start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\n; Start G-Code sequence START\nT[initial_tool]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100 ; set max feedrate\nM92 E140 ; E-steps per filament milimeter\n{if not has_wipe_tower}\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\n{endif}\nG92 E0.0 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 @@ -3401,7 +3401,7 @@ retract_speed = 80,80,80,80 serial_port = serial_speed = 250000 single_extruder_multi_material = 1 -start_gcode = M115 U3.1.0 ; tell printer latest fw version\n; Start G-Code sequence START\nT[initial_tool]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\n{if not has_wipe_tower}\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\n{endif}\nG92 E0.0 +start_gcode = M115 U3.1.0 ; tell printer latest fw version\nM201 X9000 Y9000 Z500 E10000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1500 T1500 ; sets acceleration (S) and retract acceleration (T)\nM205 X10 Y10 Z0.2 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\n; Start G-Code sequence START\nT[initial_tool]\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG21 ; set units to millimeters\nG90 ; use absolute coordinates\nM83 ; use relative distances for extrusion\nG28 W\nG80\nG92 E0.0\nM203 E100\nM92 E140\n{if not has_wipe_tower}\nG1 Z0.250 F7200.000\nG1 X50.0 E80.0 F1000.0\nG1 X160.0 E20.0 F1000.0\nG1 Z0.200 F7200.000\nG1 X220.0 E13 F1000.0\nG1 X240.0 E0 F1000.0\nG1 E-4 F1000.0\n{endif}\nG92 E0.0 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 diff --git a/resources/profiles/Original Prusa i3 MK3.ini b/resources/profiles/Original Prusa i3 MK3.ini index a4e0694ec8..1aafb61f90 100644 --- a/resources/profiles/Original Prusa i3 MK3.ini +++ b/resources/profiles/Original Prusa i3 MK3.ini @@ -1,4 +1,4 @@ -# generated by Slic3r Prusa Edition 1.38.6 on 2018-01-05 at 15:21:29 +# generated by Slic3r Prusa Edition 1.39.0 on 2018-01-06 at 15:12:34 [print:0.05mm DETAIL] avoid_crossing_perimeters = 0 @@ -3280,7 +3280,7 @@ retract_speed = 35 serial_port = serial_speed = 250000 single_extruder_multi_material = 0 -start_gcode = M115 U3.1.1-RC4 ; tell printer latest fw version\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S95 +start_gcode = M115 U3.1.1-RC4 ; tell printer latest fw version\nM201 X1000 Y1000 Z200 E5000 ; sets maximum accelerations, mm/sec^2\nM203 X500 Y500 Z12 E120 ; sets maximum feedrates, mm/sec\nM204 S1250 T1250 ; sets acceleration (S) and retract acceleration (T)\nM205 X15 Y15 Z0.4 E2.5 ; sets the jerk limits, mm/sec\nM205 S0 T0 ; sets the minimum extruding and travel feed rate, mm/sec\nM83 ; extruder relative mode\nM104 S[first_layer_temperature] ; set extruder temp\nM140 S[first_layer_bed_temperature] ; set bed temp\nM190 S[first_layer_bed_temperature] ; wait for bed temp\nM109 S[first_layer_temperature] ; wait for extruder temp\nG28 W ; home all without mesh bed level\nG80 ; mesh bed leveling\nG1 Y-3.0 F1000.0 ; go outside print area\nG92 E0.0\nG1 X60.0 E9.0 F1000.0 ; intro line\nG1 X100.0 E12.5 F1000.0 ; intro line\nG92 E0.0\nM221 S95 toolchange_gcode = use_firmware_retraction = 0 use_relative_e_distances = 1 From fec1fcdca8805cd6db95095abdaea5952e22d513 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Sat, 6 Jan 2018 18:49:28 +0100 Subject: [PATCH 29/33] Separated the Marlin G-code flavor from the RepRap G-code flavor due to the differences in the M203 code (RepRap firmware has it in mm/min, Marlin in mm/sec). This difference is important to the G-code time estimator. Changed the g-code flavor to Marlin for all Prusa3D bundled profiles. --- .../Original Prusa i3 MK2 and MK2S.ini | 6 ++--- ...inal Prusa i3 MK2, MK2S, MK2MM and MK3.ini | 16 ++++++------ .../profiles/Original Prusa i3 MK2MM.ini | 8 +++--- resources/profiles/Original Prusa i3 MK3.ini | 2 +- xs/src/libslic3r/GCode.cpp | 1 + xs/src/libslic3r/GCodeTimeEstimator.cpp | 26 +++++++++---------- xs/src/libslic3r/GCodeTimeEstimator.hpp | 18 +++---------- xs/src/libslic3r/GCodeWriter.cpp | 2 +- xs/src/libslic3r/Print.cpp | 4 +-- xs/src/libslic3r/PrintConfig.cpp | 7 +++-- xs/src/libslic3r/PrintConfig.hpp | 4 ++- 11 files changed, 45 insertions(+), 49 deletions(-) diff --git a/resources/profiles/Original Prusa i3 MK2 and MK2S.ini b/resources/profiles/Original Prusa i3 MK2 and MK2S.ini index d7b116f7ef..a186c37759 100644 --- a/resources/profiles/Original Prusa i3 MK2 and MK2S.ini +++ b/resources/profiles/Original Prusa i3 MK2 and MK2S.ini @@ -3258,7 +3258,7 @@ deretract_speed = 0 end_gcode = G4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors extruder_colour = #FFFF00 extruder_offset = 0x0 -gcode_flavor = reprap +gcode_flavor = marlin layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] max_layer_height = 0.25 min_layer_height = 0.07 @@ -3298,7 +3298,7 @@ deretract_speed = 0 end_gcode = G4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors extruder_colour = #FFFF00 extruder_offset = 0x0 -gcode_flavor = reprap +gcode_flavor = marlin layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] max_layer_height = 0.1 min_layer_height = 0.05 @@ -3338,7 +3338,7 @@ deretract_speed = 0 end_gcode = G4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors extruder_colour = #FFFF00 extruder_offset = 0x0 -gcode_flavor = reprap +gcode_flavor = marlin layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] max_layer_height = 0.35 min_layer_height = 0.1 diff --git a/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini b/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini index 03f48e6f2f..5835cfdeb2 100644 --- a/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini +++ b/resources/profiles/Original Prusa i3 MK2, MK2S, MK2MM and MK3.ini @@ -3258,7 +3258,7 @@ deretract_speed = 0 end_gcode = G4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors extruder_colour = #FFFF00 extruder_offset = 0x0 -gcode_flavor = reprap +gcode_flavor = marlin layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] max_layer_height = 0.25 min_layer_height = 0.07 @@ -3298,7 +3298,7 @@ deretract_speed = 0 end_gcode = G4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors extruder_colour = #FFFF00 extruder_offset = 0x0 -gcode_flavor = reprap +gcode_flavor = marlin layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] max_layer_height = 0.1 min_layer_height = 0.05 @@ -3338,7 +3338,7 @@ deretract_speed = 0 end_gcode = G4 ; wait\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors extruder_colour = #FFFF00 extruder_offset = 0x0 -gcode_flavor = reprap +gcode_flavor = marlin layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] max_layer_height = 0.35 min_layer_height = 0.1 @@ -3378,7 +3378,7 @@ deretract_speed = 50 end_gcode = G1 E-4 F2100.00000\nG91\nG1 Z1 F7200.000\nG90\nG1 X245 Y1\nG1 X240 E4\nG1 F4000\nG1 X190 E2.7 \nG1 F4600\nG1 X110 E2.8\nG1 F5200\nG1 X40 E3 \nG1 E-15.0000 F5000\nG1 E-50.0000 F5400\nG1 E-15.0000 F3000\nG1 E-12.0000 F2000\nG1 F1600\nG1 X0 Y1 E3.0000\nG1 X50 Y1 E-5.0000\nG1 F2000\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-3.0000\nG4 S0\nM107 ; fan off\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nG28 X0 ; home X axis\nM84 ; disable motors\n\n extruder_colour = #FFAA55 extruder_offset = 0x0 -gcode_flavor = reprap +gcode_flavor = marlin layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] max_layer_height = 0.25 min_layer_height = 0.07 @@ -3418,7 +3418,7 @@ deretract_speed = 50 end_gcode = G1 E-4 F2100.00000\nG91\nG1 Z1 F7200.000\nG90\nG1 X245 Y1\nG1 X240 E4\nG1 F4000\nG1 X190 E2.7 \nG1 F4600\nG1 X110 E2.8\nG1 F5200\nG1 X40 E3 \nG1 E-15.0000 F5000\nG1 E-50.0000 F5400\nG1 E-15.0000 F3000\nG1 E-12.0000 F2000\nG1 F1600\nG1 X0 Y1 E3.0000\nG1 X50 Y1 E-5.0000\nG1 F2000\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-3.0000\nG4 S0\nM107 ; fan off\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nG28 X0 ; home X axis\nM84 ; disable motors\n\n extruder_colour = #FFAA55 extruder_offset = 0x0 -gcode_flavor = reprap +gcode_flavor = marlin layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] max_layer_height = 0.25 min_layer_height = 0.07 @@ -3458,7 +3458,7 @@ deretract_speed = 50,50,50,50 end_gcode = {if not has_wipe_tower}\n; Pull the filament into the cooling tubes.\nG1 E-4 F2100.00000\nG91\nG1 Z1 F7200.000\nG90\nG1 X245 Y1\nG1 X240 E4\nG1 F4000\nG1 X190 E2.7 \nG1 F4600\nG1 X110 E2.8\nG1 F5200\nG1 X40 E3 \nG1 E-15.0000 F5000\nG1 E-50.0000 F5400\nG1 E-15.0000 F3000\nG1 E-12.0000 F2000\nG1 F1600\nG1 X0 Y1 E3.0000\nG1 X50 Y1 E-5.0000\nG1 F2000\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-3.0000\nG4 S0\n{endif}\nM107 ; fan off\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nG28 X0 ; home X axis\nM84 ; disable motors extruder_colour = #FFAA55;#5182DB;#4ECDD3;#FB7259 extruder_offset = 0x0,0x0,0x0,0x0 -gcode_flavor = reprap +gcode_flavor = marlin layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] max_layer_height = 0.25,0.25,0.25,0.25 min_layer_height = 0.07,0.07,0.07,0.07 @@ -3498,7 +3498,7 @@ deretract_speed = 50,50,50,50 end_gcode = {if not has_wipe_tower}\nG1 E-4 F2100.00000\nG91\nG1 Z1 F7200.000\nG90\nG1 X245 Y1\nG1 X240 E4\nG1 F4000\nG1 X190 E2.7 \nG1 F4600\nG1 X110 E2.8\nG1 F5200\nG1 X40 E3 \nG1 E-15.0000 F5000\nG1 E-50.0000 F5400\nG1 E-15.0000 F3000\nG1 E-12.0000 F2000\nG1 F1600\nG1 X0 Y1 E3.0000\nG1 X50 Y1 E-5.0000\nG1 F2000\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-3.0000\nG4 S0\n{endif}\nM107 ; fan off\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nG28 X0 ; home X axis\nM84 ; disable motors\n extruder_colour = #FFAA55;#5182DB;#4ECDD3;#FB7259 extruder_offset = 0x0,0x0,0x0,0x0 -gcode_flavor = reprap +gcode_flavor = marlin layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] max_layer_height = 0.25,0.25,0.25,0.25 min_layer_height = 0.07,0.07,0.07,0.07 @@ -3538,7 +3538,7 @@ deretract_speed = 0 end_gcode = G4 ; wait\nM221 S100\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors extruder_colour = #FFFF00 extruder_offset = 0x0 -gcode_flavor = reprap +gcode_flavor = marlin layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] max_layer_height = 0.25 min_layer_height = 0.07 diff --git a/resources/profiles/Original Prusa i3 MK2MM.ini b/resources/profiles/Original Prusa i3 MK2MM.ini index 9776c065e7..035d15515e 100644 --- a/resources/profiles/Original Prusa i3 MK2MM.ini +++ b/resources/profiles/Original Prusa i3 MK2MM.ini @@ -3258,7 +3258,7 @@ deretract_speed = 50 end_gcode = G1 E-4 F2100.00000\nG91\nG1 Z1 F7200.000\nG90\nG1 X245 Y1\nG1 X240 E4\nG1 F4000\nG1 X190 E2.7 \nG1 F4600\nG1 X110 E2.8\nG1 F5200\nG1 X40 E3 \nG1 E-15.0000 F5000\nG1 E-50.0000 F5400\nG1 E-15.0000 F3000\nG1 E-12.0000 F2000\nG1 F1600\nG1 X0 Y1 E3.0000\nG1 X50 Y1 E-5.0000\nG1 F2000\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-3.0000\nG4 S0\nM107 ; fan off\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nG28 X0 ; home X axis\nM84 ; disable motors\n\n extruder_colour = #FFAA55 extruder_offset = 0x0 -gcode_flavor = reprap +gcode_flavor = marlin layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] max_layer_height = 0.25 min_layer_height = 0.07 @@ -3298,7 +3298,7 @@ deretract_speed = 50 end_gcode = G1 E-4 F2100.00000\nG91\nG1 Z1 F7200.000\nG90\nG1 X245 Y1\nG1 X240 E4\nG1 F4000\nG1 X190 E2.7 \nG1 F4600\nG1 X110 E2.8\nG1 F5200\nG1 X40 E3 \nG1 E-15.0000 F5000\nG1 E-50.0000 F5400\nG1 E-15.0000 F3000\nG1 E-12.0000 F2000\nG1 F1600\nG1 X0 Y1 E3.0000\nG1 X50 Y1 E-5.0000\nG1 F2000\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-3.0000\nG4 S0\nM107 ; fan off\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nG28 X0 ; home X axis\nM84 ; disable motors\n\n extruder_colour = #FFAA55 extruder_offset = 0x0 -gcode_flavor = reprap +gcode_flavor = marlin layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] max_layer_height = 0.25 min_layer_height = 0.07 @@ -3338,7 +3338,7 @@ deretract_speed = 50,50,50,50 end_gcode = {if not has_wipe_tower}\n; Pull the filament into the cooling tubes.\nG1 E-4 F2100.00000\nG91\nG1 Z1 F7200.000\nG90\nG1 X245 Y1\nG1 X240 E4\nG1 F4000\nG1 X190 E2.7 \nG1 F4600\nG1 X110 E2.8\nG1 F5200\nG1 X40 E3 \nG1 E-15.0000 F5000\nG1 E-50.0000 F5400\nG1 E-15.0000 F3000\nG1 E-12.0000 F2000\nG1 F1600\nG1 X0 Y1 E3.0000\nG1 X50 Y1 E-5.0000\nG1 F2000\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-3.0000\nG4 S0\n{endif}\nM107 ; fan off\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nG28 X0 ; home X axis\nM84 ; disable motors extruder_colour = #FFAA55;#5182DB;#4ECDD3;#FB7259 extruder_offset = 0x0,0x0,0x0,0x0 -gcode_flavor = reprap +gcode_flavor = marlin layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] max_layer_height = 0.25,0.25,0.25,0.25 min_layer_height = 0.07,0.07,0.07,0.07 @@ -3378,7 +3378,7 @@ deretract_speed = 50,50,50,50 end_gcode = {if not has_wipe_tower}\nG1 E-4 F2100.00000\nG91\nG1 Z1 F7200.000\nG90\nG1 X245 Y1\nG1 X240 E4\nG1 F4000\nG1 X190 E2.7 \nG1 F4600\nG1 X110 E2.8\nG1 F5200\nG1 X40 E3 \nG1 E-15.0000 F5000\nG1 E-50.0000 F5400\nG1 E-15.0000 F3000\nG1 E-12.0000 F2000\nG1 F1600\nG1 X0 Y1 E3.0000\nG1 X50 Y1 E-5.0000\nG1 F2000\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-5.0000\nG1 F2400\nG1 X0 Y1 E5.0000\nG1 X50 Y1 E-3.0000\nG4 S0\n{endif}\nM107 ; fan off\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nG28 X0 ; home X axis\nM84 ; disable motors\n extruder_colour = #FFAA55;#5182DB;#4ECDD3;#FB7259 extruder_offset = 0x0,0x0,0x0,0x0 -gcode_flavor = reprap +gcode_flavor = marlin layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] max_layer_height = 0.25,0.25,0.25,0.25 min_layer_height = 0.07,0.07,0.07,0.07 diff --git a/resources/profiles/Original Prusa i3 MK3.ini b/resources/profiles/Original Prusa i3 MK3.ini index 1aafb61f90..0afbb35cd3 100644 --- a/resources/profiles/Original Prusa i3 MK3.ini +++ b/resources/profiles/Original Prusa i3 MK3.ini @@ -3258,7 +3258,7 @@ deretract_speed = 0 end_gcode = G4 ; wait\nM221 S100\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nG1 X0 Y200; home X axis\nM84 ; disable motors extruder_colour = #FFFF00 extruder_offset = 0x0 -gcode_flavor = reprap +gcode_flavor = marlin layer_gcode = ;AFTER_LAYER_CHANGE\n;[layer_z] max_layer_height = 0.25 min_layer_height = 0.07 diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index e85b21f80d..d220407992 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -400,6 +400,7 @@ void GCode::_do_export(Print &print, FILE *file) // resets time estimator m_time_estimator.reset(); + m_time_estimator.set_dialect(print.config.gcode_flavor); // How many times will be change_layer() called? // change_layer() in turn increments the progress bar status. diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index 2ebeb9fd29..2edbfeac5f 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -302,12 +302,12 @@ namespace Slic3r { return _state.extrude_factor_override_percentage; } - void GCodeTimeEstimator::set_dialect(GCodeTimeEstimator::EDialect dialect) + void GCodeTimeEstimator::set_dialect(GCodeFlavor dialect) { _state.dialect = dialect; } - GCodeTimeEstimator::EDialect GCodeTimeEstimator::get_dialect() const + GCodeFlavor GCodeTimeEstimator::get_dialect() const { return _state.dialect; } @@ -360,7 +360,7 @@ namespace Slic3r { void GCodeTimeEstimator::set_default() { set_units(Millimeters); - set_dialect(Unknown); + set_dialect(gcfRepRap); set_positioning_xyz_type(Absolute); set_positioning_e_type(Relative); @@ -738,17 +738,17 @@ namespace Slic3r { void GCodeTimeEstimator::_processG4(const GCodeReader::GCodeLine& line) { - EDialect dialect = get_dialect(); + GCodeFlavor dialect = get_dialect(); float value; if (line.has_value('P', value)) add_additional_time(value * MILLISEC_TO_SEC); // see: http://reprap.org/wiki/G-code#G4:_Dwell - if ((dialect == Repetier) || - (dialect == Marlin) || - (dialect == Smoothieware) || - (dialect == RepRapFirmware)) + if ((dialect == gcfRepetier) || + (dialect == gcfMarlin) || + (dialect == gcfSmoothie) || + (dialect == gcfRepRap)) { if (line.has_value('S', value)) add_additional_time(value); @@ -846,10 +846,10 @@ namespace Slic3r { void GCodeTimeEstimator::_processM201(const GCodeReader::GCodeLine& line) { - EDialect dialect = get_dialect(); + GCodeFlavor dialect = get_dialect(); // see http://reprap.org/wiki/G-code#M201:_Set_max_printing_acceleration - float factor = ((dialect != RepRapFirmware) && (get_units() == GCodeTimeEstimator::Inches)) ? INCHES_TO_MM : 1.0f; + float factor = ((dialect != gcfRepRap) && (get_units() == GCodeTimeEstimator::Inches)) ? INCHES_TO_MM : 1.0f; if (line.has_x()) set_axis_max_acceleration(X, line.x() * factor); @@ -866,14 +866,14 @@ namespace Slic3r { void GCodeTimeEstimator::_processM203(const GCodeReader::GCodeLine& line) { - EDialect dialect = get_dialect(); + GCodeFlavor dialect = get_dialect(); // see http://reprap.org/wiki/G-code#M203:_Set_maximum_feedrate - if (dialect == Repetier) + if (dialect == gcfRepetier) return; // see http://reprap.org/wiki/G-code#M203:_Set_maximum_feedrate - float factor = (dialect == Marlin) ? 1.0f : MMMIN_TO_MMSEC; + float factor = (dialect == gcfMarlin) ? 1.0f : MMMIN_TO_MMSEC; if (line.has_x()) set_axis_max_feedrate(X, line.x() * factor); diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index 46f8669724..9e429462e8 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -2,6 +2,7 @@ #define slic3r_GCodeTimeEstimator_hpp_ #include "libslic3r.h" +#include "PrintConfig.hpp" #include "GCodeReader.hpp" namespace Slic3r { @@ -24,17 +25,6 @@ namespace Slic3r { Num_Axis }; - enum EDialect : unsigned char - { - Unknown, - Marlin, - Repetier, - Smoothieware, - RepRapFirmware, - Teacup, - Num_Dialects - }; - enum EPositioningType : unsigned char { Absolute, @@ -62,7 +52,7 @@ namespace Slic3r { struct State { - EDialect dialect; + GCodeFlavor dialect; EUnits units; EPositioningType positioning_xyz_type; EPositioningType positioning_e_type; @@ -222,8 +212,8 @@ namespace Slic3r { void set_extrude_factor_override_percentage(float percentage); float get_extrude_factor_override_percentage() const; - void set_dialect(EDialect dialect); - EDialect get_dialect() const; + void set_dialect(GCodeFlavor dialect); + GCodeFlavor get_dialect() const; void set_units(EUnits units); EUnits get_units() const; diff --git a/xs/src/libslic3r/GCodeWriter.cpp b/xs/src/libslic3r/GCodeWriter.cpp index abf55114b2..cbe94f3179 100644 --- a/xs/src/libslic3r/GCodeWriter.cpp +++ b/xs/src/libslic3r/GCodeWriter.cpp @@ -42,7 +42,7 @@ std::string GCodeWriter::preamble() gcode << "G21 ; set units to millimeters\n"; gcode << "G90 ; use absolute coordinates\n"; } - if (FLAVOR_IS(gcfRepRap) || FLAVOR_IS(gcfTeacup) || FLAVOR_IS(gcfRepetier) || FLAVOR_IS(gcfSmoothie)) { + if (FLAVOR_IS(gcfRepRap) || FLAVOR_IS(gcfMarlin) || FLAVOR_IS(gcfTeacup) || FLAVOR_IS(gcfRepetier) || FLAVOR_IS(gcfSmoothie)) { if (this->config.use_relative_e_distances) { gcode << "M83 ; use relative distances for extrusion\n"; } else { diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp index 7739983944..0bc63f2f38 100644 --- a/xs/src/libslic3r/Print.cpp +++ b/xs/src/libslic3r/Print.cpp @@ -567,8 +567,8 @@ std::string Print::validate() const if (std::abs(dmr - 0.4) > EPSILON) return "The Wipe Tower is currently only supported for the 0.4mm nozzle diameter."; #endif - if (this->config.gcode_flavor != gcfRepRap) - return "The Wipe Tower is currently only supported for the RepRap (Marlin / Sprinter) G-code flavor."; + if (this->config.gcode_flavor != gcfRepRap && this->config.gcode_flavor != gcfMarlin) + return "The Wipe Tower is currently only supported for the Marlin and RepRap/Sprinter G-code flavors."; if (! this->config.use_relative_e_distances) return "The Wipe Tower is currently only supported with the relative extruder addressing (use_relative_e_distances=1)."; SlicingParameters slicing_params0 = this->objects.front()->slicing_parameters(); diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 9029145361..0dc6c9d43b 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -653,21 +653,23 @@ PrintConfigDef::PrintConfigDef() def->enum_values.push_back("repetier"); def->enum_values.push_back("teacup"); def->enum_values.push_back("makerware"); + def->enum_values.push_back("marlin"); def->enum_values.push_back("sailfish"); def->enum_values.push_back("mach3"); def->enum_values.push_back("machinekit"); def->enum_values.push_back("smoothie"); def->enum_values.push_back("no-extrusion"); - def->enum_labels.push_back("RepRap (Marlin/Sprinter)"); + def->enum_labels.push_back("RepRap/Sprinter"); def->enum_labels.push_back("Repetier"); def->enum_labels.push_back("Teacup"); def->enum_labels.push_back("MakerWare (MakerBot)"); + def->enum_labels.push_back("Marlin"); def->enum_labels.push_back("Sailfish (MakerBot)"); def->enum_labels.push_back("Mach3/LinuxCNC"); def->enum_labels.push_back("Machinekit"); def->enum_labels.push_back("Smoothie"); def->enum_labels.push_back("No extrusion"); - def->default_value = new ConfigOptionEnum(gcfRepRap); + def->default_value = new ConfigOptionEnum(gcfMarlin); def = this->add("infill_acceleration", coFloat); def->label = "Infill"; @@ -1919,6 +1921,7 @@ std::string FullPrintConfig::validate() if (this->use_firmware_retraction.value && this->gcode_flavor.value != gcfSmoothie && this->gcode_flavor.value != gcfRepRap && + this->gcode_flavor.value != gcfMarlin && this->gcode_flavor.value != gcfMachinekit && this->gcode_flavor.value != gcfRepetier) return "--use-firmware-retraction is only supported by Marlin, Smoothie, Repetier and Machinekit firmware"; diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index ab58aa3566..4394fcac1d 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -23,7 +23,8 @@ namespace Slic3r { enum GCodeFlavor { - gcfRepRap, gcfTeacup, gcfMakerWare, gcfSailfish, gcfMach3, gcfMachinekit, gcfNoExtrusion, gcfSmoothie, gcfRepetier, + gcfRepRap, gcfRepetier, gcfTeacup, gcfMakerWare, gcfMarlin, gcfSailfish, gcfMach3, gcfMachinekit, + gcfSmoothie, gcfNoExtrusion, }; enum InfillPattern { @@ -50,6 +51,7 @@ template<> inline t_config_enum_values& ConfigOptionEnum::get_enum_ keys_map["repetier"] = gcfRepetier; keys_map["teacup"] = gcfTeacup; keys_map["makerware"] = gcfMakerWare; + keys_map["marlin"] = gcfMarlin; keys_map["sailfish"] = gcfSailfish; keys_map["smoothie"] = gcfSmoothie; keys_map["mach3"] = gcfMach3; From ad5fcce6e4fd172cb105a71b9ef658338d742f56 Mon Sep 17 00:00:00 2001 From: fredizzimo Date: Sun, 7 Jan 2018 23:20:02 +0200 Subject: [PATCH 30/33] Fix environment variable setting on Windows (#674) The previous way of checking that _putenv_s is defined does not work, because _putenv_s is a function and not a define. This is a partial application of commit 31115e0369747b1e1c45cbe3f2a90f6dff66666a from alexrj/Slic3r. I tried cherry picking the whole commit, but unicode is already handled diffrently here, so that would have been a lot of work. --- xs/src/libslic3r/Config.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/xs/src/libslic3r/Config.cpp b/xs/src/libslic3r/Config.cpp index 728ed608b8..474be72372 100644 --- a/xs/src/libslic3r/Config.cpp +++ b/xs/src/libslic3r/Config.cpp @@ -18,10 +18,6 @@ #include #include -#if defined(_WIN32) && !defined(setenv) && defined(_putenv_s) -#define setenv(k, v, o) _putenv_s(k, v) -#endif - namespace Slic3r { std::string escape_string_cstyle(const std::string &str) @@ -309,7 +305,6 @@ double ConfigBase::get_abs_value(const t_config_option_key &opt_key, double rati void ConfigBase::setenv_() { -#ifdef setenv t_config_option_keys opt_keys = this->keys(); for (t_config_option_keys::const_iterator it = opt_keys.begin(); it != opt_keys.end(); ++it) { // prepend the SLIC3R_ prefix @@ -322,9 +317,8 @@ void ConfigBase::setenv_() for (size_t i = 0; i < envname.size(); ++i) envname[i] = (envname[i] <= 'z' && envname[i] >= 'a') ? envname[i]-('a'-'A') : envname[i]; - setenv(envname.c_str(), this->serialize(*it).c_str(), 1); + boost::nowide::setenv(envname.c_str(), this->serialize(*it).c_str(), 1); } -#endif } void ConfigBase::load(const std::string &file) From dfcb502ef46df5f18aa64c7e3ca6a06fb0ca1e05 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 8 Jan 2018 12:17:39 +0100 Subject: [PATCH 31/33] GCodeTimeEstimator - Fixed square roots of negative numbers --- xs/src/libslic3r/GCodeTimeEstimator.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index 2edbfeac5f..b65ff555b5 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -56,7 +56,9 @@ namespace Slic3r { float GCodeTimeEstimator::Block::Trapezoid::speed_from_distance(float initial_feedrate, float distance, float acceleration) { - return ::sqrt(sqr(initial_feedrate) + 2.0f * acceleration * distance); + // to avoid invalid negative numbers due to numerical imprecision + float value = std::max(0.0f, sqr(initial_feedrate) + 2.0f * acceleration * distance); + return ::sqrt(value); } float GCodeTimeEstimator::Block::move_length() const @@ -122,7 +124,9 @@ namespace Slic3r { float GCodeTimeEstimator::Block::max_allowable_speed(float acceleration, float target_velocity, float distance) { - return ::sqrt(sqr(target_velocity) - 2.0f * acceleration * distance); + // to avoid invalid negative numbers due to numerical imprecision + float value = std::max(0.0f, sqr(target_velocity) - 2.0f * acceleration * distance); + return ::sqrt(value); } float GCodeTimeEstimator::Block::estimate_acceleration_distance(float initial_rate, float target_rate, float acceleration) From aeca5def00f14e5ae2dc12264e57ab04965d83d9 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 8 Jan 2018 12:27:18 +0100 Subject: [PATCH 32/33] GCodeTimeEstimator - Added credits for CuraEngine --- xs/src/libslic3r/GCodeTimeEstimator.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index 9e429462e8..63dd0a6c6f 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -7,6 +7,11 @@ namespace Slic3r { + // + // Some of the algorithms used by class GCodeTimeEstimator were inpired by + // Cura Engine's class TimeEstimateCalculator + // https://github.com/Ultimaker/CuraEngine/blob/master/src/timeEstimate.h + // class GCodeTimeEstimator { public: From e94491ee8c3a652ed16158d87f55543d30ac1f6f Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 8 Jan 2018 13:23:54 +0100 Subject: [PATCH 33/33] GCodeTimeEstimator - Fixed _simulate_st_synchronize() --- xs/src/libslic3r/GCodeTimeEstimator.cpp | 16 +++++++++++++--- xs/src/libslic3r/GCodeTimeEstimator.hpp | 1 + 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/xs/src/libslic3r/GCodeTimeEstimator.cpp b/xs/src/libslic3r/GCodeTimeEstimator.cpp index b65ff555b5..22821a7082 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.cpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.cpp @@ -153,6 +153,9 @@ namespace Slic3r { [this](GCodeReader &reader, const GCodeReader::GCodeLine &line) { this->_process_gcode_line(reader, line); }); + _calculate_time(); + + _reset_blocks(); _reset(); } @@ -163,6 +166,7 @@ namespace Slic3r { _parser.parse_file(file, boost::bind(&GCodeTimeEstimator::_process_gcode_line, this, _1, _2)); _calculate_time(); + _reset_blocks(); _reset(); } @@ -176,6 +180,7 @@ namespace Slic3r { _parser.parse_line(line, action); _calculate_time(); + _reset_blocks(); _reset(); } @@ -203,6 +208,7 @@ namespace Slic3r { { PROFILE_FUNC(); _calculate_time(); + _reset_blocks(); _reset(); } @@ -387,6 +393,7 @@ namespace Slic3r { void GCodeTimeEstimator::reset() { _time = 0.0f; + _reset_blocks(); _reset(); } @@ -416,8 +423,6 @@ namespace Slic3r { void GCodeTimeEstimator::_reset() { - _blocks.clear(); - _curr.reset(); _prev.reset(); @@ -428,6 +433,11 @@ namespace Slic3r { set_additional_time(0.0f); } + void GCodeTimeEstimator::_reset_blocks() + { + _blocks.clear(); + } + void GCodeTimeEstimator::_calculate_time() { _forward_pass(); @@ -954,7 +964,7 @@ namespace Slic3r { void GCodeTimeEstimator::_simulate_st_synchronize() { _calculate_time(); - _reset(); + _reset_blocks(); } void GCodeTimeEstimator::_forward_pass() diff --git a/xs/src/libslic3r/GCodeTimeEstimator.hpp b/xs/src/libslic3r/GCodeTimeEstimator.hpp index 63dd0a6c6f..fb41a2753d 100644 --- a/xs/src/libslic3r/GCodeTimeEstimator.hpp +++ b/xs/src/libslic3r/GCodeTimeEstimator.hpp @@ -246,6 +246,7 @@ namespace Slic3r { private: void _reset(); + void _reset_blocks(); // Calculates the time estimate void _calculate_time();