示例#1
0
 public static void createLayerParts(SliceVolumeStorage storage, Slicer slicer, ConfigConstants.REPAIR_OVERLAPS unionAllType)
 {
     for (int layerIndex = 0; layerIndex < slicer.layers.Count; layerIndex++)
     {
         storage.layers.Add(new SliceLayer());
         storage.layers[layerIndex].printZ = slicer.layers[layerIndex].z;
         LayerPart.createLayerWithParts(storage.layers[layerIndex], slicer.layers[layerIndex], unionAllType);
     }
 }
示例#2
0
        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;
                    }
                }
            }
        }
示例#3
0
 public static void CreateLayerParts(SliceVolumeStorage storage, Slicer slicer, ConfigConstants.REPAIR_OVERLAPS unionAllType)
 {
     for (int layerIndex = 0; layerIndex < slicer.layers.Count; layerIndex++)
     {
         storage.layers.Add(new SliceLayer());
         storage.layers[layerIndex].printZ = slicer.layers[layerIndex].Z;
         LayerPart.CreateLayerWithParts(storage.layers[layerIndex], slicer.layers[layerIndex], unionAllType);
     }
 }
示例#4
0
        public static void generateSparse(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 sparse   = part.insets[part.insets.Count - 1].Offset(-extrusionWidth / 2);
                Polygons downskin = sparse;
                Polygons upskin   = sparse;

                if ((int)(layerIndex - downSkinCount) >= 0)
                {
                    SliceLayer layer2 = storage.layers[layerIndex - downSkinCount];
                    for (int partNr2 = 0; partNr2 < layer2.parts.Count; partNr2++)
                    {
                        if (part.boundaryBox.hit(layer2.parts[partNr2].boundaryBox))
                        {
                            if (layer2.parts[partNr2].insets.Count > 1)
                            {
                                downskin = downskin.CreateDifference(layer2.parts[partNr2].insets[layer2.parts[partNr2].insets.Count - 2]);
                            }
                            else
                            {
                                downskin = downskin.CreateDifference(layer2.parts[partNr2].insets[layer2.parts[partNr2].insets.Count - 1]);
                            }
                        }
                    }
                }
                if ((int)(layerIndex + upSkinCount) < (int)storage.layers.Count)
                {
                    SliceLayer layer2 = storage.layers[layerIndex + upSkinCount];
                    for (int partNr2 = 0; partNr2 < layer2.parts.Count; partNr2++)
                    {
                        if (part.boundaryBox.hit(layer2.parts[partNr2].boundaryBox))
                        {
                            if (layer2.parts[partNr2].insets.Count > 1)
                            {
                                upskin = upskin.CreateDifference(layer2.parts[partNr2].insets[layer2.parts[partNr2].insets.Count - 2]);
                            }
                            else
                            {
                                upskin = upskin.CreateDifference(layer2.parts[partNr2].insets[layer2.parts[partNr2].insets.Count - 1]);
                            }
                        }
                    }
                }

                Polygons result = upskin.CreateUnion(downskin);

                double minAreaSize = 3.0;//(2 * M_PI * ((double)(config.extrusionWidth) / 1000.0) * ((double)(config.extrusionWidth) / 1000.0)) * 3;
                for (int i = 0; i < result.Count; i++)
                {
                    double area = Math.Abs(result[i].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" */
                    {
                        result.RemoveAt(i);
                        i -= 1;
                    }
                }

                part.sparseOutline = sparse.CreateDifference(result);
            }
        }
示例#5
0
        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;
            }
        }
示例#6
0
        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;
            }
        }
示例#7
0
        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;
            }
        }
示例#8
0
        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;
            }
        }