예제 #1
0
            /// <summary>
            /// merge two VFaces into lhs,
            /// modify other related data-structures as well
            /// </summary>
            private void _MergeVFace(VFace lhs, VFace rhs)
            {
                //int lhsTriIdx = lhs.GetRTriIdx(0);
                int rhsTriIdx = rhs.GetRTriIdx(0);

                m_VFaceCont[rhsTriIdx] = lhs; //link rhs's rTri to lhs

                // merge the data from rhs to lhs
                lhs.AddRTri(rhsTriIdx);
            }
예제 #2
0
            // "VQuad table init"

            /// <summary>
            /// this method will try to make VMesh from tri-mesh into hybrid tri-quad-mesh,
            /// it will mark some vedges as "ActiveEdge" which will be used,
            ///
            /// the result will be used in:
            /// * edge marker,
            /// * edge loop
            /// * etc
            ///
            /// [BE WARNED]:
            /// </summary>
            private void _InitVFaceTable()
            {
                //////////////////////////////////////////////////
                // 1. foreach vedge of the vmesh
                //       if vedge has and only has 2 tris
                //          calc a score and store in sorted_vEdges
                // 2. foreach vedge in sorted_vEdges
                //       if the 2 tris not be 'marked' yet, then
                //          take it as the 'non-quad' edge;
                //          mark the 2 tris;
                // 3. get all active-edge into m_VActiveEdgeArr
                //   3.1 call all vvert, to make activeVEdge
                // 4. prepare the VFaceCont:
                //        create the rTriIdx <=> VFace first;
                //        merge VFace with those markedTris;
                // 5. process the degraded r-tris, assign them to some good VFace (so we can handle click-selection)
                //////////////////////////////////////////////////

                int totalTriCnt = MeshCache.Instance.triangles.Length / 3;

                VVert[] tmpVertArr = new VVert[4];

                // step 1
                SortedDictionary <_ScoredEdge, bool> sortedVEdges = new SortedDictionary <_ScoredEdge, bool>();

                foreach (var vedge in m_VEdgeCont)
                {
                    if (vedge.GetRTriCount() != 2)
                    {
                        continue;
                    }

                    RTriCont rtris = vedge.GetRTris();
                    _GetAsQuadVerts(rtris[0], rtris[1], vedge, tmpVertArr);

                    float score = _CalcQuadScore(tmpVertArr); // calc score for the quad-to-be
                    sortedVEdges.Add(new _ScoredEdge(score, vedge), false);
                }

                // step 2
                //int cnt = 0;
                Dictionary <int, int> markedTris = new Dictionary <int, int>();

                for (var ie = sortedVEdges.GetEnumerator(); ie.MoveNext();)
                {
                    var vedge = ie.Current.Key.vEdge;
                    //if (cnt < 100)
                    //Dbg.Log("sortedVEdges: {0}: {1}, score:{2}", cnt++, vedge, ie.Current.Key.score);
                    RTriCont triCont = vedge.GetRTris();
                    Dbg.Assert(triCont.Count == 2, "VMesh._InitVFaceTable: the tri-cont count of vEdge != 2");
                    if (!markedTris.ContainsKey(triCont[0]) && !markedTris.ContainsKey(triCont[1]))
                    {
                        //Dbg.Log("Add markedTris: {0}<=>{1}", triCont[0], triCont[1]);
                        markedTris.Add(triCont[0], triCont[1]);
                        markedTris.Add(triCont[1], triCont[0]);
                        vedge.IsActiveEdge = false;

                        if (markedTris.Count >= totalTriCnt)
                        {
                            break; // all tris covered, no need to loop on
                        }
                    }
                }

                // step 3
                List <VEdge> quadEdges = new List <VEdge>();

                for (int i = 0; i < m_VEdgeArr.Length; ++i)
                {
                    if (m_VEdgeArr[i].IsActiveEdge)
                    {
                        quadEdges.Add(m_VEdgeArr[i]);
                    }
                }
                m_VActiveEdgeArr = quadEdges.ToArray();

                //step 3.1
                for (int i = 0; i < m_VVertArr.Length; ++i)
                {
                    m_VVertArr[i].CreateActiveVEdgesList();
                }

                // step 4
                int[] rTriIdxs = MeshCache.Instance.triangles;
                int   rTriCnt  = rTriIdxs.Length / 3;

                for (int i = 0; i < rTriCnt; ++i)
                {
                    VFace vFace = new VFace();
                    vFace.AddRTri(i);

                    m_VFaceCont.Add(i, vFace);
                }

                for (var ie = markedTris.GetEnumerator(); ie.MoveNext();)
                {
                    int rTriIdx0 = ie.Current.Key;
                    int rTriIdx1 = ie.Current.Value;

                    if (rTriIdx0 > rTriIdx1)
                    {
                        continue;
                    }

                    VFace vf0 = m_VFaceCont[rTriIdx0];
                    VFace vf1 = m_VFaceCont[rTriIdx1];

                    _MergeVFace(vf0, vf1);
                }
                markedTris.Clear();

                // step 5
                _MapVVertToVFaces();
            }