Beispiel #1
0
    /// Optimize in a greedy fashion.
    public void PriorityQueueOptimization(HMesh m, EnergyFun efun)
    {
        //HalfEdgeAttributeVector<HalfEdgeCounter> counter(m.allocated_halfedges(), HalfEdgeCounter{0, false});
//        VertexAttributeVector<int> flipCounter(m.allocated_vertices(), 0);
        Dictionary <int, HalfEdgeCounter> counter     = new Dictionary <int, HalfEdgeCounter>();
        Dictionary <int, int>             flipCounter = new Dictionary <int, int>();

        Priority_Queue.SimplePriorityQueue <PQElement> Q = new SimplePriorityQueue <PQElement>();
        //priority_queue<PQElement> Q;

        //cout << "Building priority queue"<< endl;
        int time = 1;

        foreach (var h in m.GetHalfedgesRaw())
        {
            if (!counter.ContainsKey(h.id))
            {
                counter.Add(h.id, new HalfEdgeCounter());
            }
            AddToQueue(counter, Q, h, efun, flipCounter, time);
        }

        //cout << "Emptying priority queue of size: " << Q.size() << " ";
        while (Q.Count > 0)
        {
            PQElement elem = Q.Dequeue();

            //Walker w = m.walker(elem.h);

            if (counter[elem.h.id].isRemovedFromQueue) // if item already has been processed continue
            {
                continue;
            }

            counter[elem.h.id].isRemovedFromQueue = true;

            if (counter[elem.h.id].touched != elem.time)
            {
                if (efun.DeltaEnergy(elem.h) >= 0)
                {
                    continue;
                }
            }
            if (!PrecondFlipEdge(elem.h))
            {
                continue;
            }

            flipCounter[elem.h.vert.id]++;

            elem.h.Flip();

            AddOneRingToQueue(counter, Q, elem.h.vert, efun, flipCounter, time);
            AddOneRingToQueue(counter, Q, elem.h.next.vert, efun, flipCounter, time);
            AddOneRingToQueue(counter, Q, elem.h.opp.vert, efun, flipCounter, time);
            AddOneRingToQueue(counter, Q, elem.h.opp.next.vert, efun, flipCounter, time);
        }
    }
Beispiel #2
0
    private void AddToQueue(Dictionary <int, HalfEdgeCounter> counter, SimplePriorityQueue <PQElement> Q, Halfedge h, EnergyFun efun, Dictionary <int, int> flipCounter, int time)
    {
        if (h.IsBoundary())
        {
            return;
        }
        // only consider one of the halfedges
        if (h.id < h.opp.id)
        {
            h = h.opp;
        }
        // if half edge already tested for queue in the current frame then skip
        HalfEdgeCounter c = null;

        if (!counter.TryGetValue(h.id, out c))
        {
            c             = new HalfEdgeCounter();
            counter[h.id] = c;
        }
        if (c.touched == time)
        {
            return;
        }
        c.isRemovedFromQueue = false;

        if (!PrecondFlipEdge(h))
        {
            return;
        }

        double energy = efun.DeltaEnergy(h);

        c.touched = time;

        const int avgValence = 6;
        int       count      = 0;

        if (!flipCounter.TryGetValue(h.vert.id, out count))
        {
            flipCounter[h.vert.id] = 0;
        }
        if ((energy < 0) && (count < avgValence))
        {
            Q.Enqueue(new PQElement(energy, h, time), (float)energy);
        }
    }
Beispiel #3
0
 void AddOneRingToQueue(Dictionary <int, HalfEdgeCounter> counter, SimplePriorityQueue <PQElement> Q, Vertex v, EnergyFun efun, Dictionary <int, int> flipCounter, int time)
 {
     foreach (var he in v.Circulate())
     {
         AddToQueue(counter, Q, he, efun, flipCounter, time);
     }
 }