Пример #1
0
 public Node(GraphArray <T> graph)
 {
     m_Graph  = graph;
     m_Begin  = uint.MaxValue;
     m_End    = uint.MaxValue;
     m_Marker = false;
 }
 public void UnmarkNodes(GraphArray <Triangle> G)
 {
     foreach (GraphArray <Triangle> .Node t in G)
     {
         t.Marked = false;
     }
 }
Пример #3
0
        private void MarkTriAsTaken(uint i)
        {
            //Mark the triangle node
            m_Triangles[i].Marked = true;

            //Remove triangle from priority queue if it isn't yet
            if (!m_TriHeap.Removed(i))
            {
                m_TriHeap.Erase(i);
            }

            //Adjust the degree of available neighbour triangles
            GraphArray <Triangle> .Node Node = m_Triangles[i];
            for (uint x = Node.m_Begin; x < Node.m_End; x++)
            {
                GraphArray <Triangle> .Arc Link = Node.Arcs[(int)x];

                uint j = Link.Terminal.m_Elem.m_Index;
                if (!m_Triangles[j].Marked && !m_TriHeap.Removed(j))
                {
                    uint NewDegree = m_TriHeap[j];
                    NewDegree = NewDegree - 1;
                    m_TriHeap.Update(j, NewDegree);

                    //Update the candidate list if cache is enabled
                    if (Cache && NewDegree > 0)
                    {
                        m_Candidates.Add(j);
                    }
                }
            }
        }
Пример #4
0
        private void BuildStrip(Strip Strip)
        {
            uint Start = Strip.Start;

            bool     ClockWise = false;
            TriOrder Order     = Strip.Order;

            //Create a new strip
            Primitive p = new Primitive(PrimType.TriangleStrip);

            m_PrimitivesVector.Add(p);
            AddTriangle(m_Triangles[Start].m_Elem, Order, true);
            MarkTriAsTaken(Start);

            //Loop while we can further extend the strip
            GraphArray <Triangle> .Node Node = m_Triangles[Start];

            for (uint Size = 1; Size < Strip.Size; Size++)
            {
                GraphArray <Triangle> .Arc Link = LinkToNeighbour(Node, ClockWise, ref Order, true);

                Debug.Assert(Link != null);

                //Go to the next triangle
                Node = Link.Terminal;
                MarkTriAsTaken(Node.m_Elem.m_Index);
                ClockWise = !ClockWise;
            }
        }
Пример #5
0
        // Optimized (overloaded) functions
        public void Swap(GraphArray <T> Right)
        {
            List <Node> n = m_Nodes;
            List <Arc>  a = m_Arcs;

            m_Nodes       = Right.m_Nodes;
            m_Arcs        = Right.m_Arcs;
            Right.m_Nodes = n;
            Right.m_Arcs  = a;
        }
 void LinkNeighbours(GraphArray <Triangle> Triangles, List <TriEdge> EdgeMap, TriEdge Edge)
 {
     //Find the first edge equal to Edge
     //See if there are any other edges that are equal
     //(if so, it means that more than 2 triangles are sharing the same edge,
     //which is unlikely but not impossible)
     for (int i = BinarySearch <TriEdge>(EdgeMap, Edge, EdgeComp);
          i < EdgeMap.Count && Edge == EdgeMap[i]; i++)
     {
         Triangles.InsertArc(Edge.TriPos, EdgeMap[i].TriPos);
     }
     //Note: degenerated triangles will also point themselves as neighbour triangles
 }
Пример #7
0
        private Strip ExtendToStrip(uint Start, TriOrder Order)
        {
            TriOrder StartOrder = Order;

            m_CurrentNodes = new List <ushort>();
            _checkNodes    = true;

            //Begin a new strip
            Triangle tri = m_Triangles[Start].m_Elem;

            tri.SetStripID(++m_StripID);
            AddTriangle(tri, Order, false);

            TryAddNode(tri.A);
            TryAddNode(tri.B);
            TryAddNode(tri.C);

            uint Size      = 1;
            bool ClockWise = false;

            //Loop while we can further extend the strip
            for (uint i = Start; i < m_Triangles.Count && (!Cache || Size + 2 < CacheSize); Size++)
            {
                GraphArray <Triangle> .Node Node = m_Triangles[i];
                GraphArray <Triangle> .Arc  Link = LinkToNeighbour(Node, ClockWise, ref Order, false);

                // Is it the end of the strip?
                if (Link == null)
                {
                    Size--;
                    i = m_Triangles.Count;
                }
                else
                {
                    i = (Node = Link.Terminal).m_Elem.m_Index;

                    Node.m_Elem.SetStripID(m_StripID);
                    ClockWise = !ClockWise;
                }
            }

            _checkNodes = false;
            m_CurrentNodes.Clear();

            return(new Strip(Start, StartOrder, Size));
        }
        public TriStripper(uint[] TriIndices, ushort[] NodeIds, int[] ImpTable)
        {
            m_ImpTable         = ImpTable;
            m_Nodes            = NodeIds;
            m_Triangles        = new GraphArray <Triangle>((uint)TriIndices.Length / 3);
            m_StripID          = 0;
            m_FirstRun         = true;
            m_PrimitivesVector = new List <Primitive>();
            m_TriHeap          = new HeapArray(CompareType.Less);
            m_Candidates       = new List <uint>();
            m_Cache            = new CacheSimulator();
            m_BackCache        = new CacheSimulator();

            SetCacheSize();
            SetMinStripSize();
            SetBackwardSearch();
            SetPushCacheHits();

            MakeConnectivityGraph(m_Triangles, TriIndices);
        }
