Example #1
0
        public GCodePlanner(GCodeExport gcode, int travelSpeed, int retractionMinimumDistance_um, double perimeterStartEndOverlap = 0)
        {
            this.gcodeExport = gcode;
            travelConfig     = new GCodePathConfig("travelConfig");
            travelConfig.SetData(travelSpeed, 0, "travel");

            LastPosition         = gcode.GetPositionXY();
            totalPrintTime       = 0.0;
            forceRetraction      = false;
            currentExtruderIndex = gcode.GetExtruderIndex();
            this.retractionMinimumDistance_um = retractionMinimumDistance_um;

            this.perimeterStartEndOverlapRatio = Math.Max(0, Math.Min(1, perimeterStartEndOverlap));
        }
        public LayerGCodePlanner(ConfigSettings config, GCodeExport gcode, int travelSpeed, long retractionMinimumDistance_um, double perimeterStartEndOverlap = 0)
        {
            this.config = config;

            this.gcodeExport = gcode;
            travelConfig     = new GCodePathConfig("travelConfig", "travel");
            travelConfig.SetData(travelSpeed, 0);

            LastPosition         = gcode.GetPositionXY();
            forceRetraction      = false;
            currentExtruderIndex = gcode.GetExtruderIndex();
            this.retractionMinimumDistance_um = retractionMinimumDistance_um;

            this.perimeterStartEndOverlapRatio = Math.Max(0, Math.Min(1, perimeterStartEndOverlap));
        }
Example #3
0
        public GCodePlanner(GCodeExport gcode, int travelSpeed, int retractionMinimumDistance)
        {
            this.gcode   = gcode;
            travelConfig = new GCodePathConfig(travelSpeed, 0, "travel");

            lastPosition = gcode.getPositionXY();
            outerPerimetersToAvoidCrossing = null;
            extrudeSpeedFactor             = 100;
            travelSpeedFactor              = 100;
            extraTime                      = 0.0;
            totalPrintTime                 = 0.0;
            forceRetraction                = false;
            alwaysRetract                  = false;
            currentExtruderIndex           = gcode.getExtruderIndex();
            this.retractionMinimumDistance = retractionMinimumDistance;
        }
Example #4
0
        public GCodePlanner(GCodeExport gcode, int travelSpeed, int retractionMinimumDistance_um)
        {
            this.gcode = gcode;
            travelConfig = new GCodePathConfig(travelSpeed, 0, "travel");

            lastPosition = gcode.GetPositionXY();
            outerPerimetersToAvoidCrossing = null;
            extrudeSpeedFactor = 100;
            travelSpeedFactor = 100;
            extraTime = 0.0;
            totalPrintTime = 0.0;
            forceRetraction = false;
            alwaysRetract = false;
            currentExtruderIndex = gcode.GetExtruderIndex();
            this.retractionMinimumDistance_um = retractionMinimumDistance_um;
        }
Example #5
0
        public GCodePlanner(GCodeExport gcode, int travelSpeed, int retractionMinimumDistance_um, double perimeterStartEndOverlap = 0)
        {
            this.gcodeExport = gcode;
            travelConfig =  new GCodePathConfig("travelConfig");
            travelConfig.SetData(travelSpeed, 0, "travel");

            LastPosition = gcode.GetPositionXY();
            outerPerimetersToAvoidCrossing = null;
            extrudeSpeedFactor = 100;
            travelSpeedFactor = 100;
            extraTime = 0.0;
            totalPrintTime = 0.0;
            forceRetraction = false;
            alwaysRetract = false;
            currentExtruderIndex = gcode.GetExtruderIndex();
            this.retractionMinimumDistance_um = retractionMinimumDistance_um;

            this.perimeterStartEndOverlapRatio = Math.Max(0, Math.Min(1, perimeterStartEndOverlap));
        }
