Exemple #1
0
        private static List <Polygons> CreateInterfaceLayers(List <Polygons> inputPolys, int numInterfaceLayers)
        {
            int numLayers = inputPolys.Count;

            List <Polygons> allInterfaceLayers = CreateEmptyPolygons(numLayers);

            if (numInterfaceLayers > 0)
            {
                for (int layerIndex = 0; layerIndex < numLayers; layerIndex++)
                {
                    Polygons requiredInterfacePolys = inputPolys[layerIndex].DeepCopy();

                    if (layerIndex < numLayers - 1)
                    {
                        Polygons intersectionsAbove = inputPolys[layerIndex + 1].DeepCopy();

                        for (int aboveIndex = layerIndex + 2; aboveIndex < Math.Min(layerIndex + numInterfaceLayers + 1, numLayers); aboveIndex++)
                        {
                            intersectionsAbove = intersectionsAbove.CreateIntersection(inputPolys[aboveIndex]);
                            intersectionsAbove = Clipper.CleanPolygons(intersectionsAbove, cleanDistance_um);
                        }

                        requiredInterfacePolys = requiredInterfacePolys.CreateDifference(intersectionsAbove);
                        requiredInterfacePolys = Clipper.CleanPolygons(requiredInterfacePolys, cleanDistance_um);
                    }

                    allInterfaceLayers[layerIndex] = requiredInterfacePolys;
                }
            }

            return(allInterfaceLayers);
        }
        public void GenerateMarchingSquaresAndLines(Action <double, string> progressReporter, ImageBuffer image, IThresholdFunction thresholdFunction)
        {
            if (image != null)
            {
                // Regenerate outline
                var marchingSquaresData = new MarchingSquaresByte(
                    image,
                    thresholdFunction.ZeroColor,
                    thresholdFunction.Threshold,
                    0);

                progressReporter?.Invoke(0, "Creating Outline");

                marchingSquaresData.CreateLineSegments();
                progressReporter?.Invoke(.1, null);

                int pixelsToIntPointsScale = 1000;
                var lineLoops = marchingSquaresData.CreateLineLoops(pixelsToIntPointsScale);

                progressReporter?.Invoke(.15, null);

                var min = new IntPoint(-10, -10);
                var max = new IntPoint(10 + image.Width * pixelsToIntPointsScale, 10 + image.Height * pixelsToIntPointsScale);

                var boundingPoly = new Polygon();
                boundingPoly.Add(min);
                boundingPoly.Add(new IntPoint(min.X, max.Y));
                boundingPoly.Add(max);
                boundingPoly.Add(new IntPoint(max.X, min.Y));

                // now clip the polygons to get the inside and outside polys
                var clipper = new Clipper();
                clipper.AddPaths(lineLoops, PolyType.ptSubject, true);
                clipper.AddPath(boundingPoly, PolyType.ptClip, true);

                var polygonShape = new Polygons();
                progressReporter?.Invoke(.3, null);

                clipper.Execute(ClipType.ctIntersection, polygonShape);

                progressReporter?.Invoke(.55, null);

                polygonShape = Clipper.CleanPolygons(polygonShape, 100);

                progressReporter?.Invoke(.75, null);

                VertexStorage rawVectorShape = polygonShape.PolygonToPathStorage();

                var aabb   = this.VisibleMeshes().FirstOrDefault().GetAxisAlignedBoundingBox();
                var xScale = aabb.XSize / image.Width;

                var affine = Affine.NewScaling(1.0 / pixelsToIntPointsScale * xScale);
                affine *= Affine.NewTranslation(-aabb.XSize / 2, -aabb.YSize / 2);

                rawVectorShape.transform(affine);
                this.VertexSource = rawVectorShape;

                progressReporter?.Invoke(1, null);
            }
        }
        /// <summary>
        /// Clean up a proposed corridor shape (primarily removing holes, which are invalid in a floorplan)
        /// </summary>
        /// <param name="clipper"></param>
        /// <param name="outline"></param>
        /// <param name="corridor"></param>
        /// <param name="width"></param>
        /// <returns></returns>
        public static List <List <IntPoint> > CleanCorridorPolygon(Clipper clipper, List <IntPoint> outline, IEnumerable <Vector2> corridor, float width)
        {
            //Clean up after the previous run, just in case
            clipper.Clear();

            //Clip this spanning tree to the footprint of the floorplan (to create a polytree)
            var result = new List <List <IntPoint> >();

            clipper.AddPath(outline, PolyType.ptClip, true);
            clipper.AddPath(corridor.Select(ToPoint).ToList(), PolyType.ptSubject, true);
            clipper.Execute(ClipType.ctIntersection, result);

            //Clean up after self, to be polite
            clipper.Clear();

            //Keep simplifying, and removing holes until nothing happens
            do
            {
                //merge together vertices which are very close
                result = Clipper.CleanPolygons(result, width / 8);

                //Remove holes from the result
                var holes = result.RemoveAll(r => !Clipper.Orientation(r));

                //Once we have one single polygon, or removing holes did nothing we've finished!
                if (result.Count == 1 || holes == 0)
                {
                    return(result);
                }
            } while (result.Count > 0);

            //This shouldn't ever happen unless we simplify away to nothing
            return(result);
        }
