internal static bool ChamferPolygons(List <Polygon> polygons, List <Edge> edges, float distance, int iterations, out List <Polygon> resultPolygons) { // list of clipping planes. List <Plane> clippingPlanes = new List <Plane>(); // iterate through all edges and calculate the clipping planes. for (int e = 0; e < edges.Count; e++) { Edge edge = edges[e]; // find the two polygons connected to the edge. Polygon[] matchingPolygons = polygons.Where(p => Polygon.ContainsEdge(p, edge)).ToArray(); if (matchingPolygons.Length != 2) { resultPolygons = null; return(false); } ; // find the actual edges on the polygons (which helps determine their direction for the chamfer). Edge realEdge1; Polygon.FindEdge(matchingPolygons[0], edge, out realEdge1); Edge realEdge2; Polygon.FindEdge(matchingPolygons[1], edge, out realEdge2); // calculate clipping plane position: Vector3 v1 = realEdge1.Vertex1.Position - ChamferPolygons_GetNormal(realEdge1.Vertex1.Position, realEdge1.Vertex2.Position, matchingPolygons[0].GetCenterPoint()).normalized *distance; Vector3 v2 = realEdge1.Vertex2.Position - ChamferPolygons_GetNormal(realEdge1.Vertex1.Position, realEdge1.Vertex2.Position, matchingPolygons[0].GetCenterPoint()).normalized *distance; Vector3 v3 = realEdge2.Vertex2.Position - ChamferPolygons_GetNormal(realEdge2.Vertex1.Position, realEdge2.Vertex2.Position, matchingPolygons[1].GetCenterPoint()).normalized *distance; for (int i = 0; i < iterations; i++) { float t = (1.0f / iterations); Vector3 p1 = ShapeEditor.Bezier.GetPoint(v1, realEdge1.Vertex1.Position, v3, t * i); Vector3 p2 = ShapeEditor.Bezier.GetPoint(v1, realEdge1.Vertex1.Position, v3, t * (i + 1)); clippingPlanes.Add(new Plane( p1, p2, p1 + (v1 - v2).normalized )); } } // copy the input polygons. resultPolygons = polygons.DeepCopy(); // clip the polygons. for (int i = 0; i < clippingPlanes.Count; i++) { List <Polygon> polygonsFront; List <Polygon> polygonsBack; if (SplitPolygonsByPlane(resultPolygons, clippingPlanes[i], false, out polygonsFront, out polygonsBack)) { resultPolygons = polygonsFront; } } return(true); }
public static bool SplitPolygonsByEdges(Polygon[] polygons, List <Edge> sourceEdges, out Polygon[] finalPolygons, out List <Edge> newEdges) { // First of all refine the list of edges to those that are on the polygons and share a polygon with another specified edge // Verification step, no more than two edges should be selected per face // Once the list of edges is refined, walk through each set of polygons // Where a polygon has two specified edges, it needs to be split in two // Where a polygon has one specified edge, it needs a vertex to be added List <Polygon> newPolygons = new List <Polygon>(polygons); // Complete set of new polygons newEdges = new List <Edge>(); // These are the new edges we create List <Edge> edges = new List <Edge>(); // Pull out a list of edges that occur on any of the polygons at least twice. // This way we ignore edges on other brushes or edges which aren't possible to connect via a polygon for (int edge1Index = 0; edge1Index < sourceEdges.Count; edge1Index++) { bool found = false; for (int i = 0; i < polygons.Length && !found; i++) { Edge edge1 = sourceEdges[edge1Index]; for (int edge2Index = 0; edge2Index < sourceEdges.Count && !found; edge2Index++) { if (edge2Index != edge1Index) // Skip the same edge { Edge edge2 = sourceEdges[edge2Index]; bool edge1Contained = Polygon.ContainsEdge(polygons[i], edge1); bool edge2Contained = Polygon.ContainsEdge(polygons[i], edge2); if (edge1Contained && edge2Contained) { if (!edges.Contains(edge1)) { edges.Add(edge1); } if (!edges.Contains(edge2)) { edges.Add(edge2); } found = true; } } } } } // Now process each polygon for (int i = 0; i < polygons.Length; i++) { Polygon polygon = polygons[i]; List <Edge> edgesOnPolygon = new List <Edge>(); for (int edgeIndex = 0; edgeIndex < edges.Count; edgeIndex++) { Edge edge = edges[edgeIndex]; if (Polygon.ContainsEdge(polygon, edge)) { edgesOnPolygon.Add(edge); } } if (edgesOnPolygon.Count == 1) { Vertex newVertex; // Add vertex if (!SplitPolygonAtEdge(polygon, edgesOnPolygon[0], out newVertex)) { Debug.LogError("Could not add vertex to adjacent polygon"); } } else if (edgesOnPolygon.Count == 2) { // Split into two Edge edge1 = edgesOnPolygon[0]; Edge edge2 = edgesOnPolygon[1]; // First split the shared polygon Vector3 edge1Center = edge1.GetCenterPoint(); Vector3 edge2Center = edge2.GetCenterPoint(); Vector3 thirdPoint = edge1Center + polygon.Plane.normal; Plane splitPlane = new Plane(edge1Center, edge2Center, thirdPoint); Polygon splitPolygon1; Polygon splitPolygon2; Vertex edge1Vertex; Vertex edge2Vertex; Polygon.SplitPolygon(polygon, out splitPolygon1, out splitPolygon2, out edge1Vertex, out edge2Vertex, splitPlane); newEdges.Add(new Edge(edge1Vertex, edge2Vertex)); newPolygons.Remove(polygon); newPolygons.Add(splitPolygon1); newPolygons.Add(splitPolygon2); } } finalPolygons = newPolygons.ToArray(); return(true); }