private void CloneOnClick(object sender, EventArgs eventArgs) { if (lstExistingWorkingAreas.SelectedItems.Count == 0) { return; } ListViewItem listviewItem = lstExistingWorkingAreas.SelectedItems[0]; WorkingArea workingArea = (WorkingArea)listviewItem.Tag; //WorkingArea to be cloned! if (DialogResult.Yes == MessageBox.Show("Are you really sure you want to clone this workingArea?", "Clone workingArea?", MessageBoxButtons.YesNo)) { lstExistingWorkingAreas.SelectedItems.Clear(); lstExistingWorkingAreas.Items.Remove(listviewItem); WorkingArea clone = workingArea.Clone(); clone.Id = null; clone.Name = workingArea.Name + "_CLONE"; workingAreasPersistence.AddOrUpdate(clone.Id, clone); ListWorkingAreas(); } }
private static ClassificationResult ClassifyGeneric( INestingManager manager, List <Part> parts, WorkingArea workingArea) { float areaX, areaY; if (!manager.IsRectangle(workingArea, out areaX, out areaY)) { throw new Exception("WorkingArea is not a rectangle!"); } float boxX, boxY; manager.GetRectangleBoxOfParts(parts, out boxX, out boxY); if (boxX > areaX || boxY > areaY) { throw new Exception("Part does not fit inside Working area!"); } //Calculate how many boxes could be fit in the area int horizontalBoxes = (int)(areaX / boxX); int verticalBoxes = (int)(areaY / boxY); //We build the final result using the partial results and the calculated positions of the boxes ClassificationResult result = new ClassificationResult(ClassifierInformation) { WorkingArea = workingArea.Clone() }; 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++) { Point subResultOrigin = new Point(i * boxX, j * boxY); result.ExtraPolygons.Add(manager.CalculateRectangle(boxX, boxY, subResultOrigin)); Part placedPart = parts[partIndex % parts.Count].Clone(); placedPart.Place(subResultOrigin); result.Parts.Add(placedPart); partIndex++; } } return(result); }
public ClassificationParameters(WorkingArea workingArea, List <Part> parts) { if (workingArea == null) { throw new Exception("Error creating ClassificationParameters: WorkingArea is null!"); } if (workingArea.Vertexes.Count < 3) { throw new Exception("Error creating ClassificationParameters: WorkingArea has a wrong number of vertexes!"); } if (parts == null || parts.Count == 0) { throw new Exception("Error creating ClassificationParameters: Parts list is null or empty!"); } //We check if parts can't fit in the working area (too big) this.WorkingArea = workingArea.Clone(); this.WorkingArea.Parts.Clear(); double available = workingArea.GetTotalArea(); this.Parts = new List <Part>(); foreach (Part part in parts) { Part clone = (Part)part.Clone(); clone.UnPlace(); if (clone.Vertexes.Count < 3) { throw new Exception("Error creating ClassificationParameters: Part has a wrong number of vertexes!"); } available = available - clone.GetTotalArea(); Parts.Add(clone); } }
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); }