Exemple #4
0
        private Polygons FixWinding(Polygons polygonsToPathAround)
        {
            polygonsToPathAround = Clipper.CleanPolygons(polygonsToPathAround);
            Polygon boundsPolygon = new Polygon();
            IntRect bounds        = Clipper.GetBounds(polygonsToPathAround);

            bounds.minX -= 10;
            bounds.maxY += 10;
            bounds.maxX += 10;
            bounds.minY -= 10;

            boundsPolygon.Add(new IntPoint(bounds.minX, bounds.minY));
            boundsPolygon.Add(new IntPoint(bounds.maxX, bounds.minY));
            boundsPolygon.Add(new IntPoint(bounds.maxX, bounds.maxY));
            boundsPolygon.Add(new IntPoint(bounds.minX, bounds.maxY));

            Clipper clipper = new Clipper();

            clipper.AddPaths(polygonsToPathAround, PolyType.ptSubject, true);
            clipper.AddPath(boundsPolygon, PolyType.ptClip, true);

            PolyTree intersectionResult = new PolyTree();

            clipper.Execute(ClipType.ctIntersection, intersectionResult);

            Polygons outputPolygons = Clipper.ClosedPathsFromPolyTree(intersectionResult);

            return(outputPolygons);
        }
Exemple #5
0
        private static List <Polygons> AccumulateDownPolygons(ConfigSettings config, List <Polygons> inputPolys, List <Polygons> allPartOutlines)
        {
            int numLayers = inputPolys.Count;

            long nozzleSize = config.ExtrusionWidth_um;

            List <Polygons> allDownOutlines = CreateEmptyPolygons(numLayers);

            for (int layerIndex = numLayers - 2; layerIndex >= 0; layerIndex--)
            {
                Polygons aboveRequiredSupport = inputPolys[layerIndex + 1];

                // get all the polygons above us
                Polygons accumulatedAbove = allDownOutlines[layerIndex + 1].CreateUnion(aboveRequiredSupport);

                // add in the support on this level
                Polygons curRequiredSupport = inputPolys[layerIndex];

                Polygons totalSupportThisLayer = accumulatedAbove.CreateUnion(curRequiredSupport);

                // remove the solid polygons on this level
                Polygons remainingAbove = totalSupportThisLayer.CreateDifference(allPartOutlines[layerIndex]);

                allDownOutlines[layerIndex] = Clipper.CleanPolygons(remainingAbove, cleanDistance_um);
            }

            return(allDownOutlines);
        }
Exemple #6
0
        public static void generateInsets(SliceLayerPart part, int offset, int insetCount)
        {
            part.combBoundery = part.outline.Offset(-offset);
            if (insetCount == 0)
            {
                // if we have no insets defined still create one
                part.insets.Add(part.outline);
            }
            else // generate the insets
            {
                for (int i = 0; i < insetCount; i++)
                {
                    part.insets.Add(new Polygons());
                    part.insets[i] = part.outline.Offset(-offset * i - offset / 2);

                    if (i == 0)
                    {
                        // Add thin wall filling by taking the area between the insets.
                        //Polygons thinWalls = part.insets[0].Offset(-offset / 4).CreateDifference(part.insets[0].Offset);
                        //upskin.AddAll(thinWalls);
                        //downskin.AddAll(thinWalls);
                    }

                    long minimumDistanceToCreateNewPosition = 10;
                    part.insets[i] = Clipper.CleanPolygons(part.insets[i], minimumDistanceToCreateNewPosition);

                    if (part.insets[i].Count < 1)
                    {
                        part.insets.RemoveAt(part.insets.Count - 1);
                        break;
                    }
                }
            }
        }
