Ejemplo n.º 1
0
        /// <summary>
        /// Parsed eine VertexSplit Deklaration.
        /// </summary>
        /// <param name="l">
        /// Die Zeile, die die VertexSplit Deklaration enthält.
        /// </param>
        /// <returns>
        /// Der Vertex-Split Eintrag.
        /// </returns>
        /// <exception cref="InvalidOperationException">
        /// Die VertexSplit Deklaration ist ungültig.
        /// </exception>
        static VertexSplit ParseVertexSplit(string l)
        {
            var m = Regex.Match(l, @"^#vsplit\s+(\d+)\s+{(.*)}\s+{(.*)}\s+{(.*)}$");

            if (!m.Success)
            {
                throw new InvalidOperationException("Invalid vsplit: " + l);
            }
            var s = new VertexSplit()
            {
                S         = int.Parse(m.Groups[1].Value) - 1,
                SPosition = ParseVector(m.Groups[2].Value),
                TPosition = ParseVector(m.Groups[3].Value)
            };
            var faceIndices = m.Groups[4].Value;
            var matches     = Regex.Matches(faceIndices, @"\((-?\d+)\s+(-?\d+)\s+(-?\d+)\)");

            for (int i = 0; i < matches.Count; i++)
            {
                var _m = matches[i];
                if (!_m.Success)
                {
                    throw new InvalidOperationException("Invalid face index entry in vsplit: " + l);
                }
                var indices = new[] {
                    int.Parse(_m.Groups[1].Value) - 1,
                    int.Parse(_m.Groups[2].Value) - 1,
                    int.Parse(_m.Groups[3].Value) - 1
                };
                s.Faces.Add(new Triangle(indices));
            }
            return(s);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Führt eine Vertex-Split Operation auf der Mesh aus.
        /// </summary>
        /// <param name="split">
        /// Die Vertex-Split Operation, die ausgeführt werden soll.
        /// </param>
        /// <param name="incidentFaces">
        /// Eine Map die jedem Vertex der Mesh die Menge seiner inzidenten Facetten zuordnet.
        /// </param>
        void PerformVertexSplit(VertexSplit split, IDictionary <int, ISet <Triangle> > incidentFaces)
        {
            // 1. Vertex s wird an neue Position verschoben.
            Vertices[split.S].Position = split.SPosition;
            // 2. Vertex t wird neu zur Mesh hinzugefügt.
            Vertices.Add(new Vertex()
            {
                Position = split.TPosition
            });
            var t = Vertices.Count - 1;
            // 3. Alle Facetten von s, die ursprünglich t "gehört" haben, auf t zurückbiegen.
            var facesOfS = incidentFaces[split.S];
            var facesOfT = new HashSet <Triangle>();

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

            foreach (var f in facesOfS)
            {
                var _c = IsOriginalFaceOfT(t, f, split);
                if (_c < 0)
                {
                    continue;
                }
                f.Indices[_c] = t;
                facesOfT.Add(f);
                removeFromS.Add(f);
            }
            foreach (var r in removeFromS)
            {
                facesOfS.Remove(r);
            }
            // 4. 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 Triangle(f.Indices);
                Faces.Add(newFace);
                for (int c = 0; c < newFace.Indices.Length; c++)
                {
                    incidentFaces[newFace.Indices[c]].Add(newFace);
                }
            }
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Prüft, ob die angegebene Facette ursprünglich dem angegebenen Vertex "gehörte".
 /// </summary>
 /// <param name="t">
 /// Der Vertex.
 /// </param>
 /// <param name="face">
 /// Die Facette.
 /// </param>
 /// <param name="split">
 /// Die zugehörige VertexSplit Instanz.
 /// </param>
 /// <returns>
 /// Der Facettenindex, an dessen Stelle der ursprüngliche Vertex eingetragen war,
 /// oder -1 falls die Facette nicht ursprünglich dem Vertex "gehörte".
 /// </returns>
 /// <remarks>
 /// Diese Methode könnte schöner sein und sollte eigentlich in 2 Methoden aufgeteilt
 /// werden: Eine Methode zum Prüfen mit Rückgabewert Bool und eine Methode zum
 /// Abfragen des Index. Aus Geschwindigkeitsgründen ist dies aber ungünstig.
 /// </remarks>
 int IsOriginalFaceOfT(int t, Triangle face, VertexSplit split)
 {
     foreach (var f in split.Faces)
     {
         var index  = -1;
         var isface = true;
         for (int i = 0; i < 3; i++)
         {
             if (f.Indices[i] == t && face.Indices[i] == split.S)
             {
                 index = i;
             }
             else if (f.Indices[i] != face.Indices[i])
             {
                 isface = false;
             }
         }
         if (isface)
         {
             return(index);
         }
     }
     return(-1);
 }