Esempio n. 1
0
        /// <summary>
        /// Erzeugt und speichert einen VertexSplit Eintrag für das angegebene Paar.
        /// </summary>
        /// <param name="p">
        /// Das Paar für welches ein VertexSplit Eintrag erstellt werden soll.
        /// </param>
        void AddSplitRecord(Pair p)
        {
            contractionIndices.Push(p.Vertex2);
            var split = new VertexSplit()
            {
                S         = p.Vertex1, SPosition = vertices[p.Vertex1],
                TPosition = vertices[p.Vertex2]
            };

            foreach (var f in incidentFaces[p.Vertex2])
            {
                // -1 wird später durch eigentlichen Index ersetzt, wenn dieser bekannt
                // ist.
                split.Faces.Add(new Triangle(
                                    f.Indices[0] == p.Vertex2 ? -1 : f.Indices[0],
                                    f.Indices[1] == p.Vertex2 ? -1 : f.Indices[1],
                                    f.Indices[2] == p.Vertex2 ? -1 : f.Indices[2]));
            }
            splits.Push(split);
        }
        private void Contract(int targetTriangles, IProgressListener listener = null)
        {
            SelectValidPairs();

            if (listener != null)
            {
                listener.OnStarted("Compacting");
            }

            int totalTriangles = m_Faces.Count - targetTriangles;
            int currentTriangle = 0;
            while (m_Faces.Count > targetTriangles)
            {
                if (listener != null)
                {
                    listener.OnStep(currentTriangle, totalTriangles);
                }
                ++currentTriangle;
                double minError = (double)int.MaxValue;

                //KeyValuePair<VertexPair, double> min;
                VertexPair minPair = new VertexPair() { First = 0, Second = 0 };

                foreach (KeyValuePair<VertexPair, double> e in m_Errors)
                {
                    if (e.Value < minError)
                    {
                        minError = e.Value;
                        minPair = e.Key;
                    }
                }

                Vector3 error;
                ComputeError(minPair.First, minPair.Second, out error);

#if false
                VertexSplit split = new VertexSplit();

                //var fv

                split.First.Position = m_Vertices[minPair.First].Position;
                split.Second.Position = m_Vertices[minPair.Second].Position;
                split.Target.Position = error;
                m_Splits.Add(split);
#endif
                var vertex = m_Vertices[minPair.First];
                vertex.Position = error;

                m_Quadrics[minPair.First] = m_Quadrics[minPair.First] + m_Quadrics[minPair.Second];

                for (int i = m_Faces.Count - 1; i != 0; )
                {
                    var face = m_Faces[i];

                    for (int j = 0; j < 3; ++j)
                    {
                        if (face[j] == minPair.Second)
                        {
                            if (face[0] == minPair.First || face[1] == minPair.First || face[2] == minPair.First)
                            {
                                m_Faces.Remove(face);
                            }
                            else
                            {
                                face[j] = minPair.First;
                            }
                            --i;
                            break;
                        }
                        else if (j == 2)
                        {
                            --i;
                        }
                    }
                }

                m_Vertices.Remove(minPair.Second);

                KeyValuePair<VertexPair, double> pair;

#if false
                for (int iter = m_Errors.Count - 1; iter != 0; )
                {
                    pair = m_Errors.ElementAt(iter);

                    if (pair.Key.First == minPair.Second && pair.Key.Second != minPair.First)
                    {
                        m_Errors.Remove(m_Errors.ElementAt(iter).Key);

                        m_Errors.Add(
                            new VertexPair() { First = Math.Min(minPair.First, pair.Key.Second), Second = Math.Max(minPair.First, pair.Key.Second) },
                            0.0);
                        --iter;
                    }
                    else if (pair.Key.Second == minPair.Second && pair.Key.First != minPair.First)
                    {
                        m_Errors.Remove(m_Errors.ElementAt(iter).Key);

                        m_Errors.Add(
                            new VertexPair() { First = Math.Min(minPair.First, pair.Key.First), Second = Math.Max(minPair.First, pair.Key.First) },
                            0.0);
                        --iter;
                    }
                    else
                    {
                        --iter;
                    }
                }
#else
                for (int it = 0; it < m_Errors.Count; ++it)
                {
                    pair = m_Errors.ElementAt(it);

                    if (pair.Key.First == minPair.Second && pair.Key.Second != minPair.First)
                    {
                        m_Errors.Remove(m_Errors.ElementAt(it).Key);

                        var key = new VertexPair()
                        {
                            First = Math.Min(minPair.First, pair.Key.Second),
                            Second = Math.Max(minPair.First, pair.Key.Second)
                        };

                        if (!m_Errors.ContainsKey(key))
                        {
                            m_Errors.Add(
                                key,
                                0.0);
                        }
                    }
                    else if (pair.Key.Second == minPair.Second && pair.Key.First != minPair.First)
                    {
                        m_Errors.Remove(m_Errors.ElementAt(it).Key);

                        var key = new VertexPair()
                        {
                            First = Math.Min(minPair.First, pair.Key.First),
                            Second = Math.Max(minPair.First, pair.Key.First)
                        };

                        if (!m_Errors.ContainsKey(key))
                        {
                            m_Errors.Add(
                                key,
                                0.0);
                        }
                    }
                }
#endif
                m_Errors.Remove(minPair);

                for (int it = 0; it < m_Errors.Count; ++it)
                {
                    var key = m_Errors.ElementAt(it).Key;

                    if (key.First == minPair.First)
                    {
                        m_Errors[key] = ComputeError(minPair.First, key.Second);
                    }

                    if (key.Second == minPair.First)
                    {
                        m_Errors[key] = ComputeError(minPair.First, key.First);
                    }
                }
                /*foreach (var e in m_Errors)
                {
                    var p = e.Key;
                    if (p.First == minPair.First)
                    {
                        m_Errors[p] = ComputeError(minPair.First, p.Second);
                    }

                    if (p.Second == minPair.First)
                    {
                        m_Errors[p] = ComputeError(minPair.First, p.First);
                    }
                }*/

            }
            if (listener != null)
            {
                listener.OnComplete("Compacting");
            }
        }