Exemple #7
0
        private static List <Polygons> RemoveSelfSupportedSections(List <Polygons> inputPolys, long supportWidth_um)
        {
            int numLayers = inputPolys.Count;

            List <Polygons> allRequiredSupportOutlines = CreateEmptyPolygons(numLayers);

            // calculate all the non-supported areas
            for (int layerIndex = numLayers - 1; layerIndex > 0; layerIndex--)
            {
                if (inputPolys[layerIndex - 1].Count > 0)
                {
                    if (inputPolys[layerIndex].Count > 0)
                    {
                        Polygons expandedLayerBellow = inputPolys[layerIndex - 1].Offset(supportWidth_um);

                        allRequiredSupportOutlines[layerIndex] = inputPolys[layerIndex].CreateDifference(expandedLayerBellow);
                        allRequiredSupportOutlines[layerIndex] = Clipper.CleanPolygons(allRequiredSupportOutlines[layerIndex], cleanDistance_um);
                    }
                }
                else
                {
                    allRequiredSupportOutlines[layerIndex] = inputPolys[layerIndex].DeepCopy();
                }
            }

            return(allRequiredSupportOutlines);
        }
Exemple #8
0
        private void InsetPath()
        {
            var path = this.Children.OfType <IPathObject>().FirstOrDefault();

            if (path == null)
            {
                // clear our existing data
                VertexSource = new VertexStorage();
                return;
            }

            var aPolys = path.VertexSource.CreatePolygons();

            var offseter = new ClipperOffset();

            offseter.AddPaths(aPolys, InflatePathObject3D.GetJoinType(OuterStyle), EndType.etClosedPolygon);
            var outerLoops = new List <List <IntPoint> >();

            offseter.Execute(ref outerLoops, OutlineWidth * Ratio * 1000);
            Clipper.CleanPolygons(outerLoops);

            offseter.AddPaths(aPolys, InflatePathObject3D.GetJoinType(InnerStyle), EndType.etClosedPolygon);
            var innerLoops = new List <List <IntPoint> >();

            offseter.Execute(ref innerLoops, -OutlineWidth * (1 - Ratio) * 1000);
            Clipper.CleanPolygons(innerLoops);

            var allLoops = outerLoops;

            allLoops.AddRange(innerLoops);

            VertexSource = allLoops.CreateVertexStorage();

            (VertexSource as VertexStorage).Add(0, 0, ShapePath.FlagsAndCommand.Stop);
        }
Exemple #9
0
        public static Polygons GetCorrectedWinding(this Polygons polygonsToFix)
        {
            polygonsToFix = Clipper.CleanPolygons(polygonsToFix);
            var     boundsPolygon = new Polygon();
            IntRect bounds        = Clipper.GetBounds(polygonsToFix);

            bounds.minX -= 10;
            bounds.minY -= 10;
            bounds.maxY += 10;
            bounds.maxX += 10;

            boundsPolygon.Add(new IntPoint(bounds.minX, bounds.minY));
            boundsPolygon.Add(new IntPoint(bounds.maxX, bounds.minY));
            boundsPolygon.Add(new IntPoint(bounds.maxX, bounds.maxY));
            boundsPolygon.Add(new IntPoint(bounds.minX, bounds.maxY));

            var clipper = new Clipper();

            clipper.AddPaths(polygonsToFix, PolyType.ptSubject, true);
            clipper.AddPath(boundsPolygon, PolyType.ptClip, true);

            var intersectionResult = new PolyTree();

            clipper.Execute(ClipType.ctIntersection, intersectionResult);

            Polygons outputPolygons = Clipper.ClosedPathsFromPolyTree(intersectionResult);

            return(outputPolygons);
        }