Example #6
0
        public GCodePlanner(GCodeExport gcode, int travelSpeed, int retractionMinimumDistance_um, double perimeterStartEndOverlap = 0, bool mergeOverlappingLines = false)
        {
            this.mergeOverlappingLines = mergeOverlappingLines;
            this.gcodeExport           = gcode;
            travelConfig = new GCodePathConfig("travelConfig");
            travelConfig.SetData(travelSpeed, 0, "travel");

            LastPosition = gcode.GetPositionXY();
            outerPerimetersToAvoidCrossing = null;
            extrudeSpeedFactor             = 100;
            travelSpeedFactor    = 100;
            extraTime            = 0.0;
            totalPrintTime       = 0.0;
            forceRetraction      = false;
            alwaysRetract        = false;
            currentExtruderIndex = gcode.GetExtruderIndex();
            this.retractionMinimumDistance_um = retractionMinimumDistance_um;

            this.perimeterStartEndOverlapRatio = Math.Max(0, Math.Min(1, perimeterStartEndOverlap));
        }
        private int GetFanPercent(int layerIndex, GCodeExport gcodeExport)
        {
            if (layerIndex < config.FirstLayerToAllowFan)
            {
                // Don't allow the fan below this layer
                return(0);
            }

            var minFanSpeedLayerTime = Math.Max(config.MinFanSpeedLayerTime, config.MaxFanSpeedLayerTime);

            // check if the layer time is slow enough that we need to turn the fan on
            if (this.LayerTime < minFanSpeedLayerTime)
            {
                if (config.MaxFanSpeedLayerTime >= minFanSpeedLayerTime)
                {
                    // the max always comes on first so just return the max speed
                    return(config.FanSpeedMaxPercent);
                }

                // figure out how much to turn it on
                var amountSmallerThanMin = Math.Max(0, minFanSpeedLayerTime - this.LayerTime);
                var timeToMax            = Math.Max(0, minFanSpeedLayerTime - config.MaxFanSpeedLayerTime);

                double ratioToMaxSpeed = 0;
                if (timeToMax > 0)
                {
                    ratioToMaxSpeed = Math.Min(1, amountSmallerThanMin / timeToMax);
                }

                return(config.FanSpeedMinPercent + (int)(ratioToMaxSpeed * (config.FanSpeedMaxPercent - config.FanSpeedMinPercent)));
            }
            else             // we are going to slow turn the fan off
            {
                return(0);
            }
        }
Example #8
0
		public void WriteRaftGCodeIfRequired(ConfigSettings config, GCodeExport gcode)
		{
			LayerDataStorage storage = this;
			if (config.ShouldGenerateRaft())
			{
				GCodePathConfig raftBaseConfig = new GCodePathConfig(config.firstLayerSpeed, config.raftBaseExtrusionWidth_um, "SUPPORT");
				GCodePathConfig raftMiddleConfig = new GCodePathConfig(config.raftPrintSpeed, config.raftInterfaceExtrusionWidth_um, "SUPPORT");
				GCodePathConfig raftSurfaceConfig = new GCodePathConfig((config.raftSurfacePrintSpeed > 0) ? config.raftSurfacePrintSpeed : config.raftPrintSpeed, config.raftSurfaceExtrusionWidth_um, "SUPPORT");

				// create the raft base
				{
					gcode.WriteComment("LAYER:-3");
					gcode.WriteComment("RAFT BASE");
					GCodePlanner gcodeLayer = new GCodePlanner(gcode, config.travelSpeed, config.minimumTravelToCauseRetraction_um);
					if (config.raftExtruder >= 0)
					{
						// if we have a specified raft extruder use it
						gcodeLayer.SetExtruder(config.raftExtruder);
					}
					else if (config.supportExtruder >= 0)
					{
						// else preserve the old behavior of using the support extruder if set.
						gcodeLayer.SetExtruder(config.supportExtruder);
					}

					gcode.setZ(config.raftBaseThickness_um);
					gcode.SetExtrusion(config.raftBaseThickness_um, config.filamentDiameter_um, config.extrusionMultiplier);

					Polygons raftLines = new Polygons();
					Infill.GenerateLinePaths(storage.raftOutline, ref raftLines, config.raftBaseLineSpacing_um, config.infillExtendIntoPerimeter_um, 0);

					// write the skirt around the raft
					gcodeLayer.QueuePolygonsByOptimizer(storage.skirt, raftBaseConfig);

					// write the outline of the raft
					gcodeLayer.QueuePolygonsByOptimizer(storage.raftOutline, raftBaseConfig);

					// write the inside of the raft base
					gcodeLayer.QueuePolygonsByOptimizer(raftLines, raftBaseConfig);

					gcodeLayer.WriteQueuedGCode(config.raftBaseThickness_um);
				}

				if (config.raftFanSpeedPercent > 0)
				{
					gcode.WriteFanCommand(config.raftFanSpeedPercent);
				}

				// raft middle layers
				{
					gcode.WriteComment("LAYER:-2");
					gcode.WriteComment("RAFT MIDDLE");
					GCodePlanner gcodeLayer = new GCodePlanner(gcode, config.travelSpeed, config.minimumTravelToCauseRetraction_um);
					gcode.setZ(config.raftBaseThickness_um + config.raftInterfaceThicknes_um);
					gcode.SetExtrusion(config.raftInterfaceThicknes_um, config.filamentDiameter_um, config.extrusionMultiplier);

					Polygons raftLines = new Polygons();
					Infill.GenerateLinePaths(storage.raftOutline, ref raftLines, config.raftInterfaceLineSpacing_um, config.infillExtendIntoPerimeter_um, 45);
					gcodeLayer.QueuePolygonsByOptimizer(raftLines, raftMiddleConfig);

					gcodeLayer.WriteQueuedGCode(config.raftInterfaceThicknes_um);
				}

				for (int raftSurfaceIndex = 1; raftSurfaceIndex <= config.raftSurfaceLayers; raftSurfaceIndex++)
				{
					gcode.WriteComment("LAYER:-1");
					gcode.WriteComment("RAFT SURFACE");
					GCodePlanner gcodeLayer = new GCodePlanner(gcode, config.travelSpeed, config.minimumTravelToCauseRetraction_um);
					gcode.setZ(config.raftBaseThickness_um + config.raftInterfaceThicknes_um + config.raftSurfaceThickness_um * raftSurfaceIndex);
					gcode.SetExtrusion(config.raftSurfaceThickness_um, config.filamentDiameter_um, config.extrusionMultiplier);

					Polygons raftLines = new Polygons();
					if (raftSurfaceIndex == config.raftSurfaceLayers)
					{
						// make sure the top layer of the raft is 90 degrees offset to the first layer of the part so that it has minimum contact points.
						Infill.GenerateLinePaths(storage.raftOutline, ref raftLines, config.raftSurfaceLineSpacing_um, config.infillExtendIntoPerimeter_um, config.infillStartingAngle + 90);
					}
					else
					{
						Infill.GenerateLinePaths(storage.raftOutline, ref raftLines, config.raftSurfaceLineSpacing_um, config.infillExtendIntoPerimeter_um, 90 * raftSurfaceIndex);
					}
					gcodeLayer.QueuePolygonsByOptimizer(raftLines, raftSurfaceConfig);

					gcodeLayer.WriteQueuedGCode(config.raftInterfaceThicknes_um);
				}
			}
		}
