void GCodeExport::switchExtruder(int new_extruder) { if (current_extruder == new_extruder) return; writeRetraction_extruderSwitch(); resetExtrusionValue(); // should be called on the old extruder int old_extruder = current_extruder; current_extruder = new_extruder; if (flavor == EGCodeFlavor::MACH3) { resetExtrusionValue(); // also zero the E value on the new extruder } writeCode(extruder_attr[old_extruder].end_code.c_str()); if (flavor == EGCodeFlavor::MAKERBOT) { *output_stream << "M135 T" << current_extruder << "\n"; } else { *output_stream << "T" << current_extruder << "\n"; } writeCode(extruder_attr[new_extruder].start_code.c_str()); //Change the Z position so it gets re-writting again. We do not know if the switch code modified the Z position. currentPosition.z += 1; }
void GCodeExport::startExtruder(int new_extruder) { if (new_extruder != current_extruder) // wouldn't be the case on the very first extruder start if it's extruder 0 { if (flavor == EGCodeFlavor::MAKERBOT) { *output_stream << "M135 T" << new_extruder << new_line; } else { *output_stream << "T" << new_extruder << new_line; } } current_extruder = new_extruder; assert(getCurrentExtrudedVolume() == 0.0 && "Just after an extruder switch we haven't extruded anything yet!"); resetExtrusionValue(); // zero the E value on the new extruder, just to be sure writeCode(extruder_attr[new_extruder].start_code.c_str()); CommandSocket::setExtruderForSend(new_extruder); CommandSocket::setSendCurrentPosition( getPositionXY() ); //Change the Z position so it gets re-writting again. We do not know if the switch code modified the Z position. currentPosition.z += 1; }
void GCodeExport::switchExtruder(int new_extruder) { if (current_extruder == new_extruder) return; if (!isRetracted) // assumes the last retraction already was an extruder switch retraction { writeRetraction_extruderSwitch(); } int old_extruder = current_extruder; current_extruder = new_extruder; if (flavor == EGCodeFlavor::MACH3) resetExtrusionValue(); isRetracted = true; writeCode(extruder_attr[old_extruder].end_code.c_str()); if (flavor == EGCodeFlavor::MAKERBOT) *output_stream << "M135 T" << current_extruder << "\n"; else // TinyG TODO: find out what a T code does *output_stream << "T" << current_extruder << "\n"; writeCode(extruder_attr[new_extruder].start_code.c_str()); //Change the Z position so it gets re-writting again. We do not know if the switch code modified the Z position. currentPosition.z += 1; }
void GCodeExport::switchExtruder(int newExtruder) { if (extruderNr == newExtruder) return; if (flavor == GCODE_FLAVOR_ULTIGCODE) { fprintf(f, "G10 S1\n"); }else{ fprintf(f, "G1 F%i %c%0.5lf\n", retractionSpeed * 60, extruderCharacter[extruderNr], extrusionAmount - extruderSwitchRetraction); currentSpeed = retractionSpeed; } resetExtrusionValue(); extruderNr = newExtruder; if (flavor == GCODE_FLAVOR_MACH3) resetExtrusionValue(); isRetracted = true; if (flavor == GCODE_FLAVOR_MAKERBOT) fprintf(f, "M135 T%i\n", extruderNr); else fprintf(f, "T%i\n", extruderNr); }
/*! * 换一台打印机 * \param newExtruder 新的打印机的序号 */ void GCodeExport::switchExtruder(int newExtruder) { if (extruderNr == newExtruder) return; if (flavor == GCODE_FLAVOR_BFB) { if (!isRetracted) *output_stream << "M103\r\n"; isRetracted = true; return; } resetExtrusionValue(); if (flavor == GCODE_FLAVOR_ULTIGCODE || flavor == GCODE_FLAVOR_REPRAP_VOLUMATRIC) { *output_stream << "G10 S1\n"; }else{ *output_stream << "G1 F" << (extruderSwitchRetractionSpeed * 60) << " " << extruderCharacter[extruderNr] << std::setprecision(5) << (extrusion_amount - extruderSwitchRetraction) << "\n"; currentSpeed = extruderSwitchRetractionSpeed; } extruderNr = newExtruder; if (flavor == GCODE_FLAVOR_MACH3) resetExtrusionValue(); isRetracted = true; writeCode(preSwitchExtruderCode[extruderNr].c_str()); if (flavor == GCODE_FLAVOR_MAKERBOT) *output_stream << "M135 T" << extruderNr << "\n"; else *output_stream << "T" << extruderNr << "\n"; writeCode(postSwitchExtruderCode[extruderNr].c_str()); //Change the Z position so it gets re-writting again. We do not know if the switch code modified the Z position. currentPosition.z += 1; }
void GCodeExport::switchExtruder(int new_extruder, const RetractionConfig& retraction_config_old_extruder) { if (current_extruder == new_extruder) return; bool force = true; bool extruder_switch = true; writeRetraction(&const_cast<RetractionConfig&>(retraction_config_old_extruder), force, extruder_switch); resetExtrusionValue(); // zero the E value on the old extruder, so that the current_e_value is registered on the old extruder int old_extruder = current_extruder; writeCode(extruder_attr[old_extruder].end_code.c_str()); startExtruder(new_extruder); }
void GCodeExport::switchExtruder(int newExtruder) { if (extruderNr == newExtruder) return; resetExtrusionValue(); extruderNr = newExtruder; if (flavor == GCODE_FLAVOR_ULTIGCODE) { fprintf(f, "G10 S1\n"); }else{ fprintf(f, "G1 F%i E%0.4lf\n", retractionSpeed * 60, extrusionAmount - extruderSwitchRetraction); currentSpeed = retractionSpeed; } isRetracted = true; fprintf(f, "T%i\n", extruderNr); }
void GCodeExport::writeRetraction_extruderSwitch() { if (isRetracted) { return; } if (flavor == EGCodeFlavor::BFB) { if (!isRetracted) *output_stream << "M103\r\n"; isRetracted = true; return; } resetExtrusionValue(); if (flavor == EGCodeFlavor::ULTIGCODE || flavor == EGCodeFlavor::REPRAP_VOLUMATRIC) { *output_stream << "G10 S1\n"; }else{ *output_stream << "G1 F" << (extruder_attr[current_extruder].extruderSwitchRetractionSpeed * 60) << " " << extruder_attr[current_extruder].extruderCharacter << std::setprecision(5) << (extrusion_amount - extruder_attr[current_extruder].extruderSwitchRetraction) << "\n"; currentSpeed = extruder_attr[current_extruder].extruderSwitchRetractionSpeed; } isRetracted = true; }
void GCodeExport::addMove(Point p, int speed, int lineWidth) { if (lineWidth != 0) { Point diff = p - getPositionXY(); if (isRetracted) { if (flavor == GCODE_FLAVOR_ULTIGCODE) { fprintf(f, "G11\n"); }else{ fprintf(f, "G1 F%i E%0.5lf\n", retractionSpeed * 60, extrusionAmount); currentSpeed = retractionSpeed; } if (extrusionAmount > 10000.0) //According to https://github.com/Ultimaker/CuraEngine/issues/14 having more then 21m of extrusion causes inaccuracies. So reset it every 10m, just to be sure. resetExtrusionValue(); isRetracted = false; } extrusionAmount += extrusionPerMM * double(lineWidth) / 1000.0 * vSizeMM(diff); fprintf(f, "G1"); }else{ fprintf(f, "G0"); } if (currentSpeed != speed) { fprintf(f, " F%i", speed * 60); currentSpeed = speed; } fprintf(f, " X%0.2f Y%0.2f", float(p.X - extruderOffset[extruderNr].X)/1000, float(p.Y - extruderOffset[extruderNr].Y)/1000); if (zPos != currentPosition.z) fprintf(f, " Z%0.2f", float(zPos)/1000); if (lineWidth != 0) fprintf(f, " E%0.5lf", extrusionAmount); fprintf(f, "\n"); currentPosition = Point3(p.X, p.Y, zPos); }
void GCodeExport::writeMove(int x, int y, int z, double speed, double extrusion_mm3_per_mm) { if (currentPosition.x == x && currentPosition.y == y && currentPosition.z == z) return; #ifdef ASSERT_INSANE_OUTPUT assert(speed < 200 && speed > 1); // normal F values occurring in UM2 gcode (this code should not be compiled for release) assert(currentPosition != no_point3); assert((Point3(x,y,z) - currentPosition).vSize() < MM2INT(300)); // no crazy positions (this code should not be compiled for release) #endif //ASSERT_INSANE_OUTPUT if (extrusion_mm3_per_mm < 0) logWarning("Warning! Negative extrusion move!"); if (flavor == EGCodeFlavor::BFB) { writeMoveBFB(x, y, z, speed, extrusion_mm3_per_mm); return; } double extrusion_per_mm = mm3ToE(extrusion_mm3_per_mm); Point gcode_pos = getGcodePos(x,y, current_extruder); if (extrusion_mm3_per_mm > 0.000001) { Point3 diff = Point3(x,y,z) - getPosition(); if (isZHopped > 0) { *output_stream << std::setprecision(3) << "G1 Z" << INT2MM(currentPosition.z) << new_line; isZHopped = 0; } double prime_volume = extruder_attr[current_extruder].prime_volume; current_e_value += mm3ToE(prime_volume); if (extruder_attr[current_extruder].retraction_e_amount_current) { if (firmware_retract) { // note that BFB is handled differently *output_stream << "G11" << new_line; //Assume default UM2 retraction settings. if (prime_volume > 0) { *output_stream << "G1 F" << (extruder_attr[current_extruder].last_retraction_prime_speed * 60) << " " << extruder_attr[current_extruder].extruderCharacter << std::setprecision(5) << current_e_value << new_line; currentSpeed = extruder_attr[current_extruder].last_retraction_prime_speed; } estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), eToMm(current_e_value)), 25.0); } else { current_e_value += extruder_attr[current_extruder].retraction_e_amount_current; *output_stream << "G1 F" << (extruder_attr[current_extruder].last_retraction_prime_speed * 60) << " " << extruder_attr[current_extruder].extruderCharacter << std::setprecision(5) << current_e_value << new_line; currentSpeed = extruder_attr[current_extruder].last_retraction_prime_speed; estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), eToMm(current_e_value)), currentSpeed); } if (getCurrentExtrudedVolume() > 10000.0) //According to https://github.com/Ultimaker/CuraEngine/issues/14 having more then 21m of extrusion causes inaccuracies. So reset it every 10m, just to be sure. { resetExtrusionValue(); } extruder_attr[current_extruder].retraction_e_amount_current = 0.0; } else if (prime_volume > 0.0) { *output_stream << "G1 F" << (extruder_attr[current_extruder].last_retraction_prime_speed * 60) << " " << extruder_attr[current_extruder].extruderCharacter << std::setprecision(5) << current_e_value << new_line; currentSpeed = extruder_attr[current_extruder].last_retraction_prime_speed; estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), eToMm(current_e_value)), currentSpeed); } extruder_attr[current_extruder].prime_volume = 0.0; current_e_value += extrusion_per_mm * diff.vSizeMM(); *output_stream << "G1"; } else { *output_stream << "G0"; CommandSocket::sendLineTo(extruder_attr[current_extruder].retraction_e_amount_current ? PrintFeatureType::MoveRetraction : PrintFeatureType::MoveCombing, Point(x, y), extruder_attr[current_extruder].retraction_e_amount_current ? MM2INT(0.2) : MM2INT(0.1)); } if (currentSpeed != speed) { *output_stream << " F" << (speed * 60); currentSpeed = speed; } *output_stream << std::setprecision(3) << " X" << INT2MM(gcode_pos.X) << " Y" << INT2MM(gcode_pos.Y); if (z != currentPosition.z + isZHopped) *output_stream << " Z" << INT2MM(z + isZHopped); if (extrusion_mm3_per_mm > 0.000001) *output_stream << " " << extruder_attr[current_extruder].extruderCharacter << std::setprecision(5) << current_e_value; *output_stream << new_line; currentPosition = Point3(x, y, z); estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), eToMm(current_e_value)), speed); }
void GCodeExport::writeMove(Point p, int speed, int lineWidth) { if (flavor == GCODE_FLAVOR_BFB) { //For Bits From Bytes machines, we need to handle this completely differently. As they do not use E values but RPM values. float fspeed = speed * 60; float rpm = (extrusionPerMM * double(lineWidth) / 1000.0) * speed * 60; const float mm_per_rpm = 4.0; //All BFB machines have 4mm per RPM extrusion. rpm /= mm_per_rpm; if (rpm > 0) { if (isRetracted) { if (currentSpeed != int(rpm * 10)) { //fprintf(f, "; %f e-per-mm %d mm-width %d mm/s\n", extrusionPerMM, lineWidth, speed); fprintf(f, "M108 S%0.1f\n", rpm * 10); currentSpeed = int(rpm * 10); } fprintf(f, "M101\n"); isRetracted = false; } //Fix the speed by the actual RPM we are asking, because of rounding errors we cannot get all RPM values, but we have a lot more resolution in the feedrate value. // (Trick copied from KISSlicer, thanks Jonathan) fspeed *= (rpm / (roundf(rpm * 100) / 100)); }else{ //If we are not extruding, check if we still need to disable the extruder. This causes a retraction due to auto-retraction. if (!isRetracted) { fprintf(f, "M103\n"); isRetracted = true; } } fprintf(f, "G1 X%0.2f Y%0.2f Z%0.2f F%0.1f\n", INT2MM(p.X - extruderOffset[extruderNr].X), INT2MM(p.Y - extruderOffset[extruderNr].Y), INT2MM(zPos), fspeed); }else{ //Normal E handling. if (lineWidth != 0) { Point diff = p - getPositionXY(); if (isRetracted) { if (retractionZHop > 0) fprintf(f, "G1 Z%0.2f\n", float(currentPosition.z)/1000); if (flavor == GCODE_FLAVOR_ULTIGCODE) { fprintf(f, "G11\n"); }else{ fprintf(f, "G1 F%i %c%0.5lf\n", retractionSpeed * 60, extruderCharacter[extruderNr], extrusionAmount); currentSpeed = retractionSpeed; estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(p.X), INT2MM(p.Y), INT2MM(zPos), extrusionAmount), currentSpeed); } if (extrusionAmount > 10000.0) //According to https://github.com/Ultimaker/CuraEngine/issues/14 having more then 21m of extrusion causes inaccuracies. So reset it every 10m, just to be sure. resetExtrusionValue(); isRetracted = false; } extrusionAmount += extrusionPerMM * INT2MM(lineWidth) * vSizeMM(diff); fprintf(f, "G1"); }else{ fprintf(f, "G0"); } if (currentSpeed != speed) { fprintf(f, " F%i", speed * 60); currentSpeed = speed; } fprintf(f, " X%0.2f Y%0.2f", INT2MM(p.X - extruderOffset[extruderNr].X), INT2MM(p.Y - extruderOffset[extruderNr].Y)); if (zPos != currentPosition.z) fprintf(f, " Z%0.2f", INT2MM(zPos)); if (lineWidth != 0) fprintf(f, " %c%0.5lf", extruderCharacter[extruderNr], extrusionAmount); fprintf(f, "\n"); } currentPosition = Point3(p.X, p.Y, zPos); estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), extrusionAmount), speed); }
void GCodeExport::writeMove(int x, int y, int z, double speed, double extrusion_mm3_per_mm) { if (currentPosition.x == x && currentPosition.y == y && currentPosition.z == z) return; assert(speed < 200 && speed > 1); // normal F values occurring in UM2 gcode (this code should not be compiled for release) assert((Point3(x,y,z) - currentPosition).vSize() < MM2INT(300)); // no crazy positions (this code should not be compiled for release) if (extrusion_mm3_per_mm < 0) logWarning("Warning! Negative extrusion move!"); double extrusion_per_mm = extrusion_mm3_per_mm; if (!is_volumatric) { extrusion_per_mm = extrusion_mm3_per_mm / getFilamentArea(current_extruder); } Point gcode_pos = getGcodePos(x,y, current_extruder); if (flavor == EGCodeFlavor::BFB) { //For Bits From Bytes machines, we need to handle this completely differently. As they do not use E values but RPM values. float fspeed = speed * 60; float rpm = extrusion_per_mm * speed * 60; const float mm_per_rpm = 4.0; //All BFB machines have 4mm per RPM extrusion. rpm /= mm_per_rpm; if (rpm > 0) { if (isRetracted) { if (currentSpeed != double(rpm)) { //fprintf(f, "; %f e-per-mm %d mm-width %d mm/s\n", extrusion_per_mm, lineWidth, speed); //fprintf(f, "M108 S%0.1f\r\n", rpm); *output_stream << "M108 S" << std::setprecision(1) << rpm << "\r\n"; currentSpeed = double(rpm); } //Add M101 or M201 to enable the proper extruder. *output_stream << "M" << int((current_extruder + 1) * 100 + 1) << "\r\n"; isRetracted = false; } //Fix the speed by the actual RPM we are asking, because of rounding errors we cannot get all RPM values, but we have a lot more resolution in the feedrate value. // (Trick copied from KISSlicer, thanks Jonathan) fspeed *= (rpm / (roundf(rpm * 100) / 100)); //Increase the extrusion amount to calculate the amount of filament used. Point3 diff = Point3(x,y,z) - getPosition(); extrusion_amount += extrusion_per_mm * diff.vSizeMM(); }else{ //If we are not extruding, check if we still need to disable the extruder. This causes a retraction due to auto-retraction. if (!isRetracted) { *output_stream << "M103\r\n"; isRetracted = true; } } *output_stream << std::setprecision(3) << "G1 X" << INT2MM(gcode_pos.X) << " Y" << INT2MM(gcode_pos.Y) << " Z" << INT2MM(z) << std::setprecision(1) << " F" << fspeed << "\r\n"; } else { //Normal E handling. if (extrusion_mm3_per_mm > 0.000001) { Point3 diff = Point3(x,y,z) - getPosition(); if (isZHopped > 0) { // TinyG G1: Straight feed *output_stream << std::setprecision(3) << "G1 Z" << INT2MM(currentPosition.z) << "\n"; isZHopped = 0; } extrusion_amount += (is_volumatric) ? last_coasted_amount_mm3 : last_coasted_amount_mm3 / getFilamentArea(current_extruder); if (isRetracted) { if (flavor == EGCodeFlavor::ULTIGCODE || flavor == EGCodeFlavor::REPRAP_VOLUMATRIC) { *output_stream << "G11\n"; //TODO try this code and see what happens //Assume default UM2 retraction settings. if (last_coasted_amount_mm3 > 0) { *output_stream << "G1 F" << (retractionPrimeSpeed * 60) << " " << extruder_attr[current_extruder].extruderCharacter << std::setprecision(5) << extrusion_amount << "\n"; } estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), extrusion_amount), 25.0); }else{ // TinyG checked *output_stream << "G1 F" << (retractionPrimeSpeed * 60) << " " << extruder_attr[current_extruder].extruderCharacter << std::setprecision(5) << extrusion_amount << "\n"; currentSpeed = retractionPrimeSpeed; estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), extrusion_amount), currentSpeed); } if (getExtrusionAmountMM3(current_extruder) > 10000.0) //According to https://github.com/Ultimaker/CuraEngine/issues/14 having more then 21m of extrusion causes inaccuracies. So reset it every 10m, just to be sure. resetExtrusionValue(); isRetracted = false; } else { if (last_coasted_amount_mm3 > 0) { *output_stream << "G1 F" << (retractionPrimeSpeed * 60) << " " << extruder_attr[current_extruder].extruderCharacter << std::setprecision(5) << extrusion_amount << "\n"; estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), extrusion_amount), currentSpeed); } } last_coasted_amount_mm3 = 0; extrusion_amount += extrusion_per_mm * diff.vSizeMM(); // TinyG TODO: add one axis *output_stream << "G1"; }else{ *output_stream << "G0"; if (commandSocket) { // we should send this travel as a non-retraction move cura::Polygons travelPoly; PolygonRef travel = travelPoly.newPoly(); travel.add(Point(currentPosition.x, currentPosition.y)); travel.add(Point(x, y)); commandSocket->sendPolygons(isRetracted ? MoveRetractionType : MoveCombingType, layer_nr, travelPoly, isRetracted ? MM2INT(0.2) : MM2INT(0.1)); } } if (currentSpeed != speed) { *output_stream << " F" << (speed * 60); currentSpeed = speed; } *output_stream << std::setprecision(3) << " X" << INT2MM(gcode_pos.X) << " Y" << INT2MM(gcode_pos.Y); if (z != currentPosition.z) *output_stream << " Z" << INT2MM(z + isZHopped); if (extrusion_mm3_per_mm > 0.000001) *output_stream << " " << extruder_attr[current_extruder].extruderCharacter << std::setprecision(5) << extrusion_amount; *output_stream << "\n"; } currentPosition = Point3(x, y, z); startPosition = currentPosition; estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), extrusion_amount), speed); }
/*! * 直线运动到指定点 */ void GCodeExport::writeMove(int x, int y, int z, int speed, double extrusion_per_mm) { if (currentPosition.x == x && currentPosition.y == y && currentPosition.z == z) return; if (flavor == GCODE_FLAVOR_BFB) { //For Bits From Bytes machines, we need to handle this completely differently. As they do not use E values but RPM values. float fspeed = speed * 60; float rpm = extrusion_per_mm * speed * 60; const float mm_per_rpm = 4.0; //All BFB machines have 4mm per RPM extrusion. rpm /= mm_per_rpm; if (rpm > 0) { if (isRetracted) { if (currentSpeed != int(rpm * 10)) { //fprintf(f, "; %f e-per-mm %d mm-width %d mm/s\n", extrusion_per_mm, lineWidth, speed); //fprintf(f, "M108 S%0.1f\r\n", rpm); *output_stream << "M108 S" << std::setprecision(1) << rpm << "\r\n"; currentSpeed = int(rpm * 10); } //Add M101 or M201 to enable the proper extruder. *output_stream << "M" << int((extruderNr + 1) * 100 + 1) << "\r\n"; isRetracted = false; } //Fix the speed by the actual RPM we are asking, because of rounding errors we cannot get all RPM values, but we have a lot more resolution in the feedrate value. // (Trick copied from KISSlicer, thanks Jonathan) fspeed *= (rpm / (roundf(rpm * 100) / 100)); //Increase the extrusion amount to calculate the amount of filament used. Point3 diff = Point3(x,y,z) - getPosition(); extrusion_amount += extrusion_per_mm * diff.vSizeMM(); }else{ //If we are not extruding, check if we still need to disable the extruder. This causes a retraction due to auto-retraction. if (!isRetracted) { *output_stream << "M103\r\n"; isRetracted = true; } } *output_stream << std::setprecision(3)/*精度设定*/ << "G1 X" << INT2MM(x - extruderOffset[extruderNr].X) << " Y" << INT2MM(y - extruderOffset[extruderNr].Y) << " Z" << INT2MM(z) << std::setprecision(1) << " F" << fspeed << "\r\n"; }else{ //Normal E handling. if (extrusion_per_mm > 0.000001) { Point3 diff = Point3(x,y,z) - getPosition(); if (isZHopped > 0) { *output_stream << std::setprecision(3) << "G1 Z" << INT2MM(currentPosition.z) << "\n"; isZHopped = false; } if (isRetracted) { if (flavor == GCODE_FLAVOR_ULTIGCODE || flavor == GCODE_FLAVOR_REPRAP_VOLUMATRIC) { *output_stream << "G11\n"; //Assume default UM2 retraction settings. estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), extrusion_amount), 25.0); }else{ *output_stream << "G1 F" << (retractionPrimeSpeed * 60) << " " << extruderCharacter[extruderNr] << std::setprecision(5) << extrusion_amount << "\n"; currentSpeed = retractionPrimeSpeed; estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), extrusion_amount), currentSpeed); } if (extrusion_amount > 10000.0) //According to https://github.com/Ultimaker/CuraEngine/issues/14 having more then 21m of extrusion causes inaccuracies. So reset it every 10m, just to be sure. resetExtrusionValue(); isRetracted = false; } extrusion_amount += extrusion_per_mm * diff.vSizeMM(); *output_stream << "G1"; }else{ *output_stream << "G0"; } if (currentSpeed != speed) { *output_stream << " F" << (speed * 60); currentSpeed = speed; } *output_stream << std::setprecision(3) << " X" << INT2MM(x - extruderOffset[extruderNr].X) << " Y" << INT2MM(y - extruderOffset[extruderNr].Y); if (z != currentPosition.z) *output_stream << " Z" << INT2MM(z); if (extrusion_per_mm > 0.000001) *output_stream << " " << extruderCharacter[extruderNr] << std::setprecision(5) << extrusion_amount; *output_stream << "\n"; } currentPosition = Point3(x, y, z); startPosition = currentPosition; estimateCalculator.plan(TimeEstimateCalculator::Position(INT2MM(currentPosition.x), INT2MM(currentPosition.y), INT2MM(currentPosition.z), extrusion_amount), speed); }