Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
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);
        }
Example #4
0
        public static bool BridgeAngle(Polygons outline, SliceLayer prevLayer, out double bridgeAngle, string debugName = "")
        {
            bridgeAngle = -1;
            Aabb boundaryBox = new Aabb(outline);
            //To detect if we have a bridge, first calculate the intersection of the current layer with the previous layer.
            // This gives us the islands that the layer rests on.
            Polygons islands = new Polygons();

            foreach (SliceLayerPart prevLayerPart in prevLayer.parts)
            {
                if (!boundaryBox.Hit(prevLayerPart.BoundingBox))
                {
                    continue;
                }

                islands.AddRange(outline.CreateIntersection(prevLayerPart.TotalOutline));
            }

#if OUTPUT_DEBUG_DATA
            string outlineString     = outline.WriteToString();
            string partOutlineString = "";
            foreach (SliceLayerPart prevLayerPart in prevLayer.parts)
            {
                foreach (Polygon prevPartOutline in prevLayerPart.outline)
                {
                    partOutlineString += prevPartOutline.WriteToString();
                }

                partOutlineString += "|";
            }

            string islandsString = islands.WriteToString();
#endif

            if (islands.Count > 5 || islands.Count < 1)
            {
                return(false);
            }

            if (islands.Count == 1)
            {
                return(GetSingleIslandAngle(outline, islands[0], out bridgeAngle, debugName));
            }

            // Find the 2 largest islands that we rest on.
            double biggestArea       = 0;
            double nextBiggestArea   = 0;
            int    indexOfBiggest    = -1;
            int    indexOfNextBigest = -1;
            for (int islandIndex = 0; islandIndex < islands.Count; islandIndex++)
            {
                //Skip internal holes
                if (!islands[islandIndex].Orientation())
                {
                    continue;
                }

                double area = Math.Abs(islands[islandIndex].Area());
                if (area > biggestArea)
                {
                    if (biggestArea > nextBiggestArea)
                    {
                        nextBiggestArea   = biggestArea;
                        indexOfNextBigest = indexOfBiggest;
                    }
                    biggestArea    = area;
                    indexOfBiggest = islandIndex;
                }
                else if (area > nextBiggestArea)
                {
                    nextBiggestArea   = area;
                    indexOfNextBigest = islandIndex;
                }
            }

            if (indexOfBiggest < 0 || indexOfNextBigest < 0)
            {
                return(false);
            }

            IntPoint center1 = islands[indexOfBiggest].CenterOfMass();
            IntPoint center2 = islands[indexOfNextBigest].CenterOfMass();

            bridgeAngle = Math.Atan2(center2.Y - center1.Y, center2.X - center1.X) / Math.PI * 180;
            Range0To360(ref bridgeAngle);
#if OUTPUT_DEBUG_DATA
            islands.SaveToGCode("{0} - angle {1:0.}.gcode".FormatWith(debugName, bridgeAngle));
#endif
            return(true);
        }
