/// <summary> /// nodeFilterF is used to restrict to valid nodes (eg if id space is sparse, or you only want a subset of possible nbrs) /// seeds list are pairs (id, seedvalue) /// </summary> public DijkstraGraphDistance(int nMaxID, bool bSparse, Func <int, bool> nodeFilterF, Func <int, int, float> nodeDistanceF, Func <int, IEnumerable <int> > neighboursF, IEnumerable <Vector2d> seeds = null // these are pairs (index, seedval) ) { NodeFilterF = nodeFilterF; NodeDistanceF = nodeDistanceF; NeighboursF = neighboursF; if (bSparse) { SparseQueue = new DynamicPriorityQueue <GraphNode>(); SparseNodes = new SparseObjectList <GraphNode>(nMaxID, 0); SparseNodePool = new MemoryPool <GraphNode>(); } else { DenseQueue = new IndexPriorityQueue(nMaxID); DenseNodes = new GraphNodeStruct[nMaxID]; } Seeds = new List <int>(); max_value = float.MinValue; if (seeds != null) { foreach (var v in seeds) { AddSeed((int)v.x, (float)v.y); } } }
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); */ }