Exemple #10
0
        public static void GenerateInsets(SliceLayerPart part, int offset, int insetCount)
        {
            part.AvoidCrossingBoundery = part.TotalOutline.Offset(-offset);
            if (insetCount == 0)
            {
                // if we have no insets defined still create one
                part.Insets.Add(part.TotalOutline);
            }
            else             // generate the insets
            {
                for (int i = 0; i < insetCount; i++)
                {
                    part.Insets.Add(new Polygons());
                    part.Insets[i] = part.TotalOutline.Offset(-offset * i - offset / 2);

                    double minimumDistanceToCreateNewPosition = 10;
                    part.Insets[i] = Clipper.CleanPolygons(part.Insets[i], minimumDistanceToCreateNewPosition);

                    if (part.Insets[i].Count < 1)
                    {
                        part.Insets.RemoveAt(part.Insets.Count - 1);
                        break;
                    }
                }
            }
        }
Exemple #11
0
        private Polygons FixWinding(Polygons polygonsToPathAround)
        {
            polygonsToPathAround = Clipper.CleanPolygons(polygonsToPathAround);
            Polygon boundsPolygon = new Polygon();
            IntRect bounds        = Clipper.GetBounds(polygonsToPathAround);

            bounds.left   -= 10;
            bounds.bottom += 10;
            bounds.right  += 10;
            bounds.top    -= 10;

            boundsPolygon.Add(new IntPoint(bounds.left, bounds.top));
            boundsPolygon.Add(new IntPoint(bounds.right, bounds.top));
            boundsPolygon.Add(new IntPoint(bounds.right, bounds.bottom));
            boundsPolygon.Add(new IntPoint(bounds.left, bounds.bottom));

            Clipper clipper = new Clipper();

            clipper.AddPaths(polygonsToPathAround, PolyType.ptSubject, true);
            clipper.AddPath(boundsPolygon, PolyType.ptClip, true);

            PolyTree intersectionResult = new PolyTree();

            clipper.Execute(ClipType.ctIntersection, intersectionResult);

            Polygons outputPolygons = Clipper.ClosedPathsFromPolyTree(intersectionResult);

            Clipper.ReversePaths(outputPolygons);

            return(outputPolygons);
        }
        public static Polygons GetCorrectedWinding(this Polygons polygonsToFix)
        {
            polygonsToFix = Clipper.CleanPolygons(polygonsToFix);
            Polygon boundsPolygon = new Polygon();
            IntRect bounds        = Clipper.GetBounds(polygonsToFix);

            bounds.left   -= 10;
            bounds.bottom += 10;
            bounds.right  += 10;
            bounds.top    -= 10;

            boundsPolygon.Add(new IntPoint(bounds.left, bounds.top));
            boundsPolygon.Add(new IntPoint(bounds.right, bounds.top));
            boundsPolygon.Add(new IntPoint(bounds.right, bounds.bottom));
            boundsPolygon.Add(new IntPoint(bounds.left, bounds.bottom));

            Clipper clipper = new Clipper();

            clipper.AddPaths(polygonsToFix, PolyType.ptSubject, true);
            clipper.AddPath(boundsPolygon, PolyType.ptClip, true);

            PolyTree intersectionResult = new PolyTree();

            clipper.Execute(ClipType.ctIntersection, intersectionResult);

            Polygons outputPolygons = Clipper.ClosedPathsFromPolyTree(intersectionResult);

            return(outputPolygons);
        }
Exemple #13
0
        public void QueueAirGappedBottomLayer(ConfigSettings config, GCodePlanner gcodeLayer, int layerIndex, GCodePathConfig supportNormalConfig)
        {
            // normal support
            Polygons currentAirGappedBottoms = airGappedBottomOutlines[layerIndex];

            currentAirGappedBottoms = currentAirGappedBottoms.Offset(-config.ExtrusionWidth_um / 2);
            List <Polygons> supportIslands = currentAirGappedBottoms.ProcessIntoSeparatIslands();

            foreach (Polygons islandOutline in supportIslands)
            {
                Polygons islandInfillLines = new Polygons();
                // render a grid of support
                if (config.GenerateSupportPerimeter)
                {
                    Polygons outlines = Clipper.CleanPolygons(islandOutline, config.ExtrusionWidth_um / 4);
                    gcodeLayer.QueuePolygonsByOptimizer(outlines, supportNormalConfig);
                }
                Polygons infillOutline = islandOutline.Offset(-config.ExtrusionWidth_um / 2);
                switch (config.SupportType)
                {
                case ConfigConstants.SUPPORT_TYPE.GRID:
                    Infill.GenerateGridInfill(config, infillOutline, islandInfillLines, config.SupportInfillStartingAngle, config.SupportLineSpacing_um);
                    break;

                case ConfigConstants.SUPPORT_TYPE.LINES:
                    Infill.GenerateLineInfill(config, infillOutline, islandInfillLines, config.SupportInfillStartingAngle, config.SupportLineSpacing_um);
                    break;
                }
                gcodeLayer.QueuePolygonsByOptimizer(islandInfillLines, supportNormalConfig);
            }
        }
