Ejemplo n.º 1
0
        /// <summary>
        /// Entfernt die oberste Contraction von dem Contraction Stack und führt sie
        /// durch.
        /// </summary>
        /// <returns>
        /// true, wenn eine Contraction aus dem Stack entnommen wurde und durchgeführt
        /// wurde; andernfalls false, d.h. der Stack war schon leer.
        /// </returns>
        /// <remarks>
        /// Das Durchführen einer Contraction Operation hat immer das Pushen ihrer
        /// Umkehroperation auf den VertexSplit Stack zur Folge.
        /// </remarks>
        public bool PerformContraction()
        {
            if (Contractions.Count == 0)
            {
                return(false);
            }
            var contraction = Contractions.Pop();

            // 1. Vertex s wird an neue Position verschoben.
            Vertices[contraction.S] = new Vertex()
            {
                Position = contraction.Position
            };
            NumberOfFaces = contraction.faceOffset;
            NumberOfVertices--;
            uint t = (uint)NumberOfVertices;

            // 2. Alle Facetten von t auf s umbiegen.
            foreach (var f in incidentFaces[t])
            {
                bool remove = false;
                for (int i = 0; i < 3; i++)
                {
                    if (f[i] == contraction.S)
                    {
                        remove = true;
                    }
                    else if (f[i] == t)
                    {
                        f[i] = contraction.S;
                    }
                }
                if (remove)
                {
                    for (int c = 0; c < 3; c++)
                    {
                        incidentFaces[f[c]].Remove(f);
                    }
                }
                else
                {
                    incidentFaces[contraction.S].Add(f);
                }
            }
            incidentFaces.Remove(t);
            // 3. Umkehroperation der Contraction auf den VertexSplit Stack pushen.
            Splits.Push(contraction.VertexSplit);
            // Normalen aller betroffenen Vertices neuberechnen.
            ComputeNormals(incidentFaces[contraction.S]);
            return(true);
        }