Example #9
0
        public void WriteRaftGCodeIfRequired(GCodeExport gcode, ConfigSettings config)
        {
            LayerDataStorage storage = this;

            if (config.ShouldGenerateRaft())
            {
                GCodePathConfig raftBaseConfig = new GCodePathConfig("raftBaseConfig");
                raftBaseConfig.SetData(config.FirstLayerSpeed, config.RaftBaseExtrusionWidth_um, "SUPPORT");

                GCodePathConfig raftMiddleConfig = new GCodePathConfig("raftMiddleConfig");
                raftMiddleConfig.SetData(config.RaftPrintSpeed, config.RaftInterfaceExtrusionWidth_um, "SUPPORT");

                GCodePathConfig raftSurfaceConfig = new GCodePathConfig("raftMiddleConfig");
                raftSurfaceConfig.SetData((config.RaftSurfacePrintSpeed > 0) ? config.RaftSurfacePrintSpeed : config.RaftPrintSpeed, config.RaftSurfaceExtrusionWidth_um, "SUPPORT");

                // create the raft base
                {
                    gcode.WriteComment("RAFT BASE");
                    LayerGCodePlanner layerPlanner = new LayerGCodePlanner(config, gcode, config.TravelSpeed, config.MinimumTravelToCauseRetraction_um, config.PerimeterStartEndOverlapRatio);
                    if (config.RaftExtruder >= 0)
                    {
                        // if we have a specified raft extruder use it
                        layerPlanner.SetExtruder(config.RaftExtruder);
                    }
                    else if (config.SupportExtruder >= 0)
                    {
                        // else preserve the old behavior of using the support extruder if set.
                        layerPlanner.SetExtruder(config.SupportExtruder);
                    }

                    gcode.CurrentZ = config.RaftBaseThickness_um;

                    gcode.LayerChanged(-3, config.RaftBaseThickness_um);

                    gcode.SetExtrusion(config.RaftBaseThickness_um, config.FilamentDiameter_um, config.ExtrusionMultiplier);

                    // write the skirt around the raft
                    layerPlanner.QueuePolygonsByOptimizer(storage.Skirt, null, raftBaseConfig, 0);

                    List <Polygons> raftIslands = storage.raftOutline.ProcessIntoSeparateIslands();
                    foreach (var raftIsland in raftIslands)
                    {
                        // write the outline of the raft
                        layerPlanner.QueuePolygonsByOptimizer(raftIsland, null, raftBaseConfig, 0);

                        Polygons raftLines = new Polygons();
                        Infill.GenerateLinePaths(raftIsland.Offset(-config.RaftBaseExtrusionWidth_um), raftLines, config.RaftBaseLineSpacing_um, config.InfillExtendIntoPerimeter_um, 0);

                        // write the inside of the raft base
                        layerPlanner.QueuePolygonsByOptimizer(raftLines, null, raftBaseConfig, 0);

                        if (config.RetractWhenChangingIslands)
                        {
                            layerPlanner.ForceRetract();
                        }
                    }

                    layerPlanner.WriteQueuedGCode(config.RaftBaseThickness_um);
                }

                // raft middle layers
                {
                    gcode.WriteComment("RAFT MIDDLE");
                    LayerGCodePlanner layerPlanner = new LayerGCodePlanner(config, gcode, config.TravelSpeed, config.MinimumTravelToCauseRetraction_um, config.PerimeterStartEndOverlapRatio);
                    gcode.CurrentZ = config.RaftBaseThickness_um + config.RaftInterfaceThicknes_um;
                    gcode.LayerChanged(-2, config.RaftInterfaceThicknes_um);
                    gcode.SetExtrusion(config.RaftInterfaceThicknes_um, config.FilamentDiameter_um, config.ExtrusionMultiplier);

                    Polygons raftLines = new Polygons();
                    Infill.GenerateLinePaths(storage.raftOutline, raftLines, config.RaftInterfaceLineSpacing_um, config.InfillExtendIntoPerimeter_um, 45);
                    layerPlanner.QueuePolygonsByOptimizer(raftLines, null, raftMiddleConfig, 0);

                    layerPlanner.WriteQueuedGCode(config.RaftInterfaceThicknes_um);
                }

                for (int raftSurfaceIndex = 1; raftSurfaceIndex <= config.RaftSurfaceLayers; raftSurfaceIndex++)
                {
                    gcode.WriteComment("RAFT SURFACE");
                    LayerGCodePlanner layerPlanner = new LayerGCodePlanner(config, gcode, config.TravelSpeed, config.MinimumTravelToCauseRetraction_um, config.PerimeterStartEndOverlapRatio);
                    gcode.CurrentZ = config.RaftBaseThickness_um + config.RaftInterfaceThicknes_um + config.RaftSurfaceThickness_um * raftSurfaceIndex;
                    gcode.LayerChanged(-1, config.RaftSurfaceThickness_um);
                    gcode.SetExtrusion(config.RaftSurfaceThickness_um, config.FilamentDiameter_um, config.ExtrusionMultiplier);

                    Polygons raftLines = new Polygons();
                    if (raftSurfaceIndex == config.RaftSurfaceLayers)
                    {
                        // make sure the top layer of the raft is 90 degrees offset to the first layer of the part so that it has minimum contact points.
                        Infill.GenerateLinePaths(storage.raftOutline, raftLines, config.RaftSurfaceLineSpacing_um, config.InfillExtendIntoPerimeter_um, config.InfillStartingAngle + 90);
                    }
                    else
                    {
                        Infill.GenerateLinePaths(storage.raftOutline, raftLines, config.RaftSurfaceLineSpacing_um, config.InfillExtendIntoPerimeter_um, 90 * raftSurfaceIndex);
                    }
                    layerPlanner.QueuePolygonsByOptimizer(raftLines, null, raftSurfaceConfig, 0);

                    layerPlanner.WriteQueuedGCode(config.RaftInterfaceThicknes_um);
                }
            }
        }