Example #5
0
		public bool BridgeAngle(Polygons areaAboveToFill, out double bridgeAngle, string debugName = "")
		{
			SliceLayer layerToRestOn = this;
            bridgeAngle = -1;
			Aabb boundaryBox = new Aabb(areaAboveToFill);
			//To detect if we have a bridge, first calculate the intersection of the current layer with the previous layer.
			// This gives us the islands that the layer rests on.
			Polygons islandsToRestOn = new Polygons();
			foreach (LayerIsland islandToRestOn in layerToRestOn.Islands)
			{
				if (!boundaryBox.Hit(islandToRestOn.BoundingBox))
				{
					continue;
				}

				islandsToRestOn.AddRange(areaAboveToFill.CreateIntersection(islandToRestOn.IslandOutline));
			}

			if (OUTPUT_DEBUG_DATA)
			{
				string outlineString = areaAboveToFill.WriteToString();
				string islandOutlineString = "";
				foreach (LayerIsland prevLayerIsland in layerToRestOn.Islands)
				{
					foreach (Polygon islandOutline in prevLayerIsland.IslandOutline)
					{
						islandOutlineString += islandOutline.WriteToString();
					}

					islandOutlineString += "|";
				}

				string islandsString = islandsToRestOn.WriteToString();
			}

			Polygons islandConvexHuls = new Polygons();
			foreach(Polygon poly in islandsToRestOn)
			{
				islandConvexHuls.Add(poly.CreateConvexHull());
			}

			if (islandsToRestOn.Count > 5 || islandsToRestOn.Count < 1)
			{
				return false;
			}

			if (islandsToRestOn.Count == 1)
			{
				return GetSingleIslandAngle(areaAboveToFill, islandsToRestOn[0], out bridgeAngle, debugName);
			}

			// Find the 2 largest islands that we rest on.
			double biggestArea = 0;
			double nextBiggestArea = 0;
			int indexOfBiggest = -1;
			int indexOfNextBigest = -1;
			for (int islandIndex = 0; islandIndex < islandsToRestOn.Count; islandIndex++)
			{
				//Skip internal holes
				if (!islandsToRestOn[islandIndex].Orientation())
				{
					continue;
				}

				double area = Math.Abs(islandConvexHuls[islandIndex].Area());
				if (area > biggestArea)
				{
					if (biggestArea > nextBiggestArea)
					{
						nextBiggestArea = biggestArea;
						indexOfNextBigest = indexOfBiggest;
					}
					biggestArea = area;
					indexOfBiggest = islandIndex;
				}
				else if (area > nextBiggestArea)
				{
					nextBiggestArea = area;
					indexOfNextBigest = islandIndex;
				}
			}

			if (indexOfBiggest < 0 || indexOfNextBigest < 0)
			{
				return false;
			}

			Polygons big1 = new Polygons() { islandConvexHuls[indexOfBiggest] };
			Polygons big2 = new Polygons() { islandConvexHuls[indexOfNextBigest] };

			Polygons intersection = big1.CreateIntersection(big2);
			if(intersection.Count > 0)
			{
				return GetSingleIslandAngle(areaAboveToFill, islandsToRestOn[indexOfBiggest], out bridgeAngle, debugName);
			}

			IntPoint center1 = islandsToRestOn[indexOfBiggest].CenterOfMass();
			IntPoint center2 = islandsToRestOn[indexOfNextBigest].CenterOfMass();

			bridgeAngle = Math.Atan2(center2.Y - center1.Y, center2.X - center1.X) / Math.PI * 180;
			Range0To360(ref bridgeAngle);
			if (OUTPUT_DEBUG_DATA)
			{
				islandsToRestOn.SaveToGCode("{0} - angle {1:0.}.gcode".FormatWith(debugName, bridgeAngle));
			}
			return true;
		}
