public void WriteQueuedGCode(long layerThickness_um) { GCodePathConfig lastConfig = null; int extruderIndex = gcodeExport.GetExtruderIndex(); for (int pathIndex = 0; pathIndex < paths.Count; pathIndex++) { var path = paths[pathIndex]; if (extruderIndex != path.ExtruderIndex) { extruderIndex = path.ExtruderIndex; gcodeExport.SwitchExtruder(extruderIndex); } else if (path.Retract != RetractType.None) { double timeOfMove = 0; if (path.Config.LineWidthUM == 0) { var lengthToStart = (gcodeExport.GetPosition() - path.Polygon[0]).Length(); var lengthOfMove = lengthToStart + path.Polygon.PolygonLength(); timeOfMove = lengthOfMove / 1000.0 / path.Speed; } gcodeExport.WriteRetraction(timeOfMove, path.Retract == RetractType.Force); } if (lastConfig != path.Config && path.Config != travelConfig) { gcodeExport.WriteComment("TYPE:{0}".FormatWith(path.Config.GCodeComment)); lastConfig = path.Config; } if (path.FanPercent != -1) { gcodeExport.WriteFanCommand(path.FanPercent); } if (path.Polygon.Count == 1 && path.Config != travelConfig && (gcodeExport.GetPositionXY() - path.Polygon[0]).ShorterThen(path.Config.LineWidthUM * 2)) { //Check for lots of small moves and combine them into one large line IntPoint nextPosition = path.Polygon[0]; int i = pathIndex + 1; while (i < paths.Count && paths[i].Polygon.Count == 1 && (nextPosition - paths[i].Polygon[0]).ShorterThen(path.Config.LineWidthUM * 2)) { nextPosition = paths[i].Polygon[0]; i++; } if (paths[i - 1].Config == travelConfig) { i--; } if (i > pathIndex + 2) { nextPosition = gcodeExport.GetPosition(); for (int x = pathIndex; x < i - 1; x += 2) { long oldLen = (nextPosition - paths[x].Polygon[0]).Length(); IntPoint newPoint = (paths[x].Polygon[0] + paths[x + 1].Polygon[0]) / 2; long newLen = (gcodeExport.GetPosition() - newPoint).Length(); if (newLen > 0) { gcodeExport.WriteMove(newPoint, path.Speed, (int)(path.Config.LineWidthUM * oldLen / newLen)); } nextPosition = paths[x + 1].Polygon[0]; } long lineWidth_um = path.Config.LineWidthUM; if (paths[i - 1].Polygon[0].Width != 0) { lineWidth_um = paths[i - 1].Polygon[0].Width; } gcodeExport.WriteMove(paths[i - 1].Polygon[0], path.Speed, lineWidth_um); pathIndex = i - 1; continue; } } bool spiralize = path.Config.Spiralize; if (spiralize) { //Check if we are the last spiralize path in the list, if not, do not spiralize. for (int m = pathIndex + 1; m < paths.Count; m++) { if (paths[m].Config.Spiralize) { spiralize = false; } } } if (spiralize) // if we are still in spiralize mode { //If we need to spiralize then raise the head slowly by 1 layer as this path progresses. double totalLength = 0; long z = gcodeExport.GetPositionZ(); IntPoint currentPosition = gcodeExport.GetPositionXY(); for (int pointIndex = 0; pointIndex < path.Polygon.Count; pointIndex++) { IntPoint nextPosition = path.Polygon[pointIndex]; totalLength += (currentPosition - nextPosition).LengthMm(); currentPosition = nextPosition; } double length = 0.0; currentPosition = gcodeExport.GetPositionXY(); for (int i = 0; i < path.Polygon.Count; i++) { IntPoint nextPosition = path.Polygon[i]; length += (currentPosition - nextPosition).LengthMm(); currentPosition = nextPosition; IntPoint nextExtrusion = path.Polygon[i]; nextExtrusion.Z = (int)(z + layerThickness_um * length / totalLength + .5); gcodeExport.WriteMove(nextExtrusion, path.Speed, path.Config.LineWidthUM); } } else { var loopStart = gcodeExport.GetPosition(); int pointCount = path.Polygon.Count; bool outerPerimeter = path.Config.GCodeComment == "WALL-OUTER"; bool innerPerimeter = path.Config.GCodeComment == "WALL-INNER"; bool perimeter = outerPerimeter || innerPerimeter; bool completeLoop = (pointCount > 0 && path.Polygon[pointCount - 1] == loopStart); bool trimmed = perimeter && completeLoop && perimeterStartEndOverlapRatio < 1; // This is test code to remove double drawn small perimeter lines. if (trimmed) { long targetDistance = (long)(path.Config.LineWidthUM * (1 - perimeterStartEndOverlapRatio)); path = TrimGCodePathEnd(path, targetDistance); // update the point count after trimming pointCount = path.Polygon.Count; } for (int i = 0; i < pointCount; i++) { long lineWidth_um = path.Config.LineWidthUM; if (path.Polygon[i].Width != 0) { lineWidth_um = path.Polygon[i].Width; } gcodeExport.WriteMove(path.Polygon[i], path.Speed, lineWidth_um); } if (trimmed) { // go back to the start of the loop gcodeExport.WriteMove(loopStart, path.Speed, 0); var length = path.Polygon.PolygonLength(false); if (outerPerimeter && config.CoastAtEndDistance_um > 0 && length > config.CoastAtEndDistance_um) { //gcodeExport.WriteRetraction var wipePoly = new Polygon(new IntPoint[] { loopStart }); wipePoly.AddRange(path.Polygon); // then drive down it just a bit more to make sure we have a clean overlap var extraMove = wipePoly.CutToLength(config.CoastAtEndDistance_um); for (int i = 0; i < extraMove.Count; i++) { gcodeExport.WriteMove(extraMove[i], path.Speed, 0); } } } } } gcodeExport.UpdateLayerPrintTime(); }