public PlanarEdgePair(PlanarEdge edge1, PlanarEdge edge2) { Edge1 = edge1; Edge2 = edge2; CommonVertex = edge1.GetCommonVertex(edge2); TotalAngle = PlanarEdge.CalculateAngleBetween(edge1, edge2); AngleDiff = Vector3.AngleBetween(edge1.OutlineDirection, edge2.OutlineDirection); OutlineBisector = Vector3.Avg(edge1.OutlineDirection, edge2.OutlineDirection); }
public static void GenerateOutlines(IEnumerable <Triangle> triangles, float breakAngle) { float breakAngleRad = breakAngle / 180f * fPI; var triangleList = triangles.ToList(); var sw = Stopwatch.StartNew(); var hardEdgeDict = new HardEdgeDictionary(); hardEdgeDict.Initialize(triangleList, breakAngle); sw.Stop(); Console.WriteLine($"Calculate Hard Edges => {sw.Elapsed}"); sw.Restart(); //var tp1 = new Vector3(-0.254556f, 0.254556f, 0f); //var tp2 = new Vector3(-0.332604f, 0.137772f, 0f); //var tp3 = new Vector3(-0.295648f, 0.122464f, 0f); foreach (var triangle in triangleList) { var facePlane = new Plane(triangle.GetCenter(), triangle.Normal); var planarEdges = CalculatePlanarEdges(triangle, hardEdgeDict); var projectedEdges = new List <ProjectedEdge>(); //if (triangle.ContainsVertex(tp1) && triangle.ContainsVertex(tp2) && triangle.ContainsVertex(tp3)) //{ //} foreach (var vert in triangle.Vertices) { var edgesConnectedToVertex = planarEdges.Where(x => x.Contains(vert.Position)).ToList(); // remove edges that must be intersected with edges that are not connected to the current vertex if (edgesConnectedToVertex.Any(x => x.IsUsedInIntersection)) { var interEdges = edgesConnectedToVertex.Where(x => x.IsUsedInIntersection).ToList(); foreach (var edge in interEdges) { if (!edgesConnectedToVertex.Any(e => edge.IsConnectedTo(e))) { edgesConnectedToVertex.Remove(edge); } } } var projections = edgesConnectedToVertex.Select(x => x.ProjectTriangle(triangle, vert.Position)).ToList(); //if (vert.Position.Equals(new Vector3(-0.254556f, 0.254556f, 0f), 0.001f) || // vert.Position.Equals(new Vector3(3.85456f, 0.254556f, -2f), 0.001f) // //&& triangle.Vertices.Any(v=>v.Position.Y == 2.07874f) // //&& triangle.Normal.Equals(Vector3.UnitZ, 0.8f) // ) //{ //} projections.RemoveAll(p => p.IsOutsideTriangle); if (projections.Count(p => p.IsDeadEnd) >= 2) { var deadEnds = projections.Where(p => p.IsDeadEnd); var triCenter = triangle.GetCenter(); var projectionToKeep = deadEnds.OrderBy(p => Vector3.Distance(vert.Position + p.PlanarEdge.OutlineDirection, triCenter)).First(); projections.RemoveAll(p => p.IsDeadEnd && p != projectionToKeep); } if (projections.Count == 2) { var edge1 = projections[0].PlanarEdge; var edge2 = projections[1].PlanarEdge; var projection1 = projections[0]; var projection2 = projections[1]; if (edge1.Colinear(edge2) && !(projection1.NeedsToBeClipped || projection2.NeedsToBeClipped)) { projectedEdges.Add(projection1); } else { bool mustIntersect = false; var edgeLinkInfo = edge1.GetConnectionInfo(edge2); if (edgeLinkInfo != null) { mustIntersect = edgeLinkInfo.IsObtuse; } else { var angleBetweenEdges = PlanarEdge.CalculateAngleBetween(edge1, edge2); mustIntersect = angleBetweenEdges >= fPI; } if (mustIntersect) { projection1.NeedsToBeClipped = true; projection2.NeedsToBeClipped = true; } projection1.CombineWith = projection2; projection2.CombineWith = projection1; projectedEdges.Add(projection1); projectedEdges.Add(projection2); } } else if (projections.Count == 1) { var projection = projections[0]; projectedEdges.Add(projection); if (projection.NeedsToBeClipped) { projectedEdges.Add(CreateClippingEdge(projection, vert.Position, facePlane)); } } else if (projections.Count > 2) { } } if (projectedEdges.Any()) { int pairIdx = 0; bool combineStandAlones = projectedEdges.Count() > 3; while (pairIdx < 3 && projectedEdges.Any()) { var projection = projectedEdges.OrderByDescending(x => x.CombineWith != null) .FirstOrDefault(); projectedEdges.Remove(projection); var nextEdge = projection.CombineWith; //if (combineStandAlones && nextEdge == null) //{ // nextEdge = projectedEdges // .Where(x => !projection.NeedsToBeClipped && x.IntersectWith == null) // .FirstOrDefault(); //} if (nextEdge != null) { projectedEdges.Remove(nextEdge); } SetOutlineCoords(triangle, pairIdx++, projection, nextEdge); } } } sw.Stop(); Console.WriteLine($"Calculate Outlines => {sw.Elapsed}"); }