public static void CombineShapes(List <Polygon> shapes, out List <Polygon> resultingShapes, int depth = 0) { List <Polygon> applicants = new List <Polygon>(); Polygon currentPolygonToEval = null; List <Polygon> options = new List <Polygon>(shapes); int save = 0; while (true) { if (currentPolygonToEval == null) { if (options.Count <= 0) { break; } currentPolygonToEval = options[0]; options.RemoveAt(0); } Polygon prev = null; Polygon found = null; bool anyCombination = false; for (int i = 0; i < options.Count; i++) { Polygon v = new Polygon(currentPolygonToEval); v = v.Combine(options[i]); if (v != null) { v = RemoveRedundantPoints(v); if (IsShapeConvex(v)) { found = options[i]; prev = new Polygon(currentPolygonToEval); currentPolygonToEval = v; options.RemoveAt(i); anyCombination = true; break; } } } VMFDebug.CreateDebugImage("CombiningStep" + (save++), onDraw: (g) => { Pen greyPen = new Pen(Color.Gray, 3); Pen blackPen = new Pen(Color.Black, 3); Pen redPen = new Pen(Color.Red, 3); Pen bluePen = new Pen(Color.Blue, 3); Pen greenPen = new Pen(Color.Green, 3); for (int i = 0; i < options.Count; i++) { VMFDebug.AddShapeToGraphics(g, options[i], greyPen); } for (int i = 0; i < applicants.Count; i++) { VMFDebug.AddShapeToGraphics(g, applicants[i], blackPen); } if (found != null) { VMFDebug.AddShapeToGraphics(g, found, bluePen); } if (prev != null) { VMFDebug.AddShapeToGraphics(g, prev, greenPen); } else { VMFDebug.AddShapeToGraphics(g, currentPolygonToEval, redPen); } }); if (!anyCombination) { applicants.Add(new Polygon(currentPolygonToEval)); currentPolygonToEval = null; } } List <Polygon> result = new List <Polygon>(); for (int i = 0; i < applicants.Count; i++) { bool canAdd = true; for (int j = 0; j < result.Count; j++) { PolygonShapeData rSD = result[j].Data as PolygonShapeData; PolygonShapeData aSD = applicants[i].Data as PolygonShapeData; if (rSD.PolygonPoints.SequenceEqual(aSD.PolygonPoints)) { canAdd = false; break; } } if (canAdd) { result.Add(applicants[i]); } } resultingShapes = result; }
private void GenerateData(out List <Shape> shapesResult, out List <string> entities) { List <GenerationMethod> generationMethods = new List <GenerationMethod>(); entities = new List <string>(); EasyInputLayer.GetInput(out generationMethods, out entities); //Start shape construction List <Shape> shapes = new List <Shape>(); for (int i = 0; i < generationMethods.Count; i++) { shapes.AddRange(generationMethods[i].GetBrushes()); } List <Shape> finalShapeList = new List <Shape>(); for (int i = shapes.Count - 1; i >= 0; i--) { if (shapes[i] is Polygon) { (shapes[i] as Polygon).CalculatePreGenerateData(); if (!IsShapeConvex(shapes[i] as Polygon)) { VMFDebug.CreateDebugImage("PreTriangulation" + (i), onDraw: (g) => { Pen greyPen = new Pen(Color.Gray, 3); Pen redPen = new Pen(Color.Red, 3); for (int j = 0; j < shapes.Count; j++) { if (shapes[j] is Polygon) { VMFDebug.AddShapeToGraphics(g, shapes[j] as Polygon, greyPen); } } VMFDebug.AddShapeToGraphics(g, shapes[i] as Polygon, redPen); }); Console.WriteLine("Found a concave shape. Attempting triangulation"); List <Polygon> replacements = new List <Polygon>(); List <Shape> temp = ConvertToConvex(shapes[i] as Polygon); for (int j = 0; j < temp.Count; j++) { replacements.Add(temp[j] as Polygon); } Console.WriteLine("Single shape converted into " + replacements.Count + " new shapes"); List <Polygon> combinedShapes = new List <Polygon>(); for (int j = replacements.Count - 1; j >= 0; j--) { if (!IsShapeConvex(replacements[j] as Polygon)) { replacements[j] = RemoveRedundantPoints(replacements[j] as Polygon); Console.WriteLine("An invalid shape was found in the replacement batch. Attempting to fix..."); if (((PolygonShapeData)replacements[j].Data).PolygonPoints.Count < 3 || !IsShapeConvex(replacements[j] as Polygon)) { Console.WriteLine("Could not fix invalid shape. Deleting."); replacements.RemoveAt(j); } else { Console.WriteLine("Invalid shape fixed!"); } } } combinedShapes = replacements; CombineShapes(replacements, out combinedShapes); PolygonShapeData shapeData = shapes[i].Data as PolygonShapeData; for (int j = 0; j < combinedShapes.Count; j++) { finalShapeList.Add(combinedShapes[j]); } } else { finalShapeList.Add(shapes[i] as Polygon); } } else { finalShapeList.Add(shapes[i]); } } int currId = 0; for (int i = 0; i < finalShapeList.Count; i++) { finalShapeList[i].ID = i; finalShapeList[i].GenerateSides(currId); currId += finalShapeList[i].Sides.Length; } //End shape construction shapesResult = finalShapeList; }