public HeapNode <TObj> Insert(HeapNode <TObj> node) { int i = _buffer.Count; node.index = i; _buffer.Add(node); _upheap(i); return(node); }
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); } }
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); } }
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); }
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); } }
void _place(HeapNode <TObj> node, int i) { _buffer[i] = node; node.index = i; }
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); }