Example #6
0
        public bool BridgeAngle(Polygons areaAboveToFill, out double bridgeAngle, string debugName = "")
        {
            SliceLayer layerToRestOn = this;

            bridgeAngle = -1;
            Aabb boundaryBox = new Aabb(areaAboveToFill);
            //To detect if we have a bridge, first calculate the intersection of the current layer with the previous layer.
            // This gives us the islands that the layer rests on.
            Polygons islandsToRestOn = new Polygons();

            foreach (LayerIsland islandToRestOn in layerToRestOn.Islands)
            {
                if (!boundaryBox.Hit(islandToRestOn.BoundingBox))
                {
                    continue;
                }

                islandsToRestOn.AddRange(areaAboveToFill.CreateIntersection(islandToRestOn.IslandOutline));
            }

            if (OUTPUT_DEBUG_DATA)
            {
                string outlineString       = areaAboveToFill.WriteToString();
                string islandOutlineString = "";
                foreach (LayerIsland prevLayerIsland in layerToRestOn.Islands)
                {
                    foreach (Polygon islandOutline in prevLayerIsland.IslandOutline)
                    {
                        islandOutlineString += islandOutline.WriteToString();
                    }

                    islandOutlineString += "|";
                }

                string islandsString = islandsToRestOn.WriteToString();
            }

            if (islandsToRestOn.Count > 5 || islandsToRestOn.Count < 1)
            {
                return(false);
            }

            if (islandsToRestOn.Count == 1)
            {
                return(GetSingleIslandAngle(areaAboveToFill, islandsToRestOn[0], out bridgeAngle, debugName));
            }

            // Find the 2 largest islands that we rest on.
            double biggestArea       = 0;
            double nextBiggestArea   = 0;
            int    indexOfBiggest    = -1;
            int    indexOfNextBigest = -1;

            for (int islandIndex = 0; islandIndex < islandsToRestOn.Count; islandIndex++)
            {
                //Skip internal holes
                if (!islandsToRestOn[islandIndex].Orientation())
                {
                    continue;
                }

                double area = Math.Abs(islandsToRestOn[islandIndex].Area());
                if (area > biggestArea)
                {
                    if (biggestArea > nextBiggestArea)
                    {
                        nextBiggestArea   = biggestArea;
                        indexOfNextBigest = indexOfBiggest;
                    }
                    biggestArea    = area;
                    indexOfBiggest = islandIndex;
                }
                else if (area > nextBiggestArea)
                {
                    nextBiggestArea   = area;
                    indexOfNextBigest = islandIndex;
                }
            }

            if (indexOfBiggest < 0 || indexOfNextBigest < 0)
            {
                return(false);
            }

            IntPoint center1 = islandsToRestOn[indexOfBiggest].CenterOfMass();
            IntPoint center2 = islandsToRestOn[indexOfNextBigest].CenterOfMass();

            bridgeAngle = Math.Atan2(center2.Y - center1.Y, center2.X - center1.X) / Math.PI * 180;
            Range0To360(ref bridgeAngle);
            if (OUTPUT_DEBUG_DATA)
            {
                islandsToRestOn.SaveToGCode("{0} - angle {1:0.}.gcode".FormatWith(debugName, bridgeAngle));
            }
            return(true);
        }
Example #7
0
		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;
		}
Example #8
0
		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;
		}
Example #9
0
        public bool BridgeAngle(Polygons areaGoingOnTop, long perimeterExpandDistance, out double bridgeAngle, Polygons bridgeAreas, string debugName = "")
        {
            SliceLayer layerToRestOn = this;

            bridgeAngle = -1;
            var boundaryBox = new Aabb(areaGoingOnTop);

            boundaryBox.Expand(perimeterExpandDistance);
            // To detect if we have a bridge, first calculate the intersection of the current layer with the previous layer.
            // This gives us the islands that the layer rests on.

            var islandsToRestOn = new Polygons();

            foreach (LayerIsland islandToRestOn in layerToRestOn.Islands)
            {
                if (!boundaryBox.Hit(islandToRestOn.BoundingBox))
                {
                    continue;
                }

                islandsToRestOn.AddRange(areaGoingOnTop.CreateIntersection(islandToRestOn.IslandOutline));
            }

            if (bridgeAreas != null)
            {
                bridgeAreas.AddRange(areaGoingOnTop.CreateDifference(layerToRestOn.AllOutlines));
            }

            if (outputDebugData)
            {
                WriteDebugData(areaGoingOnTop, layerToRestOn, islandsToRestOn);
            }

            if (islandsToRestOn.Count > 5 || islandsToRestOn.Count < 1)
            {
                return(false);
            }

            if (islandsToRestOn.Count == 1)
            {
                return(GetSingleIslandAngle(areaGoingOnTop, islandsToRestOn[0], out bridgeAngle, debugName));
            }

            // Find the 2 largest islands that we rest on.
            double biggestArea       = 0;
            double nextBiggestArea   = 0;
            int    indexOfBiggest    = -1;
            int    indexOfNextBigest = -1;

            for (int islandIndex = 0; islandIndex < islandsToRestOn.Count; islandIndex++)
            {
                // Skip internal holes
                if (!islandsToRestOn[islandIndex].Orientation())
                {
                    continue;
                }

                double area = Math.Abs(islandsToRestOn[islandIndex].Area());
                if (area > biggestArea)
                {
                    if (biggestArea > nextBiggestArea)
                    {
                        nextBiggestArea   = biggestArea;
                        indexOfNextBigest = indexOfBiggest;
                    }

                    biggestArea    = area;
                    indexOfBiggest = islandIndex;
                }
                else if (area > nextBiggestArea)
                {
                    nextBiggestArea   = area;
                    indexOfNextBigest = islandIndex;
                }
            }

            if (indexOfBiggest < 0 || indexOfNextBigest < 0)
            {
                return(false);
            }

            IntPoint center1 = islandsToRestOn[indexOfBiggest].CenterOfMass();
            IntPoint center2 = islandsToRestOn[indexOfNextBigest].CenterOfMass();

            bridgeAngle = Math.Atan2(center2.Y - center1.Y, center2.X - center1.X) / Math.PI * 180;
            Range0To360(ref bridgeAngle);
            if (outputDebugData)
            {
                islandsToRestOn.SaveToGCode("{0} - angle {1:0.}.gcode".FormatWith(debugName, bridgeAngle));
            }

            return(true);
        }