Example #10
0
        public static void GenerateRaftGCodeIfRequired(SliceDataStorage storage, ConfigSettings config, GCodeExport gcode)
        {
            if (ShouldGenerateRaft(config))
            {
                GCodePathConfig raftBaseConfig    = new GCodePathConfig(config.firstLayerSpeed, config.extrusionWidth_um * 3, "SUPPORT");
                GCodePathConfig raftMiddleConfig  = new GCodePathConfig(config.raftPrintSpeed, config.raftInterfaceLinewidth_um, "SUPPORT");
                GCodePathConfig raftSurfaceConfig = new GCodePathConfig((config.raftSurfacePrintSpeed > 0) ? config.raftSurfacePrintSpeed : config.raftPrintSpeed, config.raftSurfaceLinewidth_um, "SUPPORT");

                // create the raft base
                {
                    gcode.writeComment("LAYER:-3");
                    gcode.writeComment("RAFT BASE");
                    GCodePlanner gcodeLayer = new GCodePlanner(gcode, config.travelSpeed, config.minimumTravelToCauseRetraction_um);
                    if (config.supportExtruder > 0)
                    {
                        gcodeLayer.setExtruder(config.supportExtruder);
                    }

                    gcode.setZ(config.raftBaseThickness_um);
                    gcode.setExtrusion(config.raftBaseThickness_um, config.filamentDiameter_um, config.extrusionMultiplier);
                    gcodeLayer.writePolygonsByOptimizer(storage.raftOutline, raftBaseConfig);

                    Polygons raftLines = new Polygons();
                    Infill.GenerateLinePaths(storage.raftOutline, ref raftLines, config.raftBaseThickness_um, config.raftLineSpacing_um, config.infillExtendIntoPerimeter_um, 0);
                    gcodeLayer.writePolygonsByOptimizer(storage.skirt, raftBaseConfig);
                    gcodeLayer.writePolygonsByOptimizer(raftLines, raftBaseConfig);

                    gcodeLayer.writeGCode(false, config.raftBaseThickness_um);
                }

                if (config.raftFanSpeedPercent > 0)
                {
                    gcode.writeFanCommand(config.raftFanSpeedPercent);
                }

                // raft middle layers
                {
                    gcode.writeComment("LAYER:-2");
                    gcode.writeComment("RAFT MIDDLE");
                    GCodePlanner gcodeLayer = new GCodePlanner(gcode, config.travelSpeed, config.minimumTravelToCauseRetraction_um);
                    gcode.setZ(config.raftBaseThickness_um + config.raftInterfaceThicknes_um);
                    gcode.setExtrusion(config.raftInterfaceThicknes_um, config.filamentDiameter_um, config.extrusionMultiplier);

                    Polygons raftLines = new Polygons();
                    Infill.GenerateLinePaths(storage.raftOutline, ref raftLines, config.raftInterfaceLinewidth_um, config.raftInterfaceLineSpacing_um, config.infillExtendIntoPerimeter_um, 45);
                    gcodeLayer.writePolygonsByOptimizer(raftLines, raftMiddleConfig);

                    gcodeLayer.writeGCode(false, config.raftInterfaceThicknes_um);
                }

                for (int raftSurfaceLayer = 1; raftSurfaceLayer <= config.raftSurfaceLayers; raftSurfaceLayer++)
                {
                    gcode.writeComment("LAYER:-1");
                    gcode.writeComment("RAFT SURFACE");
                    GCodePlanner gcodeLayer = new GCodePlanner(gcode, config.travelSpeed, config.minimumTravelToCauseRetraction_um);
                    gcode.setZ(config.raftBaseThickness_um + config.raftInterfaceThicknes_um + config.raftSurfaceThickness_um * raftSurfaceLayer);
                    gcode.setExtrusion(config.raftSurfaceThickness_um, config.filamentDiameter_um, config.extrusionMultiplier);

                    Polygons raftLines = new Polygons();
                    Infill.GenerateLinePaths(storage.raftOutline, ref raftLines, config.raftSurfaceLinewidth_um, config.raftSurfaceLineSpacing_um, config.infillExtendIntoPerimeter_um, 90 * raftSurfaceLayer);
                    gcodeLayer.writePolygonsByOptimizer(raftLines, raftSurfaceConfig);

                    gcodeLayer.writeGCode(false, config.raftInterfaceThicknes_um);
                }
            }
        }
