예제 #1
0
        public HeapNode <TObj> Insert(HeapNode <TObj> node)
        {
            int i = _buffer.Count;

            node.index = i;
            _buffer.Add(node);
            _upheap(i);
            return(node);
        }
예제 #2
0
        void _upheap(int i)
        {
            HeapNode <TObj> moving = _buffer[i];
            int             index  = i;
            int             p      = _parent(i);

            while (index > 0 && moving.heapValue < _buffer[p].heapValue)
            {
                _place(_buffer[p], index);
                index = p;
                p     = _parent(p);
            }

            if (index != i)
            {
                _place(moving, index);
            }
        }
예제 #3
0
        void _downheap(int i)
        {
            int length = _buffer.Count;

            if (!(i < length))
            {
                return;
            }

            HeapNode <TObj> moving = _buffer[i];
            int             index  = i;
            int             l      = _left(i);
            int             r      = _right(i);
            int             largest;

            while (l < length)
            {
                if (r < length && _buffer[l].heapValue > _buffer[r].heapValue)
                {
                    largest = r;
                }
                else
                {
                    largest = l;
                }

                if (moving.heapValue > _buffer[largest].heapValue)
                {
                    _place(_buffer[largest], index);
                    index = largest;
                    l     = _left(index);
                    r     = l + 1;         //right(index);
                }
                else
                {
                    break;
                }
            }

            if (index != i)
            {
                _place(moving, index);
            }
        }
예제 #4
0
        public HeapNode <TObj> Extract()
        {
            int p = _buffer.Count - 1;

            if (p < 0)
            {
                return(null);
            }

            _swap(0, p);

            HeapNode <TObj> dead = _buffer[p];

            _buffer.RemoveAt(p);
            dead.RemoveFromHeap();

            _downheap(0);
            return(dead);
        }
예제 #5
0
        public void Update(HeapNode <TObj> node, float v)
        {
            node.heapValue = v;
            //      if(!node.IsInHeap()) {
            //Debug.LogError("Updateing node which is not in heap!");
            //		return;
            //	}

            int i = node.index;

            if (i > 0 && v < _buffer[_parent(i)].heapValue)
            {
                _upheap(i);
            }
            else
            {
                _downheap(i);
            }
        }
예제 #6
0
 void _place(HeapNode <TObj> node, int i)
 {
     _buffer[i] = node;
     node.index = i;
 }
예제 #7
0
        public int Collapse(int numEdgesToCollapse = 1, float maxCost = 1e6f)
        {
            int collapsesDone = 0;

            while (numEdgesToCollapse > 0)
            {
                HeapNode <CollapseInfo> node;
                do
                {
                    node = heap.Extract();
                } while (node != null && mesh.isVertexPairValid(node.obj.vp) == false);
                if (node == null)
                {
                    break;
                }

                if (node.heapValue > maxCost)
                {
                    break;
                }

                CollapseInfo cinfo = node.obj;
                VertexPair   vp    = cinfo.vp;
                // Add the error terms .. v[0] is the vertex that survives the collapse
                pdePerVertex[vp.v[0]].OpAdd(pdePerVertex[vp.v[1]]);

                // DO THE COLLAPSE
                int vindex = mesh.CollapseVertexPair(cinfo);                 // vindex is the surviving vertex index

                // Need to update the cost of all edges around all linked faces of vindex
                // these are the edges connected to vindex + all the edges connected to vindex neighbours
                _edgesToUpdate.Clear();
                _surroundingVerts.Clear();

                mesh.CollectVerticesAroundVertex(vindex, ref _surroundingVerts);

                // TODO: do this better -> why?
                int mark = mesh.GetUniqueTag();
                for (int i = 0; i < _surroundingVerts.Count; ++i)
                {
                    List <int> lEdges = mesh.linkedEdgesForVert(_surroundingVerts[i]);
                    for (int j = 0; j < lEdges.Count; ++j)
                    {
                        int  edgeIndex = lEdges[j];
                        Edge e         = mesh.edges[edgeIndex];
                        if (e.mark != mark)
                        {
                            e.mark = mark;
                            if (mesh.IsEdgeValid(edgeIndex))
                            {
                                _edgesToUpdate.Add(edgeIndex);
                            }
                        }
                    }
                }

                // DO the update
                for (int i = 0; i < _edgesToUpdate.Count; ++i)
                {
                    int edgeIndex = _edgesToUpdate[i];
                    HeapNode <CollapseInfo> hnode = heapNodes[edgeIndex];
                    if (mesh.edges[edgeIndex].ContainsVertex(vindex))
                    {
                        _calculateEdgeCost(edgeIndex, hnode.obj);
                    }
                    else
                    {
                        _updateEdgePenalties(edgeIndex, hnode.obj, vindex);
                    }
                    heap.Update(hnode, hnode.obj.cost);
                }

                numEdgesToCollapse--;
                collapsesDone++;
            }
            return(collapsesDone);
        }