示例#1
0
 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);
 }
示例#2
0
        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}");
        }