Esempio n. 1
0
        protected virtual void InitializeQueue()
        {
            int NE = mesh.EdgeCount;

            Nodes     = new QEdge[2 * NE];                      // [RMS] do we need this many?
            NodePool  = new MemoryPool <QEdge>(NE);
            EdgeQueue = new g3ext.FastPriorityQueue <QEdge>(NE);

            int  cur_eid = start_edges();
            bool done    = false;

            do
            {
                if (mesh.IsEdge(cur_eid))
                {
                    Index2i ev = mesh.GetEdgeV(cur_eid);

                    QuadricError Q   = new QuadricError(ref vertQuadrics[ev.a], ref vertQuadrics[ev.b]);
                    Vector3d     opt = OptimalPoint(Q, ev.a, ev.b);
                    double       err = Q.Evaluate(opt);

                    QEdge ee = NodePool.Allocate();
                    ee.Initialize(cur_eid, Q, opt);
                    Nodes[cur_eid] = ee;
                    EdgeQueue.Enqueue(ee, (float)err);
                }
                cur_eid = next_edge(cur_eid, out done);
            } while (done == false);
        }
Esempio n. 2
0
        protected virtual void InitializeQueue()
        {
            int NE     = mesh.EdgeCount;
            int MaxEID = mesh.MaxEdgeID;

            EdgeQuadrics = new QEdge[MaxEID];
            EdgeQueue    = new IndexPriorityQueue(MaxEID);
            float[] edgeErrors = new float[MaxEID];

            // vertex quadrics can be computed in parallel
            gParallel.BlockStartEnd(0, MaxEID - 1, (start_eid, end_eid) => {
                for (int eid = start_eid; eid <= end_eid; eid++)
                {
                    if (mesh.IsEdge(eid))
                    {
                        Index2i ev        = mesh.GetEdgeV(eid);
                        QuadricError Q    = new QuadricError(ref vertQuadrics[ev.a], ref vertQuadrics[ev.b]);
                        Vector3d opt      = OptimalPoint(eid, ref Q, ev.a, ev.b);
                        edgeErrors[eid]   = (float)Q.Evaluate(ref opt);
                        EdgeQuadrics[eid] = new QEdge(eid, ref Q, ref opt);
                    }
                }
            });

            // sorted pq insert is faster, so sort edge errors array and index map
            int[] indices = new int[MaxEID];
            for (int i = 0; i < MaxEID; ++i)
            {
                indices[i] = i;
            }
            Array.Sort(edgeErrors, indices);

            // now do inserts
            for (int i = 0; i < edgeErrors.Length; ++i)
            {
                int eid = indices[i];
                if (mesh.IsEdge(eid))
                {
                    QEdge edge = EdgeQuadrics[eid];
                    EdgeQueue.Insert(edge.eid, edgeErrors[i]);
                }
            }

            /*
             * // previous code that does unsorted insert. This is marginally slower, but
             * // might get even slower on larger meshes? have only tried up to about 350k.
             * // (still, this function is not the bottleneck...)
             * int cur_eid = start_edges();
             * bool done = false;
             * do {
             *  if (mesh.IsEdge(cur_eid)) {
             *      QEdge edge = EdgeQuadrics[cur_eid];
             *      double err = errList[cur_eid];
             *      EdgeQueue.Enqueue(cur_eid, (float)err);
             *  }
             *  cur_eid = next_edge(cur_eid, out done);
             * } while (done == false);
             */
        }
Esempio n. 3
0
        public virtual void DoReduce()
        {
            if (mesh.TriangleCount == 0)                // badness if we don't catch this...
            {
                return;
            }

            begin_pass();

            begin_setup();
            InitializeVertexQuadrics();
            InitializeQueue();
            end_setup();

            begin_ops();

            begin_collapse();
            while (EdgeQueue.Count > 0 && mesh.TriangleCount > TargetTriangleCount)
            {
                COUNT_ITERATIONS++;
                QEdge cur = EdgeQueue.Dequeue();
                Nodes[cur.eid] = null;
                NodePool.Return(cur);
                if (!mesh.IsEdge(cur.eid))
                {
                    continue;
                }
                Index2i ev = mesh.GetEdgeV(cur.eid);

                int           vKept;
                ProcessResult result = CollapseEdge(cur.eid, cur.collapse_pt, out vKept);
                if (result == ProcessResult.Ok_Collapsed)
                {
                    vertQuadrics[vKept] = cur.q;
                    UpdateNeighbours(vKept);
                }
            }
            end_collapse();
            end_ops();

            Reproject();

            end_pass();
        }
Esempio n. 4
0
 // update queue weight for each edge in vertex one-ring
 protected virtual void UpdateNeighbours(int vid)
 {
     foreach (int eid in mesh.VtxEdgesItr(vid))
     {
         Index2i      nev = mesh.GetEdgeV(eid);
         QuadricError Q   = new QuadricError(ref vertQuadrics[nev.a], ref vertQuadrics[nev.b]);
         Vector3d     opt = OptimalPoint(eid, ref Q, nev.a, nev.b);
         double       err = Q.Evaluate(ref opt);
         EdgeQuadrics[eid] = new QEdge(eid, ref Q, ref opt);
         if (EdgeQueue.Contains(eid))
         {
             EdgeQueue.Update(eid, (float)err);
         }
         else
         {
             EdgeQueue.Insert(eid, (float)err);
         }
     }
 }
Esempio n. 5
0
 // update queue weight for each edge in vertex one-ring
 protected virtual void UpdateNeighbours(int vid)
 {
     foreach (int eid in mesh.VtxEdgesItr(vid))
     {
         Index2i      nev      = mesh.GetEdgeV(eid);
         QuadricError Q        = new QuadricError(ref vertQuadrics[nev.a], ref vertQuadrics[nev.b]);
         Vector3d     opt      = OptimalPoint(Q, nev.a, nev.b);
         double       err      = Q.Evaluate(opt);
         QEdge        eid_node = Nodes[eid];
         if (eid_node != null)
         {
             eid_node.q           = Q;
             eid_node.collapse_pt = opt;
             EdgeQueue.UpdatePriority(eid_node, (float)err);
         }
         else
         {
             QEdge ee = NodePool.Allocate();
             ee.Initialize(eid, Q, opt);
             Nodes[eid] = ee;
             EdgeQueue.Enqueue(ee, (float)err);
         }
     }
 }