Exemple #14
0
        public bool QueueNormalSupportLayer(ConfigSettings config, GCodePlanner gcodeLayer, int layerIndex, GCodePathConfig supportNormalConfig)
        {
            // normal support
            Polygons currentSupportOutlines = supportOutlines[layerIndex];

            currentSupportOutlines = currentSupportOutlines.Offset(-supportNormalConfig.lineWidth_um / 2);
            List <Polygons> supportIslands = currentSupportOutlines.ProcessIntoSeparatIslands();

            bool outputPaths = false;

            foreach (Polygons islandOutline in supportIslands)
            {
                // force a retract if changing islands
                if (config.RetractWhenChangingIslands)
                {
                    gcodeLayer.ForceRetract();
                }

                Polygons islandInfillLines = new Polygons();
                // render a grid of support
                if (config.GenerateSupportPerimeter || layerIndex == 0)
                {
                    Polygons outlines = Clipper.CleanPolygons(islandOutline, config.ExtrusionWidth_um / 4);
                    if (gcodeLayer.QueuePolygonsByOptimizer(outlines, supportNormalConfig))
                    {
                        outputPaths = true;
                    }
                }

                Polygons infillOutline = islandOutline.Offset(-supportNormalConfig.lineWidth_um / 2);

                if (layerIndex == 0)
                {
                    // on the first layer print this as solid
                    Infill.GenerateLineInfill(config, infillOutline, islandInfillLines, config.SupportInfillStartingAngle, config.ExtrusionWidth_um);
                }
                else
                {
                    switch (config.SupportType)
                    {
                    case ConfigConstants.SUPPORT_TYPE.GRID:
                        Infill.GenerateGridInfill(config, infillOutline, islandInfillLines, config.SupportInfillStartingAngle, config.SupportLineSpacing_um);
                        break;

                    case ConfigConstants.SUPPORT_TYPE.LINES:
                        Infill.GenerateLineInfill(config, infillOutline, islandInfillLines, config.SupportInfillStartingAngle, config.SupportLineSpacing_um);
                        break;
                    }
                }

                if (gcodeLayer.QueuePolygonsByOptimizer(islandInfillLines, supportNormalConfig))
                {
                    outputPaths |= true;
                }
            }

            return(outputPaths);
        }
Exemple #15
0
        public void GenerateInsets(long extrusionWidth_um, long outerExtrusionWidth_um, int insetCount, bool avoidCrossingPerimeters)
        {
            LayerIsland part = this;

            part.BoundingBox.Calculate(part.IslandOutline);

            if (avoidCrossingPerimeters)
            {
                part.PathFinder = new PathFinder(part.IslandOutline, extrusionWidth_um * 3 / 2, useInsideCache: avoidCrossingPerimeters, name: "inset island");
            }

            if (insetCount == 0)
            {
                // if we have no insets defined still create one
                part.InsetToolPaths.Add(part.IslandOutline);
            }
            else             // generate the insets
            {
                long currentOffset = 0;

                // Inset 0 will use the outerExtrusionWidth_um, everyone else will use extrusionWidth_um
                long offsetBy = outerExtrusionWidth_um / 2;

                for (int i = 0; i < insetCount; i++)
                {
                    // Increment by half the offset amount
                    currentOffset += offsetBy;

                    Polygons currentInset = part.IslandOutline.Offset(-currentOffset);
                    // make sure our polygon data is reasonable
                    currentInset = Clipper.CleanPolygons(currentInset, minimumDistanceToCreateNewPosition);

                    // check that we have actual paths
                    if (currentInset.Count > 0)
                    {
                        part.InsetToolPaths.Add(currentInset);

                        // Increment by the second half
                        currentOffset += offsetBy;
                    }
                    else
                    {
                        // we are done making insets as we have no area left
                        break;
                    }

                    if (i == 0)
                    {
                        // Reset offset amount to half the standard extrusion width
                        offsetBy = extrusionWidth_um / 2;
                    }
                }
            }
        }
