public int Compare(object x, object y) { VertexRecord v1 = (VertexRecord)x; VertexRecord v2 = (VertexRecord)y; if (v1.Order < v2.Order) { return(-1); } if (v1.Order > v2.Order) { return(1); } // v1.Order equals v2.Order. If these orders are > 0, they won't get // added to the sorted list anyhow, so we'll pretend they're equivalent, // and return 0. Otherwise, if the nodes' orders are zero, we'll // consider the secondary sort criteria. if (v1.Order > 0) { return(0); } try { return(v1.Underlying.SortCriteria.CompareTo(v2.Underlying.SortCriteria)); } catch (Exception ex) { _Debug.WriteLine(ex.Message); return(0); } }
private ArrayList BubbleSort(ArrayList list) { // We know that anything out of sequence is only one "bin" off. So as we move down the array, we track the last place // that the count incremented. VertexRecord[] va = (VertexRecord[])list.ToArray(typeof(VertexRecord)); int lastStepUp = -1; int lastOrder = -1; for (int i = 0; i < va.Length; i++) { int thisOrder = va[i].Order; if (thisOrder > lastOrder) { lastStepUp = i; } if (thisOrder < lastOrder) { VertexRecord tmp = va[lastStepUp]; va[lastStepUp] = va[i]; va[i] = tmp; lastStepUp++; } lastOrder = va[i].Order; } return(new ArrayList(va)); }
internal void DecrementParentsChildCount(Hashtable otherVertices) { foreach (IDependencyVertex idv in m_underlying.PredecessorList) { VertexRecord v = (VertexRecord)otherVertices[idv]; v.Order--; } }
internal void EstablishChildRelationships(Hashtable otherVertices) { foreach (IDependencyVertex idv in m_underlying.PredecessorList) { VertexRecord v = (VertexRecord)otherVertices[idv]; v.Order++; } }
private void Simplify() { Program.PrintText("Simplification"); int vn = mesh.VertexCount; // if (vn <= targetVertices) return; int nextLevel = (int)(vn * simplificationRatio); if (nextLevel < targetVertices) { nextLevel = targetVertices; } // copy connectivity // VertexRecord[] vRec = new VertexRecord[vn]; EdgeRecord[] edgeRec = CreateEdgeCollapseRecords(); List <EdgeRecord> collapseRec = new List <EdgeRecord>(); bool[] collapsed = new bool[vn]; PriorityQueue queue = new PriorityQueue(vn); for (int i = 0; i < vn; i++) { queue.Insert(edgeRec[i]); collapsed[i] = false; } { Program.PrintText("output mesh level: " + vn); List <VertexRecord> vRecList = new List <VertexRecord>(); for (int j = 0; j < vn; j++) { if (collapsed[j]) { continue; } VertexRecord r = new VertexRecord(j); foreach (int adj in edgeRec[j].adjV) { r.adjV.Add(adj); } vRecList.Add(r); } simplifiedMeshes.Add(vRecList); collapseRec.Reverse(); collapsedRecords.Add(collapseRec); faceRecords.Add((int[])mesh.FaceIndex.Clone()); collapseRec = new List <EdgeRecord>(); } int count = vn; for (int i = 0; i < vn - targetVertices; i++) { EdgeRecord rec1 = (EdgeRecord)queue.DeleteMin(); EdgeRecord rec2 = edgeRec[rec1.minIndex]; rec2.area += rec1.area; collapseRec.Add(rec1); collapsed[rec1.vIndex] = true; count--; foreach (int j in rec1.adjV) { edgeRec[j].adjV.Remove(rec1.vIndex); if (j != rec2.vIndex) { edgeRec[j].adjV.Add(rec2.vIndex); edgeRec[rec2.vIndex].adjV.Add(j); } } foreach (int j in rec2.adjV) { UpdateEdgeCollapseRecords(queue, edgeRec, j); } UpdateEdgeCollapseRecords(queue, edgeRec, rec2.vIndex); if (count == nextLevel) { Program.PrintText("output mesh level: " + count); List <VertexRecord> vRecList = new List <VertexRecord>(); for (int j = 0; j < vn; j++) { if (collapsed[j]) { continue; } VertexRecord r = new VertexRecord(j); foreach (int adj in edgeRec[j].adjV) { r.adjV.Add(adj); } vRecList.Add(r); } simplifiedMeshes.Add(vRecList); int[] fr = BuildCollapsedFaceIndex(faceRecords[faceRecords.Count - 1], collapseRec); faceRecords.Add(fr); collapseRec.Reverse(); collapsedRecords.Add(collapseRec); collapseRec = new List <EdgeRecord>(); nextLevel = (int)(nextLevel * simplificationRatio); if (nextLevel < targetVertices) { nextLevel = targetVertices; } } } simplifiedMeshes.Reverse(); collapsedRecords.Reverse(); faceRecords.Reverse(); }
/// <summary> /// Recalculates the service sequence. /// </summary> protected void RecalculateServiceSequence() { m_serviceSequenceList = new ArrayList(); // First we create the list of vertex data and a hashtable to find // the vertex from the underlying. ArrayList lstVerts = new ArrayList(); Hashtable htVerts = new Hashtable(); //_Debug.WriteLine("Calculating Service Sequence."); foreach (IDependencyVertex idv in m_vertices) { VertexRecord v = new VertexRecord(idv); if (s_diagnostics) { _Debug.WriteLine("Parents of " + v.Underlying); foreach (IDependencyVertex idv2 in v.Underlying.PredecessorList) { _Debug.WriteLine("\t" + idv2); } } lstVerts.Add(v); htVerts.Add(idv, v); if (s_diagnostics) { _Debug.WriteLine(String.Format("New vertex, {0} with {1} dependents.", idv, idv.PredecessorList.Count)); } } // Each underlying knows who it depends on - we need each vertex to // know, rather, who depends on IT. foreach (VertexRecord v in lstVerts) { v.EstablishChildRelationships(htVerts); } try { bool bResortNeeded = true; int numAffectedLastAdjustment = lstVerts.Count; // We will repeat the following until all nodes have been evaluated. while (lstVerts.Count > 0) { //if ( lstVerts.Count%100 == 0 ) Console.WriteLine("%%%" + lstVerts.Count); // Sort remaining vertices by the provided Comparer. (defaults to // sorting first by nOrder, then by the vertices' provided comparator. // See below for an explanation of the 'bResortNeeded' boolean. if (bResortNeeded) { if (numAffectedLastAdjustment > lstVerts.Count * 0.02) { lstVerts.Sort(GetVertexComparer()); } else { lstVerts = BubbleSort(lstVerts); } } // Dumps the sort order as it progresses... //foreach ( Vertex v in lstVerts ) _Debug.WriteLine(v.Underlying + " : " + v.Order); // Move the least vertex to the ServiceOrder list. VertexRecord next = (VertexRecord)lstVerts[0]; lstVerts.RemoveAt(0); m_serviceSequenceList.Add(next.Underlying); // If the vertex we just removed had no parents, then the sort order // that was valid in the preceding step is still valid. Nobody had // their child-count reduced, so no one's position in the sort will // have had a reason to change. We just move on to the next one... numAffectedLastAdjustment = next.Underlying.PredecessorList.Count; bResortNeeded = (numAffectedLastAdjustment > 0); if (next.Order != 0) { IDependencyVertex root = next.Underlying; ArrayList members = new ArrayList(); members.Add(root); Stack stack = new Stack(); foreach (IDependencyVertex parent in root.PredecessorList) { if (!FindCycle(root, parent, ref members, ref stack)) { break; } } throw new GraphCycleException(members); } // Decrement the Order of all vertices that this one depended on. next.DecrementParentsChildCount(htVerts); } } catch (StackOverflowException soe) { throw new ApplicationException("The GraphSequencer has detected a probable dependency cycle in the initialization sequence of this model. For details, set the GraphSequencer.StackCheck key to true in the modeler's app.config file.", soe); } #region Diagnostics if (s_diagnostics) { _Debug.WriteLine("Dependency Solver determines sequence to be:"); foreach (IDependencyVertex idv in m_serviceSequenceList) { _Debug.WriteLine("\t" + idv); } } #endregion Diagnostics }