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::finalize(int maxObjectHeight, double moveSpeed, const char* endCode) { writeFanCommand(0); setZ(maxObjectHeight + 5000); writeMove(Point3(0,0,maxObjectHeight + 5000) + getPositionXY(), moveSpeed, 0); writeCode(endCode); log("Print time: %d\n", int(getTotalPrintTime())); log("Filament: %d\n", int(getTotalFilamentUsed(0))); for(int n=1; n<MAX_EXTRUDERS; n++) if (getTotalFilamentUsed(n) > 0) log("Filament%d: %d\n", n + 1, int(getTotalFilamentUsed(n))); output_stream->flush(); }
void GCodeExport::finalize(int maxObjectHeight, int moveSpeed, const char* endCode) { writeFanCommand(0); writeRetraction(); setZ(maxObjectHeight + 5000); writeMove(getPositionXY(), moveSpeed, 0); writeCode(endCode); log("Print time: %d\n", int(getTotalPrintTime())); log("Filament: %d\n", int(getTotalFilamentUsed(0))); log("Filament2: %d\n", int(getTotalFilamentUsed(1))); if (getFlavor() == GCODE_FLAVOR_ULTIGCODE) { char numberString[16]; sprintf(numberString, "%d", int(getTotalPrintTime())); replaceTagInStart("<__TIME__>", numberString); sprintf(numberString, "%d", int(getTotalFilamentUsed(0))); replaceTagInStart("<FILAMENT>", numberString); sprintf(numberString, "%d", int(getTotalFilamentUsed(1))); replaceTagInStart("<FILAMEN2>", numberString); } }
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(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); }