/// <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); }