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();
        }