Example #11
0
        public static void GenerateRaftGCodeIfRequired(SliceDataStorage storage, ConfigSettings config, GCodeExport gcode)
        {
            if (ShouldGenerateRaft(config))
            {
                GCodePathConfig raftBaseConfig    = new GCodePathConfig(config.firstLayerSpeed, config.raftBaseExtrusionWidth_um, "SUPPORT");
                GCodePathConfig raftMiddleConfig  = new GCodePathConfig(config.raftPrintSpeed, config.raftInterfaceExtrusionWidth_um, "SUPPORT");
                GCodePathConfig raftSurfaceConfig = new GCodePathConfig((config.raftSurfacePrintSpeed > 0) ? config.raftSurfacePrintSpeed : config.raftPrintSpeed, config.raftSurfaceExtrusionWidth_um, "SUPPORT");

                // create the raft base
                {
                    gcode.writeComment("LAYER:-3");
                    gcode.writeComment("RAFT BASE");
                    GCodePlanner gcodeLayer = new GCodePlanner(gcode, config.travelSpeed, config.minimumTravelToCauseRetraction_um);
                    if (config.raftExtruder > 0)
                    {
                        // if we have a specified raft extruder use it
                        gcodeLayer.setExtruder(config.raftExtruder);
                    }
                    else if (config.supportExtruder > 0)
                    {
                        // else preserve the old behavior of using the support extruder if set.
                        gcodeLayer.setExtruder(config.supportExtruder);
                    }

                    gcode.setZ(config.raftBaseThickness_um);
                    gcode.setExtrusion(config.raftBaseThickness_um, config.filamentDiameter_um, config.extrusionMultiplier);
                    gcodeLayer.writePolygonsByOptimizer(storage.raftOutline, raftBaseConfig);

                    Polygons raftLines = new Polygons();
                    Infill.GenerateLinePaths(storage.raftOutline, ref raftLines, config.raftBaseLineSpacing_um, config.infillExtendIntoPerimeter_um, 0);
                    gcodeLayer.writePolygonsByOptimizer(storage.skirt, raftBaseConfig);
                    gcodeLayer.writePolygonsByOptimizer(raftLines, raftBaseConfig);

                    gcodeLayer.writeGCode(false, config.raftBaseThickness_um);
                }

                if (config.raftFanSpeedPercent > 0)
                {
                    gcode.writeFanCommand(config.raftFanSpeedPercent);
                }

                // raft middle layers
                {
                    gcode.writeComment("LAYER:-2");
                    gcode.writeComment("RAFT MIDDLE");
                    GCodePlanner gcodeLayer = new GCodePlanner(gcode, config.travelSpeed, config.minimumTravelToCauseRetraction_um);
                    gcode.setZ(config.raftBaseThickness_um + config.raftInterfaceThicknes_um);
                    gcode.setExtrusion(config.raftInterfaceThicknes_um, config.filamentDiameter_um, config.extrusionMultiplier);

                    Polygons raftLines = new Polygons();
                    Infill.GenerateLinePaths(storage.raftOutline, ref raftLines, config.raftInterfaceLineSpacing_um, config.infillExtendIntoPerimeter_um, 45);
                    gcodeLayer.writePolygonsByOptimizer(raftLines, raftMiddleConfig);

                    gcodeLayer.writeGCode(false, config.raftInterfaceThicknes_um);
                }

                for (int raftSurfaceIndex = 1; raftSurfaceIndex <= config.raftSurfaceLayers; raftSurfaceIndex++)
                {
                    gcode.writeComment("LAYER:-1");
                    gcode.writeComment("RAFT SURFACE");
                    GCodePlanner gcodeLayer = new GCodePlanner(gcode, config.travelSpeed, config.minimumTravelToCauseRetraction_um);
                    gcode.setZ(config.raftBaseThickness_um + config.raftInterfaceThicknes_um + config.raftSurfaceThickness_um * raftSurfaceIndex);
                    gcode.setExtrusion(config.raftSurfaceThickness_um, config.filamentDiameter_um, config.extrusionMultiplier);

                    Polygons raftLines = new Polygons();
                    if (raftSurfaceIndex == config.raftSurfaceLayers)
                    {
                        // make sure the top layer of the raft is 90 degrees offset to the first layer of the part so that it has minimum contact points.
                        Infill.GenerateLinePaths(storage.raftOutline, ref raftLines, config.raftSurfaceLineSpacing_um, config.infillExtendIntoPerimeter_um, config.infillStartingAngle + 90);
                    }
                    else
                    {
                        Infill.GenerateLinePaths(storage.raftOutline, ref raftLines, config.raftSurfaceLineSpacing_um, config.infillExtendIntoPerimeter_um, 90 * raftSurfaceIndex);
                    }
                    gcodeLayer.writePolygonsByOptimizer(raftLines, raftSurfaceConfig);

                    gcodeLayer.writeGCode(false, config.raftInterfaceThicknes_um);
                }
            }
        }