Ejemplo n.º 1
0
            //public bool IsOtherEndClipped(PlanarEdge linkedEdge)
            //{
            //    var commonVert = GetCommonVertex(linkedEdge);
            //    if (PrevEdgeInfo != null && PrevEdgeInfo.CommonVertex != commonVert)
            //        return PrevEdgeInfo.IsObtuse;
            //    if (NextEdgeInfo != null && NextEdgeInfo.CommonVertex != commonVert)
            //        return NextEdgeInfo.IsObtuse;
            //    return false;
            //}

            public static float CalculateAngleBetween(PlanarEdge edge1, PlanarEdge edge2)
            {
                Vector3 commonVert;

                if (edge2.Contains(edge1.P1))
                {
                    commonVert = edge1.P1;
                }
                else if (edge2.Contains(edge1.P2))
                {
                    commonVert = edge1.P2;
                }
                else
                {
                    return(0);
                }

                var opp1 = edge1.GetOppositeVertex(commonVert);
                var dir1 = (opp1 - commonVert).Normalized();

                var avgNormal = Vector3.Avg(edge1.OutlineDirection, edge2.OutlineDirection).Normalized();

                var edgeAngleDiff = Vector3.AngleBetween(avgNormal, dir1);

                return(edgeAngleDiff * 2f);
            }
Ejemplo n.º 2
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);
 }
Ejemplo n.º 3
0
            public bool Colinear(PlanarEdge other)
            {
                if (!(other.Contains(P1) || other.Contains(P2)))
                {
                    return(false);
                }

                float angleDiff = Vector3.AngleBetween(Direction, other.Direction);

                return(float.IsNaN(angleDiff) || angleDiff < 0.08);
            }
Ejemplo n.º 4
0
 public PlanarEdge GetOtherEdge(PlanarEdge edge)
 {
     if (Edge1 == edge)
     {
         return(Edge2);
     }
     if (Edge2 == edge)
     {
         return(Edge1);
     }
     return(null);
 }
Ejemplo n.º 5
0
 public Vector3 GetCommonVertex(PlanarEdge otherEdge)
 {
     if (otherEdge.Contains(P1))
     {
         return(P1);
     }
     else if (otherEdge.Contains(P2))
     {
         return(P2);
     }
     return(Vector3.Empty);
 }
Ejemplo n.º 6
0
            public PlanarEdgePair GetConnectionInfo(PlanarEdge otherEdge)
            {
                if (PrevEdgeInfo?.ContainsEdge(otherEdge) ?? false)
                {
                    return(PrevEdgeInfo);
                }

                if (NextEdgeInfo?.ContainsEdge(otherEdge) ?? false)
                {
                    return(NextEdgeInfo);
                }

                return(null);
            }
Ejemplo n.º 7
0
            public bool IsConnectedTo(PlanarEdge other)
            {
                if (other == this)
                {
                    return(false);
                }

                if (NextEdgeInfo != null && NextEdgeInfo.ContainsEdge(other))
                {
                    return(true);
                }
                if (PrevEdgeInfo != null && PrevEdgeInfo.ContainsEdge(other))
                {
                    return(true);
                }

                return(false);
            }
Ejemplo n.º 8
0
            public void ValidateValues()
            {
                var minPos = Vector2.Min(P1, P2, P3);
                var maxPos = Vector2.Max(P1, P2, P3);

                if (minPos.Y < 0 && Math.Abs(minPos.Y) > LineThickness)
                {
                    NeedsToBeClipped = true;
                }

                if (maxPos.Y < LineThickness && (maxPos.Y - minPos.Y) > LineThickness)
                {
                    IsOutsideTriangle = true;
                }

                //Dead End
                if (!PlanarEdge.IsVertexLinked(TargetVertex))
                {
                    //TO IMPROVE
                    IsDeadEnd        = true;
                    NeedsToBeClipped = true;
                }
            }
Ejemplo n.º 9
0
        static ProjectedEdge CreateClippingEdge(ProjectedEdge baseEdge, Vector3 edgeEnd, Plane facePlane)
        {
            var triangle   = baseEdge.PlanarEdge.Face;
            var oppVert    = baseEdge.PlanarEdge.GetOppositeVertex(edgeEnd);
            var outlineDir = (edgeEnd - oppVert).Normalized();

            var interEdge = new HardEdge(
                edgeEnd,
                edgeEnd + baseEdge.PlanarEdge.OutlineDirection,
                facePlane.Normal,
                outlineDir);

            interEdge.CorrectOrder();
            var planarEndEdge  = new PlanarEdge(interEdge, triangle, facePlane);
            var interProjected = planarEndEdge.ProjectTriangle(triangle, edgeEnd);

            interProjected.NeedsToBeClipped = true;

            baseEdge.CombineWith       = interProjected;
            interProjected.CombineWith = baseEdge;

            return(interProjected);
        }
Ejemplo n.º 10
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}");
        }
Ejemplo n.º 11
0
 public bool ContainsEdge(PlanarEdge edge)
 {
     return(Edge1 == edge || Edge2 == edge);
 }