private static ClassificationResult GetDirectedResult(INestingManager nestingManager, Part part, WorkingArea workingArea, List <Part> originalParts) { float areaX, areaY; if (!nestingManager.IsRectangle(workingArea, out areaX, out areaY)) { throw new Exception("WorkingArea is not a rectangle!"); } //Step 1: Calculate the tesselation polygon float boxX, boxY; nestingManager.GetRectangleBoxOfPart(part, out boxX, out boxY); int horizontalBoxes = (int)(areaX / boxX); int verticalBoxes = (int)(areaY / boxY); ClassificationResult result = new ClassificationResult(ClassifierInformation); //Step 4: Calculate the remainder polygons List <WorkingArea> remainderPolygons = CalculateRemainderWorkingAreas( nestingManager, boxX, boxY, horizontalBoxes, verticalBoxes, areaX, areaY); //Step 5: Generate the reimainder polygons' problems foreach (WorkingArea remainderPolygon in remainderPolygons) { ClassificationResult subResult = GetMainResult(nestingManager, originalParts, remainderPolygon); if (!nestingManager.IsRectangle(remainderPolygon, out areaX, out areaY)) { throw new Exception("WorkingArea is not a rectangle!"); } result.ExtraPolygons.Add(nestingManager.CalculateRectangle(areaX, areaY, remainderPolygon.Placement)); result.AddSubResult(subResult, remainderPolygon.Placement); } for (int i = 0; i < horizontalBoxes; i++) { for (int j = 0; j < verticalBoxes; j++) { Point placementPart = new Point(i * boxX, j * boxY); PlaceGenericPart(nestingManager, placementPart, part, result); result.ExtraPolygons.Add(nestingManager.CalculateRectangle(boxX, boxY, placementPart)); } } return(result); }
public static ClassificationResult GetMainResult( INestingManager nestingManager, List <Part> originalParts, WorkingArea workingArea) { float areaX, areaY; if (!nestingManager.IsRectangle(workingArea, out areaX, out areaY)) { throw new Exception("WorkingArea is not a rectangle!"); } //Step 1: Remove parts that do not fit the working area float boxX; float boxY; List <Part> parts = new List <Part>(); foreach (Part part in originalParts) { nestingManager.GetRectangleBoxOfPart(part, out boxX, out boxY); if (areaX >= boxX && areaY >= boxY) { //Part does not fit the working area parts.Add(part); } } //Step 2: Break if no parts fit the working area if (!parts.Any()) { //Empty result return(new ClassificationResult(ClassifierInformation) { WorkingArea = workingArea }); } //Step 2.5: Sort parts by Area size in descending order, so we favor the placement of bigger pieces //in case there are not enough polygons to place all the parts, because the smaller parts could be fit in the remainders parts = parts.OrderByDescending(x => x.GetTotalArea()).ToList(); //Step 3: Calculate the tesselation polygon nestingManager.GetRectangleBoxOfParts(parts, out boxX, out boxY); int horizontalBoxes = (int)(areaX / boxX); int verticalBoxes = (int)(areaY / boxY); WorkingArea tesselationPolygon = new WorkingArea() { Vertexes = new List <Point>() { new Point(0, 0), new Point(boxX, 0), new Point(boxX, boxY), new Point(0, boxY) } }; ClassificationResult result = new ClassificationResult(ClassifierInformation); //Step 4: Calculate the remainder polygons List <WorkingArea> remainderPolygons = CalculateRemainderWorkingAreas( nestingManager, boxX, boxY, horizontalBoxes, verticalBoxes, areaX, areaY); //Step 5: Generate the reimainder polygons' problems foreach (WorkingArea remainderPolygon in remainderPolygons) { ClassificationResult subResult = GetMainResult(nestingManager, parts, remainderPolygon); if (!nestingManager.IsRectangle(remainderPolygon, out areaX, out areaY)) { throw new Exception("WorkingArea is not a rectangle!"); } result.ExtraPolygons.Add(nestingManager.CalculateRectangle(areaX, areaY, remainderPolygon.Placement)); result.AddSubResult(subResult, remainderPolygon.Placement); } //Step6: Generate tesselation poligons' subproblem List <ClassificationResult> subresults = new List <ClassificationResult>(); foreach (Part part in parts) { ClassificationResult res = GetDirectedResult(nestingManager, part, tesselationPolygon, parts); if (res != null) { subresults.Add(res); } } result.WorkingArea = workingArea.Clone(); int numberOfParts = parts.Count; int partIndex = 0; //Place parts until we run out of space for (int i = 0; i < horizontalBoxes; i++) { for (int j = 0; j < verticalBoxes; j++) { ClassificationResult subResult = subresults[partIndex % numberOfParts]; Point subResultOrigin = new Point(i * boxX, j * boxY); result.AddSubResult(subResult, subResultOrigin); partIndex++; } } return(result); }