public static void generateTopAndBottomLayers(int layerIndex, SliceVolumeStorage storage, int extrusionWidth, int downSkinCount, int upSkinCount) { SliceLayer layer = storage.layers[layerIndex]; for (int partNr = 0; partNr < layer.parts.Count; partNr++) { SliceLayerPart part = layer.parts[partNr]; Polygons upskin = part.insets[part.insets.Count - 1].Offset(-extrusionWidth / 2); Polygons downskin = upskin; if (part.insets.Count > 1) { // Add thin wall filling by taking the area between the insets. Polygons thinWalls = part.insets[0].Offset(-extrusionWidth / 2).CreateDifference(part.insets[1].Offset(extrusionWidth / 2)); upskin.AddAll(thinWalls); downskin.AddAll(thinWalls); } if (layerIndex - downSkinCount >= 0) { SliceLayer layer2 = storage.layers[layerIndex - downSkinCount]; for (int partIndex = 0; partIndex < layer2.parts.Count; partIndex++) { if (part.boundaryBox.hit(layer2.parts[partIndex].boundaryBox)) { downskin = downskin.CreateDifference(layer2.parts[partIndex].insets[layer2.parts[partIndex].insets.Count - 1]); } } } if (layerIndex + upSkinCount < storage.layers.Count) { SliceLayer layer2 = storage.layers[layerIndex + upSkinCount]; for (int partIndex = 0; partIndex < layer2.parts.Count; partIndex++) { if (part.boundaryBox.hit(layer2.parts[partIndex].boundaryBox)) { upskin = upskin.CreateDifference(layer2.parts[partIndex].insets[layer2.parts[partIndex].insets.Count - 1]); } } } part.skinOutline = upskin.CreateUnion(downskin); double minAreaSize = (2 * Math.PI * (extrusionWidth / 1000.0) * (extrusionWidth / 1000.0)) * 0.3; for (int outlineIndex = 0; outlineIndex < part.skinOutline.Count; outlineIndex++) { double area = Math.Abs(part.skinOutline[outlineIndex].Area()) / 1000.0 / 1000.0; if (area < minAreaSize) // Only create an up/down skin if the area is large enough. So you do not create tiny blobs of "trying to fill" { part.skinOutline.RemoveAt(outlineIndex); outlineIndex -= 1; } } } }
public void GenerateTopAndBottoms(int layerIndex, int extrusionWidth_um, int outerPerimeterWidth_um, int downLayerCount, int upLayerCount) { ExtruderLayers extruder = this; SliceLayer layer = extruder.Layers[layerIndex]; for (int islandIndex = 0; islandIndex < layer.Islands.Count; islandIndex++) { LayerIsland island = layer.Islands[islandIndex]; // this is the entire extrusion width to make sure we are outside of the extrusion line Polygons lastInset = island.InsetToolPaths[island.InsetToolPaths.Count - 1]; Polygons insetWithOffset = lastInset.Offset(-extrusionWidth_um); Polygons infillOutlines = new Polygons(insetWithOffset); // calculate the bottom outlines if (downLayerCount > 0) { Polygons bottomOutlines = new Polygons(insetWithOffset); if (layerIndex - 1 >= 0) { bottomOutlines = RemoveIslandsFromPolygons(extruder.Layers[layerIndex - 1].Islands, island.BoundingBox, bottomOutlines); bottomOutlines.RemoveSmallAreas(extrusionWidth_um); } infillOutlines = infillOutlines.CreateDifference(bottomOutlines); infillOutlines = Clipper.CleanPolygons(infillOutlines, cleanDistance_um); island.SolidBottomToolPaths = bottomOutlines; } // calculate the top outlines if (upLayerCount > 0) { Polygons topOutlines = new Polygons(insetWithOffset); topOutlines = topOutlines.CreateDifference(island.SolidBottomToolPaths); topOutlines = Clipper.CleanPolygons(topOutlines, cleanDistance_um); for (int insetIndex = 0; insetIndex < island.InsetToolPaths.Count - 1; insetIndex++) { // Add thin wall filling by taking the area between the insets. Polygons largerInset = island.InsetToolPaths[insetIndex].Offset(-extrusionWidth_um / 2); Polygons smallerInset = island.InsetToolPaths[insetIndex + 1].Offset(extrusionWidth_um / 2); Polygons thinWalls = largerInset.CreateDifference(smallerInset).Offset(-extrusionWidth_um / 4); if (thinWalls.Count > 0) { topOutlines.AddAll(thinWalls); } } if (layerIndex + 1 < extruder.Layers.Count) { // Remove the top layer that is above this one to get only the data that is a top layer on this layer. topOutlines = RemoveIslandsFromPolygons(extruder.Layers[layerIndex + 1].Islands, island.BoundingBox, topOutlines); } topOutlines.RemoveSmallAreas(extrusionWidth_um); infillOutlines = infillOutlines.CreateDifference(topOutlines); infillOutlines = Clipper.CleanPolygons(infillOutlines, cleanDistance_um); island.SolidTopToolPaths = topOutlines; } // calculate the solid infill outlines if (upLayerCount > 1 || downLayerCount > 1) { Polygons solidInfillOutlines = new Polygons(insetWithOffset); solidInfillOutlines = solidInfillOutlines.CreateDifference(island.SolidBottomToolPaths); solidInfillOutlines = Clipper.CleanPolygons(solidInfillOutlines, cleanDistance_um); solidInfillOutlines = solidInfillOutlines.CreateDifference(island.SolidTopToolPaths); solidInfillOutlines = Clipper.CleanPolygons(solidInfillOutlines, cleanDistance_um); int upEnd = layerIndex + upLayerCount + 1; if (upEnd <= extruder.Layers.Count && layerIndex - downLayerCount >= 0) { Polygons totalPartsToRemove = new Polygons(insetWithOffset); int upStart = layerIndex + 2; for (int layerToTest = upStart; layerToTest < upEnd; layerToTest++) { totalPartsToRemove = AddIslandsToPolygons(extruder.Layers[layerToTest].Islands, island.BoundingBox, totalPartsToRemove); totalPartsToRemove = Clipper.CleanPolygons(totalPartsToRemove, cleanDistance_um); } int downStart = layerIndex - 1; int downEnd = layerIndex - downLayerCount; for (int layerToTest = downStart; layerToTest >= downEnd; layerToTest--) { totalPartsToRemove = AddIslandsToPolygons(extruder.Layers[layerToTest].Islands, island.BoundingBox, totalPartsToRemove); totalPartsToRemove = Clipper.CleanPolygons(totalPartsToRemove, cleanDistance_um); } solidInfillOutlines = solidInfillOutlines.CreateDifference(totalPartsToRemove); solidInfillOutlines.RemoveSmallAreas(extrusionWidth_um); solidInfillOutlines = Clipper.CleanPolygons(solidInfillOutlines, cleanDistance_um); } island.SolidInfillToolPaths = solidInfillOutlines; infillOutlines = infillOutlines.CreateDifference(solidInfillOutlines); } infillOutlines.RemoveSmallAreas(extrusionWidth_um); infillOutlines = Clipper.CleanPolygons(infillOutlines, cleanDistance_um); island.InfillToolPaths = infillOutlines; } }
private static Polygons GetSkirtBounds(ConfigSettings config, LayerDataStorage storage, bool externalOnly, int distance, int extrusionWidth_um, int brimCount) { bool hasWipeTower = storage.wipeTower.PolygonLength() > 0; Polygons skirtPolygons = new Polygons(); if (config.EnableRaft) { skirtPolygons = skirtPolygons.CreateUnion(storage.raftOutline); } else { Polygons allOutlines = hasWipeTower ? new Polygons(storage.wipeTower.Offset(-extrusionWidth_um / 2)) : new Polygons(); if (storage.wipeShield.Count > 0 && storage.wipeShield[0].Count > 0) { allOutlines = allOutlines.CreateUnion(storage.wipeShield[0].Offset(-extrusionWidth_um / 2)); } // Loop over every extruder for (int extrudeIndex = 0; extrudeIndex < storage.Extruders.Count; extrudeIndex++) { // Only process the first extruder on spiral vase or // skip extruders that have empty layers if (config.ContinuousSpiralOuterPerimeter) { SliceLayer layer0 = storage.Extruders[extrudeIndex].Layers[0]; allOutlines.AddAll(layer0.Islands[0]?.IslandOutline); } else { // Add the layers outline to allOutlines SliceLayer layer = storage.Extruders[extrudeIndex].Layers[0]; foreach (var island in layer.Islands) { if (island.IslandOutline?.Count > 0) { allOutlines.Add(island.IslandOutline[0]); } } } } if (brimCount > 0) { Polygons brimIslandOutlines = new Polygons(); // Grow each island by the current brim distance // Union the island brims brimIslandOutlines = brimIslandOutlines.CreateUnion(allOutlines); if (storage.support != null) { brimIslandOutlines = brimIslandOutlines.CreateUnion(storage.support.GetBedOutlines()); } brimIslandOutlines = brimIslandOutlines.Offset(extrusionWidth_um * (brimCount - 1)); // Loop over the requested brimCount creating and unioning a new perimeter for each island List <Polygons> brimIslands = brimIslandOutlines.ProcessIntoSeparateIslands(); foreach (var brimIsland in brimIslands) { Polygons brimLoops = new Polygons(); for (int brimIndex = brimCount - 1; brimIndex >= 0; brimIndex--) { int offsetDistance = extrusionWidth_um * brimIndex; // Extend the polygons to account for the brim (ensures convex hull takes this data into account) brimLoops.AddAll(brimIsland.Offset(-offsetDistance + extrusionWidth_um / 2)); } storage.Brims.Add(brimLoops); } // and extend the bonuds of the skirt polygons skirtPolygons = skirtPolygons.CreateUnion(brimIslandOutlines); } skirtPolygons = skirtPolygons.CreateUnion(allOutlines); if (storage.support != null) { skirtPolygons = skirtPolygons.CreateUnion(storage.support.GetBedOutlines()); } } return(skirtPolygons); }
private static Polygons GetSkirtBounds(ConfigSettings config, LayerDataStorage storage, bool externalOnly, int distance, int extrusionWidth_um, int brimCount) { bool hasWipeTower = storage.wipeTower.PolygonLength() > 0; Polygons skirtPolygons = new Polygons(); if (config.EnableRaft) { skirtPolygons = skirtPolygons.CreateUnion(storage.raftOutline); } else { Polygons allOutlines = hasWipeTower ? new Polygons(storage.wipeTower) : new Polygons(); // Loop over every extruder for (int extrudeIndex = 0; extrudeIndex < storage.Extruders.Count; extrudeIndex++) { // Only process the first extruder on spiral vase or // skip extruders that have empty layers if (config.ContinuousSpiralOuterPerimeter) { SliceLayer layer0 = storage.Extruders[extrudeIndex].Layers[0]; allOutlines.AddAll(layer0.Islands[0]?.IslandOutline); } else { // Add the layers outline to allOutlines SliceLayer layer = storage.Extruders[extrudeIndex].Layers[0]; foreach (var island in layer.Islands) { if (island.IslandOutline?.Count > 0) { allOutlines.Add(island.IslandOutline[0]); } } } } if (brimCount > 0) { Polygons unionedIslandOutlines = new Polygons(); // Grow each island by the current brim distance // Union the island brims unionedIslandOutlines = unionedIslandOutlines.CreateUnion(allOutlines); if (storage.support != null) { unionedIslandOutlines = unionedIslandOutlines.CreateUnion(storage.support.GetBedOutlines()); } Polygons brimLoops = new Polygons(); // Loop over the requested brimCount creating and unioning a new perimeter for each island for (int brimIndex = 0; brimIndex < brimCount; brimIndex++) { int offsetDistance = extrusionWidth_um * brimIndex + extrusionWidth_um / 2; // Extend the polygons to account for the brim (ensures convex hull takes this data into account) brimLoops.AddAll(unionedIslandOutlines.Offset(offsetDistance)); } // TODO: This is a quick hack, reuse the skirt data to stuff in the brim. Good enough from proof of concept storage.skirt.AddAll(brimLoops); skirtPolygons = skirtPolygons.CreateUnion(brimLoops); } else { skirtPolygons = skirtPolygons.CreateUnion(allOutlines); } if (storage.support != null) { skirtPolygons = skirtPolygons.CreateUnion(storage.support.GetBedOutlines()); } } return(skirtPolygons); }
public static void GenerateTopAndBottom(int layerIndex, SliceVolumeStorage storage, int extrusionWidth, int downLayerCount, int upLayerCount) { SliceLayer layer = storage.layers[layerIndex]; for (int partIndex = 0; partIndex < layer.parts.Count; partIndex++) { SliceLayerPart part = layer.parts[partIndex]; Polygons insetWithOffset = part.Insets[part.Insets.Count - 1].Offset(-extrusionWidth / 2); Polygons infillOutlines = new Polygons(insetWithOffset); // calculate the bottom outlines if (downLayerCount > 0) { Polygons bottomOutlines = new Polygons(insetWithOffset); if (layerIndex - 1 >= 0) { bottomOutlines = RemoveAdditionalOutlinesForPart(storage.layers[layerIndex - 1], part, bottomOutlines); RemoveSmallAreas(extrusionWidth, bottomOutlines); } infillOutlines = infillOutlines.CreateDifference(bottomOutlines); infillOutlines = Clipper.CleanPolygons(infillOutlines, cleanDistance_um); part.SolidBottomOutlines = bottomOutlines; } // calculate the top outlines if (upLayerCount > 0) { Polygons topOutlines = new Polygons(insetWithOffset); topOutlines = topOutlines.CreateDifference(part.SolidBottomOutlines); topOutlines = Clipper.CleanPolygons(topOutlines, cleanDistance_um); if (part.Insets.Count > 1) { // Add thin wall filling by taking the area between the insets. Polygons thinWalls = part.Insets[0].Offset(-extrusionWidth / 2).CreateDifference(part.Insets[1].Offset(extrusionWidth / 2)); topOutlines.AddAll(thinWalls); } if (layerIndex + 1 < storage.layers.Count) { topOutlines = RemoveAdditionalOutlinesForPart(storage.layers[layerIndex + 1], part, topOutlines); RemoveSmallAreas(extrusionWidth, topOutlines); } infillOutlines = infillOutlines.CreateDifference(topOutlines); infillOutlines = Clipper.CleanPolygons(infillOutlines, cleanDistance_um); part.SolidTopOutlines = topOutlines; } // calculate the solid infill outlines if (upLayerCount > 1 || downLayerCount > 1) { Polygons solidInfillOutlines = new Polygons(insetWithOffset); solidInfillOutlines = solidInfillOutlines.CreateDifference(part.SolidBottomOutlines); solidInfillOutlines = Clipper.CleanPolygons(solidInfillOutlines, cleanDistance_um); solidInfillOutlines = solidInfillOutlines.CreateDifference(part.SolidTopOutlines); solidInfillOutlines = Clipper.CleanPolygons(solidInfillOutlines, cleanDistance_um); int upEnd = layerIndex + upLayerCount + 1; if (upEnd <= storage.layers.Count && layerIndex - downLayerCount >= 0) { Polygons totalPartsToRemove = new Polygons(insetWithOffset); int upStart = layerIndex + 2; for (int layerToTest = upStart; layerToTest < upEnd; layerToTest++) { totalPartsToRemove = AddAllOutlines(storage.layers[layerToTest], part, totalPartsToRemove); totalPartsToRemove = Clipper.CleanPolygons(totalPartsToRemove, cleanDistance_um); } int downStart = layerIndex - 1; int downEnd = layerIndex - downLayerCount; for (int layerToTest = downStart; layerToTest >= downEnd; layerToTest--) { totalPartsToRemove = AddAllOutlines(storage.layers[layerToTest], part, totalPartsToRemove); totalPartsToRemove = Clipper.CleanPolygons(totalPartsToRemove, cleanDistance_um); } solidInfillOutlines = solidInfillOutlines.CreateDifference(totalPartsToRemove); RemoveSmallAreas(extrusionWidth, solidInfillOutlines); solidInfillOutlines = Clipper.CleanPolygons(solidInfillOutlines, cleanDistance_um); } part.SolidInfillOutlines = solidInfillOutlines; infillOutlines = infillOutlines.CreateDifference(solidInfillOutlines); } RemoveSmallAreas(extrusionWidth, infillOutlines); infillOutlines = Clipper.CleanPolygons(infillOutlines, cleanDistance_um); part.InfillOutlines = infillOutlines; } }
public void GenerateTopAndBottoms(int layerIndex, int extrusionWidth_um, int outerPerimeterWidth_um, int downLayerCount, int upLayerCount) { ExtruderLayers extruder = this; SliceLayer layer = extruder.Layers[layerIndex]; for (int islandIndex = 0; islandIndex < layer.Islands.Count; islandIndex++) { LayerIsland island = layer.Islands[islandIndex]; // this is the entire extrusion width to make sure we are outside of the extrusion line Polygons lastInset = island.InsetToolPaths[island.InsetToolPaths.Count - 1]; Polygons insetWithOffset = lastInset.Offset(-extrusionWidth_um); Polygons infillOutlines = new Polygons(insetWithOffset); // calculate the bottom outlines if (downLayerCount > 0) { Polygons bottomOutlines = new Polygons(insetWithOffset); if (layerIndex - 1 >= 0) { bottomOutlines = RemoveIslandsFromPolygons(extruder.Layers[layerIndex - 1].Islands, island.BoundingBox, bottomOutlines); bottomOutlines.RemoveSmallAreas(extrusionWidth_um); } infillOutlines = infillOutlines.CreateDifference(bottomOutlines); infillOutlines = Clipper.CleanPolygons(infillOutlines, cleanDistance_um); island.SolidBottomToolPaths = bottomOutlines; } // calculate the top outlines if (upLayerCount > 0) { Polygons topOutlines = new Polygons(insetWithOffset); topOutlines = topOutlines.CreateDifference(island.SolidBottomToolPaths); topOutlines = Clipper.CleanPolygons(topOutlines, cleanDistance_um); for (int insetIndex = 0; insetIndex < island.InsetToolPaths.Count - 1; insetIndex++) { // Add thin wall filling by taking the area between the insets. Polygons largerInset = island.InsetToolPaths[insetIndex].Offset(-extrusionWidth_um / 2); Polygons smallerInset = island.InsetToolPaths[insetIndex + 1].Offset(extrusionWidth_um / 2); Polygons thinWalls = largerInset.CreateDifference(smallerInset).Offset(-extrusionWidth_um/4); if (thinWalls.Count > 0) { topOutlines.AddAll(thinWalls); } } if (layerIndex + 1 < extruder.Layers.Count) { // Remove the top layer that is above this one to get only the data that is a top layer on this layer. topOutlines = RemoveIslandsFromPolygons(extruder.Layers[layerIndex + 1].Islands, island.BoundingBox, topOutlines); } topOutlines.RemoveSmallAreas(extrusionWidth_um); infillOutlines = infillOutlines.CreateDifference(topOutlines); infillOutlines = Clipper.CleanPolygons(infillOutlines, cleanDistance_um); island.SolidTopToolPaths = topOutlines; } // calculate the solid infill outlines if (upLayerCount > 1 || downLayerCount > 1) { Polygons solidInfillOutlines = new Polygons(insetWithOffset); solidInfillOutlines = solidInfillOutlines.CreateDifference(island.SolidBottomToolPaths); solidInfillOutlines = Clipper.CleanPolygons(solidInfillOutlines, cleanDistance_um); solidInfillOutlines = solidInfillOutlines.CreateDifference(island.SolidTopToolPaths); solidInfillOutlines = Clipper.CleanPolygons(solidInfillOutlines, cleanDistance_um); int upEnd = layerIndex + upLayerCount + 1; if (upEnd <= extruder.Layers.Count && layerIndex - downLayerCount >= 0) { Polygons totalPartsToRemove = new Polygons(insetWithOffset); int upStart = layerIndex + 2; for (int layerToTest = upStart; layerToTest < upEnd; layerToTest++) { totalPartsToRemove = AddIslandsToPolygons(extruder.Layers[layerToTest].Islands, island.BoundingBox, totalPartsToRemove); totalPartsToRemove = Clipper.CleanPolygons(totalPartsToRemove, cleanDistance_um); } int downStart = layerIndex - 1; int downEnd = layerIndex - downLayerCount; for (int layerToTest = downStart; layerToTest >= downEnd; layerToTest--) { totalPartsToRemove = AddIslandsToPolygons(extruder.Layers[layerToTest].Islands, island.BoundingBox, totalPartsToRemove); totalPartsToRemove = Clipper.CleanPolygons(totalPartsToRemove, cleanDistance_um); } solidInfillOutlines = solidInfillOutlines.CreateDifference(totalPartsToRemove); solidInfillOutlines.RemoveSmallAreas(extrusionWidth_um); solidInfillOutlines = Clipper.CleanPolygons(solidInfillOutlines, cleanDistance_um); } island.SolidInfillToolPaths = solidInfillOutlines; infillOutlines = infillOutlines.CreateDifference(solidInfillOutlines); } infillOutlines.RemoveSmallAreas(extrusionWidth_um); infillOutlines = Clipper.CleanPolygons(infillOutlines, cleanDistance_um); island.InfillToolPaths = infillOutlines; } }
public static void GenerateTopAndBottom(int layerIndex, SliceVolumeStorage storage, int extrusionWidth, ConfigSettings config) { var downLayerCount = config.numberOfBottomLayers; var upLayerCount = config.numberOfTopLayers; SliceLayer layer = storage.layers[layerIndex]; for (int partIndex = 0; partIndex < layer.parts.Count; partIndex++) { SliceLayerPart part = layer.parts[partIndex]; Polygons insetWithOffset = part.Insets[part.Insets.Count - 1].Offset(-extrusionWidth / 2); Polygons infillOutlines = new Polygons(insetWithOffset); // calculate the bottom outlines if (downLayerCount > 0) { Polygons bottomOutlines = new Polygons(insetWithOffset); if (layerIndex - 1 >= 0) { bottomOutlines = RemoveAdditionalOutlinesForPart(storage.layers[layerIndex - 1], part, bottomOutlines); RemoveSmallAreas(extrusionWidth, bottomOutlines); } infillOutlines = infillOutlines.CreateDifference(bottomOutlines); infillOutlines = Clipper.CleanPolygons(infillOutlines, cleanDistance_um); part.SolidBottomOutlines = bottomOutlines; } // calculate the top outlines if (upLayerCount > 0) { Polygons topOutlines = new Polygons(insetWithOffset); topOutlines = topOutlines.CreateDifference(part.SolidBottomOutlines); topOutlines = Clipper.CleanPolygons(topOutlines, cleanDistance_um); if (part.Insets.Count > 1) { // Add thin wall filling by taking the area between the insets. Polygons thinWalls = part.Insets[0].Offset(-extrusionWidth / 2).CreateDifference(part.Insets[1].Offset(extrusionWidth / 2)); topOutlines.AddAll(thinWalls); } if (layerIndex + 1 < storage.layers.Count) { topOutlines = RemoveAdditionalOutlinesForPart(storage.layers[layerIndex + 1], part, topOutlines); RemoveSmallAreas(extrusionWidth, topOutlines); } infillOutlines = infillOutlines.CreateDifference(topOutlines); infillOutlines = Clipper.CleanPolygons(infillOutlines, cleanDistance_um); part.SolidTopOutlines = topOutlines; } // calculate the solid infill outlines if (upLayerCount > 1 || downLayerCount > 1) { var solidInfillOutlines = new Polygons(insetWithOffset); solidInfillOutlines = solidInfillOutlines.CreateDifference(part.SolidBottomOutlines); solidInfillOutlines = Clipper.CleanPolygons(solidInfillOutlines, cleanDistance_um); solidInfillOutlines = solidInfillOutlines.CreateDifference(part.SolidTopOutlines); solidInfillOutlines = Clipper.CleanPolygons(solidInfillOutlines, cleanDistance_um); var upStart = layerIndex + 2; var upEnd = layerIndex + upLayerCount + 1; var downStart = layerIndex - 1; var downEnd = layerIndex - downLayerCount; if (upEnd <= storage.layers.Count && downEnd >= 0) { var makeInfillSolid = false; var totalPartsToRemove = new Polygons(insetWithOffset); for (var layerToTest = upStart; layerToTest < upEnd; layerToTest++) { totalPartsToRemove = AddAllOutlines(storage.layers[layerToTest], part, totalPartsToRemove, ref makeInfillSolid, config); totalPartsToRemove = Clipper.CleanPolygons(totalPartsToRemove, cleanDistance_um); if (makeInfillSolid) { break; } } for (var layerToTest = downStart; layerToTest >= downEnd; layerToTest--) { totalPartsToRemove = AddAllOutlines(storage.layers[layerToTest], part, totalPartsToRemove, ref makeInfillSolid, config); totalPartsToRemove = Clipper.CleanPolygons(totalPartsToRemove, cleanDistance_um); if (makeInfillSolid) { break; } } if (!makeInfillSolid) { solidInfillOutlines = solidInfillOutlines.CreateDifference(totalPartsToRemove); RemoveSmallAreas(extrusionWidth, solidInfillOutlines); } solidInfillOutlines = Clipper.CleanPolygons(solidInfillOutlines, cleanDistance_um); } part.SolidInfillOutlines = solidInfillOutlines; infillOutlines = infillOutlines.CreateDifference(solidInfillOutlines); Polygons totalInfillOutlines = null; double totalInfillArea = 0.0; if (config.infillSolidProportion > 0) { totalInfillOutlines = infillOutlines.CreateUnion(solidInfillOutlines); totalInfillArea = totalInfillOutlines.TotalArea(); } if (config.infillSolidProportion > 0) { var solidInfillArea = solidInfillOutlines.TotalArea(); if (solidInfillArea > totalInfillArea * config.infillSolidProportion) { solidInfillOutlines = solidInfillOutlines.CreateUnion(infillOutlines); infillOutlines = new Polygons(); part.SolidInfillOutlines = solidInfillOutlines; } var solidTopOutlinesArea = part.SolidTopOutlines.TotalArea(); if (totalInfillArea < solidTopOutlinesArea * config.infillSolidProportion / 2) { var totalSolidTop = totalInfillOutlines.CreateUnion(part.SolidTopOutlines); part.SolidTopOutlines = totalSolidTop; part.SolidInfillOutlines = new Polygons(); infillOutlines = part.InfillOutlines = new Polygons(); } var solidBottomOutlinesArea = part.SolidBottomOutlines.TotalArea(); if (totalInfillArea < solidBottomOutlinesArea * config.infillSolidProportion / 2) { var totalSolidBottom = totalInfillOutlines.CreateUnion(part.SolidBottomOutlines); part.SolidBottomOutlines = totalSolidBottom; part.SolidInfillOutlines = new Polygons(); infillOutlines = part.InfillOutlines = new Polygons(); } } if (config.minInfillArea_mm2 > 0) { var infillArea = infillOutlines.TotalArea() / 1e6; // convert from um2 to mm2 if (infillArea < config.minInfillArea_mm2) { solidInfillOutlines = solidInfillOutlines.CreateUnion(infillOutlines); infillOutlines = new Polygons(); part.SolidInfillOutlines = solidInfillOutlines; } } } RemoveSmallAreas(extrusionWidth, infillOutlines); infillOutlines = Clipper.CleanPolygons(infillOutlines, cleanDistance_um); part.InfillOutlines = infillOutlines; } }