/// <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); }
// "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(); }