示例#1
0
        /// <summary>
        /// Entfernt den obersten VertexSplit von dem VertexSplit Stack und führt ihn
        /// durch.
        /// </summary>
        /// <returns>
        /// true, wenn ein VertexSplit aus dem Stack entnommen wurde und durchgeführt
        /// wurde; andernfalls false, d.h. der Stack war schon leer.
        /// </returns>
        /// <remarks>
        /// Das Durchführen einer VertexSplit Operation hat immer das Pushen seiner
        /// Umkehroperation auf den Contraction Stack zur Folge.
        /// </remarks>
        public bool PerformVertexSplit()
        {
            if (Splits.Count == 0)
            {
                return(false);
            }
            if (incidentFaces == null)
            {
                incidentFaces = ComputeIncidentFaces();
                // Einmalig alle Vertexnormalen bestimmen.
//				ComputeNormals(_faces);
            }
            var split = Splits.Pop();

            // 1. Vertex s wird an neue Position verschoben.
            Vertices[split.S] = new Vertex()
            {
                Position = split.SPosition
            };
            // 2. Vertex t wird neu zur Mesh hinzugefügt.
            Vertices[NumberOfVertices] = new Vertex()
            {
                Position = split.TPosition
            };
            uint t = (uint)NumberOfVertices;

            // 3. Umkehroperation des VertexSplits auf Contraction Stack pushen.
            Contractions.Push(new Contraction()
            {
                S           = split.S,
                Position    = Vertices[split.S].Position, faceOffset = NumberOfFaces,
                VertexSplit = split
            });
            NumberOfVertices++;
            // 4. Alle Facetten von s, die ursprünglich t "gehört" haben, auf t zurückbiegen.
            var facesOfS = incidentFaces[split.S];
            var facesOfT = new HashSet <Face>();

            incidentFaces.Add(t, facesOfT);
            var removeFromS = new HashSet <Face>();

            foreach (var f in facesOfS)
            {
                var _c = IsOriginalFaceOfT(t, f, split);
                if (_c < 0)
                {
                    continue;
                }
                f[_c] = t;
                facesOfT.Add(f);
                removeFromS.Add(f);
            }
            foreach (var r in removeFromS)
            {
                facesOfS.Remove(r);
            }
            // 5. Etwaige gemeinsame Facetten von s und t der Mesh neu hinzufügen.
            foreach (var f in split.Faces)
            {
                if (!f.Indices.Contains(split.S))
                {
                    continue;
                }
                var newFace = new Face(f.Indices, FlatFaces, NumberOfFaces * 3);
                NumberOfFaces++;
                for (int c = 0; c < 3; c++)
                {
                    incidentFaces[newFace[c]].Add(newFace);
                }
            }
            // Normalen aller betroffenen Vertices neuberechnen.
            ComputeNormals(incidentFaces[split.S].Union(incidentFaces[t]));
            return(true);
        }