Exemple #16
0
        private static List <Polygons> CreateInsetPartOutlines(List <Polygons> inputPolys, long insetAmount_um)
        {
            int             numLayers        = inputPolys.Count;
            List <Polygons> allInsetOutlines = CreateEmptyPolygons(numLayers);

            // calculate all the non-supported areas
            for (int layerIndex = 0; layerIndex < numLayers; layerIndex++)
            {
                allInsetOutlines[layerIndex] = Clipper.CleanPolygons(inputPolys[layerIndex].Offset(-insetAmount_um), cleanDistance_um);
            }

            return(allInsetOutlines);
        }
        private static Polygons RemoveIslandsFromPolygons(List <LayerIsland> islands, Aabb boundsToConsider, Polygons polygonsToSubtractFrom)
        {
            for (int islandIndex = 0; islandIndex < islands.Count; islandIndex++)
            {
                if (boundsToConsider.Hit(islands[islandIndex].BoundingBox))
                {
                    polygonsToSubtractFrom = polygonsToSubtractFrom.CreateDifference(islands[islandIndex].InsetToolPaths[islands[islandIndex].InsetToolPaths.Count - 1]);

                    polygonsToSubtractFrom = Clipper.CleanPolygons(polygonsToSubtractFrom, cleanDistance_um);
                }
            }

            return(polygonsToSubtractFrom);
        }
Exemple #18
0
        private static Polygons RemoveAdditionalOutlinesForPart(SliceLayer layerToSubtract, SliceLayerPart partToUseAsBounds, Polygons polygonsToSubtractFrom)
        {
            for (int partIndex = 0; partIndex < layerToSubtract.parts.Count; partIndex++)
            {
                if (partToUseAsBounds.BoundingBox.Hit(layerToSubtract.parts[partIndex].BoundingBox))
                {
                    polygonsToSubtractFrom = polygonsToSubtractFrom.CreateDifference(layerToSubtract.parts[partIndex].Insets[layerToSubtract.parts[partIndex].Insets.Count - 1]);

                    polygonsToSubtractFrom = Clipper.CleanPolygons(polygonsToSubtractFrom, cleanDistance_um);
                }
            }

            return(polygonsToSubtractFrom);
        }
Exemple #19
0
        public void Offset(float offset)
        {
            Paths         polygons = Clipper.ClosedPathsFromPolyTree(polyTree);
            ClipperOffset co       = new ClipperOffset();

            co.ArcTolerance = scale * .0001f;
            co.AddPaths(polygons, JoinType.jtRound, EndType.etClosedPolygon);
            polyTree = new PolyTree();
            Paths offsetPaths = new Paths();

            co.Execute(ref offsetPaths, scale * offset);
            offsetPaths = Clipper.CleanPolygons(offsetPaths, scale * .0001f);
            polyTree    = PolygonsToPolyTree(offsetPaths);
        }
Exemple #20
0
        private static List <Polygons> ExpandToEasyGrabDistance(List <Polygons> inputPolys, long grabDistance_um)
        {
            int numLayers = inputPolys.Count;

            List <Polygons> easyGrabDistanceOutlines = CreateEmptyPolygons(numLayers);

            for (int layerIndex = numLayers - 1; layerIndex >= 0; layerIndex--)
            {
                Polygons curLayerPolys = inputPolys[layerIndex];
                easyGrabDistanceOutlines[layerIndex] = Clipper.CleanPolygons(curLayerPolys.Offset(grabDistance_um), cleanDistance_um);
            }

            return(easyGrabDistanceOutlines);
        }
