Пример #1
0
            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);
                }
            }
Пример #2
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));
        }
Пример #3
0
 internal void DecrementParentsChildCount(Hashtable otherVertices)
 {
     foreach (IDependencyVertex idv in m_underlying.PredecessorList)
     {
         VertexRecord v = (VertexRecord)otherVertices[idv];
         v.Order--;
     }
 }
Пример #4
0
 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();
        }
Пример #6
0
        /// <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
        }