Пример #9
0
        private GraphArray <Triangle> .Arc BackLinkToNeighbour(GraphArray <Triangle> .Node Node, bool ClockWise,
                                                               ref TriOrder Order)
        {
            TriangleEdge Edge = FirstEdge(Node.m_Elem, Order);

            for (uint i = Node.m_Begin; i < Node.m_End; i++)
            {
                GraphArray <Triangle> .Arc Link = Node.Arcs[(int)i];

                //Get the reference to the possible previous triangle
                Triangle Tri = Link.Terminal.m_Elem;

                //Check whether it's already been used
                if (Tri.StripID != m_StripID && !Link.Terminal.Marked)
                {
                    //Does the current candidate triangle match the required position for the strip?
                    if (Edge.B == Tri.A && Edge.A == Tri.B && TryAddNode(Tri.C))
                    {
                        Order = ClockWise ? TriOrder.CAB : TriOrder.BCA;
                        BackAddIndex(Tri.C);
                        return(Link);
                    }

                    if (Edge.B == Tri.B && Edge.A == Tri.C && TryAddNode(Tri.A))
                    {
                        Order = ClockWise ? TriOrder.ABC : TriOrder.CAB;
                        BackAddIndex(Tri.A);
                        return(Link);
                    }

                    if (Edge.B == Tri.C && Edge.A == Tri.A && TryAddNode(Tri.B))
                    {
                        Order = ClockWise ? TriOrder.BCA : TriOrder.ABC;
                        BackAddIndex(Tri.B);
                        return(Link);
                    }
                }
            }

            return(null);
        }
        void MakeConnectivityGraph(GraphArray <Triangle> Triangles, uint[] Indices)
        {
            Debug.Assert(Triangles.Count == (Indices.Length / 3));

            //Fill the triangle data
            for (int i = 0; i < Triangles.Count; i++)
            {
                Triangles[(uint)i].m_Elem = new Triangle(
                    Indices[i * 3 + 0],
                    Indices[i * 3 + 1],
                    Indices[i * 3 + 2])
                {
                    m_Index = (uint)i
                }
            }
            ;

            //Build an edge lookup table
            List <TriEdge> EdgeMap = new List <TriEdge>();

            for (uint i = 0; i < Triangles.Count; i++)
            {
                Triangle Tri = Triangles[i].m_Elem;
                EdgeMap.Add(new TriEdge(Tri.A, Tri.B, i));
                EdgeMap.Add(new TriEdge(Tri.B, Tri.C, i));
                EdgeMap.Add(new TriEdge(Tri.C, Tri.A, i));
            }
            EdgeMap.Sort(EdgeComp);

            //Link neighbour triangles together using the lookup table
            for (uint i = 0; i < Triangles.Count; i++)
            {
                Triangle Tri = Triangles[i].m_Elem;
                LinkNeighbours(Triangles, EdgeMap, new TriEdge(Tri.B, Tri.A, i));
                LinkNeighbours(Triangles, EdgeMap, new TriEdge(Tri.C, Tri.B, i));
                LinkNeighbours(Triangles, EdgeMap, new TriEdge(Tri.A, Tri.C, i));
            }
        }
        private Strip BackExtendToStrip(uint Start, TriOrder Order, bool ClockWise)
        {
            m_CurrentNodes = new List <ushort>();
            _checkNodes    = true;

            //Begin a new strip
            Triangle tri = m_Triangles[Start].m_Elem;
            uint     b   = LastEdge(tri, Order).B;

            if (TryAddNode(b))
            {
                tri.SetStripID(++m_StripID);
                BackAddIndex(b);
            }
            else
            {
                _checkNodes = false;
                m_CurrentNodes.Clear();
                return(null);
            }

            uint Size = 1;

            GraphArray <Triangle> .Node Node = null;

            //Loop while we can further extend the strip
            for (uint i = Start; !Cache || ((Size + 2) < CacheSize); Size++)
            {
                Node = m_Triangles[i];
                var Link = BackLinkToNeighbour(Node, ClockWise, ref Order);

                //Is it the end of the strip?
                if (Link == null)
                {
                    break;
                }
                else
                {
                    i = (Node = Link.Terminal).m_Elem.m_Index;

                    Node.m_Elem.SetStripID(m_StripID);
                    ClockWise = !ClockWise;
                }
            }

            _checkNodes = false;
            m_CurrentNodes.Clear();

            //We have to start from a counterclockwise triangle.
            //Simply return an empty strip in the case where the first triangle is clockwise.
            //Even though we could discard the first triangle and start from the next counterclockwise triangle,
            //this often leads to more lonely triangles afterward.
            if (ClockWise)
            {
                return(null);
            }

            if (Cache)
            {
                m_Cache.Merge(m_BackCache, Size);
                m_BackCache.Reset();
            }

            return(new Strip(Node.m_Elem.m_Index, Order, Size));
        }