Exemple #21
0
        private static List <Polygons> FindAllPotentialSupportOutlines(List <Polygons> inputPolys, long supportWidth_um)
        {
            int             numLayers = inputPolys.Count;
            List <Polygons> allPotentialSupportOutlines = CreateEmptyPolygons(numLayers);

            // calculate all the non-supported areas
            for (int layerIndex = numLayers - 2; layerIndex >= 0; layerIndex--)
            {
                Polygons aboveLayerPolys     = inputPolys[layerIndex + 1];
                Polygons curLayerPolys       = inputPolys[layerIndex].Offset(supportWidth_um);
                Polygons areasNeedingSupport = aboveLayerPolys.CreateDifference(curLayerPolys);
                allPotentialSupportOutlines[layerIndex] = Clipper.CleanPolygons(areasNeedingSupport, cleanDistance_um);
            }

            return(allPotentialSupportOutlines);
        }
Exemple #22
0
        private static List <Polygons> CalculateDifferencePerLayer(List <Polygons> inputPolys, List <Polygons> outlinesToRemove)
        {
            int numLayers = inputPolys.Count;

            List <Polygons> diferenceLayers = CreateEmptyPolygons(numLayers);

            for (int layerIndex = numLayers - 2; layerIndex >= 0; layerIndex--)
            {
                Polygons curRequiredSupport    = inputPolys[layerIndex];
                Polygons totalSupportThisLayer = curRequiredSupport.CreateDifference(outlinesToRemove[layerIndex]);

                diferenceLayers[layerIndex] = Clipper.CleanPolygons(totalSupportThisLayer, cleanDistance_um);
            }

            return(diferenceLayers);
        }
        private static Polygons AddIslandsToPolygons(List <LayerIsland> islands, Aabb boundsToConsider, Polygons polysToAddTo)
        {
            Polygons polysToIntersect = new Polygons();

            for (int islandIndex = 0; islandIndex < islands.Count; islandIndex++)
            {
                if (boundsToConsider.Hit(islands[islandIndex].BoundingBox))
                {
                    polysToIntersect = polysToIntersect.CreateUnion(islands[islandIndex].InsetToolPaths[islands[islandIndex].InsetToolPaths.Count - 1]);
                    polysToIntersect = Clipper.CleanPolygons(polysToIntersect, cleanDistance_um);
                }
            }

            polysToAddTo = polysToAddTo.CreateIntersection(polysToIntersect);

            return(polysToAddTo);
        }
Exemple #24
0
		public static VertexStorage Offset(this IVertexSource a, double distance)
		{
			List<List<IntPoint>> aPolys = a.CreatePolygons();

			ClipperOffset offseter = new ClipperOffset();
			offseter.AddPaths(aPolys, JoinType.jtMiter, EndType.etClosedPolygon);
			var solution = new List<List<IntPoint>>();
			offseter.Execute(ref solution, distance * 1000);

			Clipper.CleanPolygons(solution);

			VertexStorage output = solution.CreateVertexStorage();

			output.Add(0, 0, ShapePath.FlagsAndCommand.Stop);

			return output;
		}
Exemple #25
0
        private static List <Polygons> ClipToXyDistance(List <Polygons> inputPolys, List <Polygons> allPartOutlines, ConfigSettings config)
        {
            int numLayers = inputPolys.Count;

            List <Polygons> clippedToXyOutlines = CreateEmptyPolygons(numLayers);

            for (int layerIndex = numLayers - 2; layerIndex >= 0; layerIndex--)
            {
                Polygons curRequiredSupport    = inputPolys[layerIndex];
                Polygons expandedlayerPolys    = allPartOutlines[layerIndex].Offset(config.SupportXYDistance_um);
                Polygons totalSupportThisLayer = curRequiredSupport.CreateDifference(expandedlayerPolys);

                clippedToXyOutlines[layerIndex] = Clipper.CleanPolygons(totalSupportThisLayer, cleanDistance_um);
            }

            return(clippedToXyOutlines);
        }
Exemple #26
0
        private static Polygons AddAllOutlines(SliceLayer layerToAdd, SliceLayerPart partToUseAsBounds, Polygons polysToAddTo)
        {
            Polygons polysToIntersect = new Polygons();

            for (int partIndex = 0; partIndex < layerToAdd.parts.Count; partIndex++)
            {
                if (partToUseAsBounds.BoundingBox.Hit(layerToAdd.parts[partIndex].BoundingBox))
                {
                    polysToIntersect = polysToIntersect.CreateUnion(layerToAdd.parts[partIndex].Insets[layerToAdd.parts[partIndex].Insets.Count - 1]);
                    polysToIntersect = Clipper.CleanPolygons(polysToIntersect, cleanDistance_um);
                }
            }

            polysToAddTo = polysToAddTo.CreateIntersection(polysToIntersect);

            return(polysToAddTo);
        }