Example #10
0
        public static bool BridgeAngle(Polygons outline, SliceLayer prevLayer, out double bridgeAngle, string debugName = "")
        {
            bridgeAngle = -1;
            Aabb boundaryBox = new Aabb(outline);
            //To detect if we have a bridge, first calculate the intersection of the current layer with the previous layer.
            // This gives us the islands that the layer rests on.
            Polygons islands = new Polygons();
            foreach (SliceLayerPart prevLayerPart in prevLayer.parts)
            {
                if (!boundaryBox.Hit(prevLayerPart.BoundingBox))
                {
                    continue;
                }

                islands.AddRange(outline.CreateIntersection(prevLayerPart.TotalOutline));
            }

            #if OUTPUT_DEBUG_DATA
            string outlineString = outline.WriteToString();
            string partOutlineString = "";
            foreach (SliceLayerPart prevLayerPart in prevLayer.parts)
            {
                foreach (Polygon prevPartOutline in prevLayerPart.outline)
                {
                    partOutlineString += prevPartOutline.WriteToString();
                }

                partOutlineString += "|";
            }

            string islandsString = islands.WriteToString();
            #endif

            if (islands.Count > 5 || islands.Count < 1)
            {
                return false;
            }

            if (islands.Count == 1)
            {
                return GetSingleIslandAngle(outline, islands[0], out bridgeAngle, debugName);
            }

            // Find the 2 largest islands that we rest on.
            double biggestArea = 0;
            double nextBiggestArea = 0;
            int indexOfBiggest = -1;
            int indexOfNextBigest = -1;
            for (int islandIndex = 0; islandIndex < islands.Count; islandIndex++)
            {
                //Skip internal holes
                if (!islands[islandIndex].Orientation())
                {
                    continue;
                }

                double area = Math.Abs(islands[islandIndex].Area());
                if (area > biggestArea)
                {
                    if (biggestArea > nextBiggestArea)
                    {
                        nextBiggestArea = biggestArea;
                        indexOfNextBigest = indexOfBiggest;
                    }
                    biggestArea = area;
                    indexOfBiggest = islandIndex;
                }
                else if (area > nextBiggestArea)
                {
                    nextBiggestArea = area;
                    indexOfNextBigest = islandIndex;
                }
            }

            if (indexOfBiggest < 0 || indexOfNextBigest < 0)
            {
                return false;
            }

            IntPoint center1 = islands[indexOfBiggest].CenterOfMass();
            IntPoint center2 = islands[indexOfNextBigest].CenterOfMass();

            bridgeAngle = Math.Atan2(center2.Y - center1.Y, center2.X - center1.X) / Math.PI * 180;
            Range0To360(ref bridgeAngle);
            #if OUTPUT_DEBUG_DATA
            islands.SaveToGCode("{0} - angle {1:0.}.gcode".FormatWith(debugName, bridgeAngle));
            #endif
            return true;
        }