Esempio n. 3
0
        private void Contract(int targetTriangles, IProgressListener listener = null)
        {
            SelectValidPairs();

            if (listener != null)
            {
                listener.OnStarted("Compacting");
            }

            int totalTriangles  = m_Faces.Count - targetTriangles;
            int currentTriangle = 0;

            while (m_Faces.Count > targetTriangles)
            {
                if (listener != null)
                {
                    listener.OnStep(currentTriangle, totalTriangles);
                }
                ++currentTriangle;
                double minError = (double)int.MaxValue;

                //KeyValuePair<VertexPair, double> min;
                VertexPair minPair = new VertexPair()
                {
                    First = 0, Second = 0
                };

                foreach (KeyValuePair <VertexPair, double> e in m_Errors)
                {
                    if (e.Value < minError)
                    {
                        minError = e.Value;
                        minPair  = e.Key;
                    }
                }

                Vector3 error;
                ComputeError(minPair.First, minPair.Second, out error);

#if false
                VertexSplit split = new VertexSplit();

                //var fv

                split.First.Position  = m_Vertices[minPair.First].Position;
                split.Second.Position = m_Vertices[minPair.Second].Position;
                split.Target.Position = error;
                m_Splits.Add(split);
#endif
                var vertex = m_Vertices[minPair.First];
                vertex.Position = error;

                m_Quadrics[minPair.First] = m_Quadrics[minPair.First] + m_Quadrics[minPair.Second];

                for (int i = m_Faces.Count - 1; i != 0;)
                {
                    var face = m_Faces[i];

                    for (int j = 0; j < 3; ++j)
                    {
                        if (face[j] == minPair.Second)
                        {
                            if (face[0] == minPair.First || face[1] == minPair.First || face[2] == minPair.First)
                            {
                                m_Faces.Remove(face);
                            }
                            else
                            {
                                face[j] = minPair.First;
                            }
                            --i;
                            break;
                        }
                        else if (j == 2)
                        {
                            --i;
                        }
                    }
                }

                m_Vertices.Remove(minPair.Second);

                KeyValuePair <VertexPair, double> pair;

#if false
                for (int iter = m_Errors.Count - 1; iter != 0;)
                {
                    pair = m_Errors.ElementAt(iter);

                    if (pair.Key.First == minPair.Second && pair.Key.Second != minPair.First)
                    {
                        m_Errors.Remove(m_Errors.ElementAt(iter).Key);

                        m_Errors.Add(
                            new VertexPair()
                        {
                            First = Math.Min(minPair.First, pair.Key.Second), Second = Math.Max(minPair.First, pair.Key.Second)
                        },
                            0.0);
                        --iter;
                    }
                    else if (pair.Key.Second == minPair.Second && pair.Key.First != minPair.First)
                    {
                        m_Errors.Remove(m_Errors.ElementAt(iter).Key);

                        m_Errors.Add(
                            new VertexPair()
                        {
                            First = Math.Min(minPair.First, pair.Key.First), Second = Math.Max(minPair.First, pair.Key.First)
                        },
                            0.0);
                        --iter;
                    }
                    else
                    {
                        --iter;
                    }
                }
#else
                for (int it = 0; it < m_Errors.Count; ++it)
                {
                    pair = m_Errors.ElementAt(it);

                    if (pair.Key.First == minPair.Second && pair.Key.Second != minPair.First)
                    {
                        m_Errors.Remove(m_Errors.ElementAt(it).Key);

                        var key = new VertexPair()
                        {
                            First  = Math.Min(minPair.First, pair.Key.Second),
                            Second = Math.Max(minPair.First, pair.Key.Second)
                        };

                        if (!m_Errors.ContainsKey(key))
                        {
                            m_Errors.Add(
                                key,
                                0.0);
                        }
                    }
                    else if (pair.Key.Second == minPair.Second && pair.Key.First != minPair.First)
                    {
                        m_Errors.Remove(m_Errors.ElementAt(it).Key);

                        var key = new VertexPair()
                        {
                            First  = Math.Min(minPair.First, pair.Key.First),
                            Second = Math.Max(minPair.First, pair.Key.First)
                        };

                        if (!m_Errors.ContainsKey(key))
                        {
                            m_Errors.Add(
                                key,
                                0.0);
                        }
                    }
                }
#endif
                m_Errors.Remove(minPair);

                for (int it = 0; it < m_Errors.Count; ++it)
                {
                    var key = m_Errors.ElementAt(it).Key;

                    if (key.First == minPair.First)
                    {
                        m_Errors[key] = ComputeError(minPair.First, key.Second);
                    }

                    if (key.Second == minPair.First)
                    {
                        m_Errors[key] = ComputeError(minPair.First, key.First);
                    }
                }

                /*foreach (var e in m_Errors)
                 * {
                 *  var p = e.Key;
                 *  if (p.First == minPair.First)
                 *  {
                 *      m_Errors[p] = ComputeError(minPair.First, p.Second);
                 *  }
                 *
                 *  if (p.Second == minPair.First)
                 *  {
                 *      m_Errors[p] = ComputeError(minPair.First, p.First);
                 *  }
                 * }*/
            }
            if (listener != null)
            {
                listener.OnComplete("Compacting");
            }
        }