Exemple #27
0
        private static List <Polygons> RemoveSupportFromInternalSpaces(List <Polygons> inputPolys, List <Polygons> allPartOutlines)
        {
            int numLayers = inputPolys.Count;

            Polygons accumulatedLayers = new Polygons();

            for (int layerIndex = 0; layerIndex < numLayers; layerIndex++)
            {
                accumulatedLayers = accumulatedLayers.CreateUnion(allPartOutlines[layerIndex]);
                accumulatedLayers = Clipper.CleanPolygons(accumulatedLayers, cleanDistance_um);

                inputPolys[layerIndex] = inputPolys[layerIndex].CreateDifference(accumulatedLayers);
                inputPolys[layerIndex] = Clipper.CleanPolygons(inputPolys[layerIndex], cleanDistance_um);
            }

            return(inputPolys);
        }
Exemple #28
0
        public static void GenerateInsets(SliceLayerPart part, int offset_um, int outerPerimeterOffset_um, int insetCount)
        {
            double minimumDistanceToCreateNewPosition = 10;

            int currentOffset = 0;
            int offsetBy      = outerPerimeterOffset_um / 2;

            part.AvoidCrossingBoundery = part.TotalOutline.Offset(-offset_um);
            if (insetCount == 0)
            {
                // if we have no insets defined still create one
                part.Insets.Add(part.TotalOutline);
            }
            else             // generate the insets
            {
                for (int i = 0; i < insetCount; i++)
                {
                    currentOffset += offsetBy;

                    Polygons currentInset = part.TotalOutline.Offset(-currentOffset);
                    // make sure our polygon data is reasonable
                    currentInset = Clipper.CleanPolygons(currentInset, minimumDistanceToCreateNewPosition);

                    // check that we have actuall paths
                    if (currentInset.Count > 0)
                    {
                        part.Insets.Add(currentInset);
                        currentOffset += (offsetBy + offset_um / 2);
                        offsetBy       = offset_um / 2;
                    }
                    else
                    {
                        // we are done making insets as we have no arrea left
                        break;
                    }

                    currentOffset += offsetBy;

                    if (i == 0)
                    {
                        offsetBy = offset_um / 2;
                    }
                }
            }
        }
Exemple #29
0
        private static Polygons IntersectWithSparsePolygons(List <LayerIsland> islands, Aabb boundsToConsider, Polygons polysToIntersect)
        {
            Polygons polysFromIslands = new Polygons();

            for (int islandIndex = 0; islandIndex < islands.Count; islandIndex++)
            {
                if (boundsToConsider.Hit(islands[islandIndex].BoundingBox))
                {
                    if (islands[islandIndex].InsetToolPaths.Count > 0)
                    {
                        polysFromIslands = polysFromIslands.CreateUnion(islands[islandIndex].SparseInfillPaths);
                        polysFromIslands = Clipper.CleanPolygons(polysFromIslands, cleanDistance_um);
                    }
                }
            }

            polysToIntersect = polysToIntersect.CreateIntersection(polysFromIslands);

            return(polysToIntersect);
        }
Exemple #30
0
        private static List <Polygons> PushUpTops(List <Polygons> inputPolys, ConfigSettings config)
        {
            int numLayers = inputPolys.Count;

            return(inputPolys);

            int             layersFor2Mm  = 2000 / config.LayerThickness_um;
            List <Polygons> pushedUpPolys = CreateEmptyPolygons(numLayers);

            for (int layerIndex = numLayers - 1; layerIndex >= 0; layerIndex--)
            {
                for (int layerToAddToIndex = Math.Min(layerIndex + layersFor2Mm, numLayers - 1); layerToAddToIndex >= 0; layerToAddToIndex--)
                {
                }

                Polygons curLayerPolys = inputPolys[layerIndex];
                pushedUpPolys[layerIndex] = Clipper.CleanPolygons(curLayerPolys.Offset(config.ExtrusionWidth_um + config.SupportXYDistance_um), cleanDistance_um);
            }

            return(pushedUpPolys);
        }