예제 #1
0
        /// <summary>
        /// 塌陷一个点
        /// </summary>
        /// <param name="mesh"></param>
        /// <param name="rv"></param>
        protected static void Collapse(LODMesh mesh, RepeatedVertex rv, bool reCompute = false)
        {
            RepeatedVertex to = rv.collapsedTo;

            // 删除点
            rv.deleteFlag = true;
            // 删除边
            LODEdge edge   = new LODEdge(rv.index, rv.collapsedTo.index);
            LODEdge target = mesh.edges.Find((item) => { return(edge.Equals(item)); });

            target.deleteFlag = true;
            // 删除面
            List <int> remains      = new List <int>();
            List <int> deletedFaces = GetEdgeShareFaces(mesh, rv.index, to.index, remains);

            foreach (int del in deletedFaces)
            {
                mesh.faces[del].deleteFlag = true;
            }
            // 更新面
            foreach (int remain in remains)
            {
                // 顶点更新
                mesh.faces[remain].Replace(mesh, rv.index, to.index);
                // uv更新
                // todo
            }

            // 更新临点
            if (reCompute)
            {
                List <RepeatedVertex> neighbors = new List <RepeatedVertex>();
                RefreshNeighbor(mesh, rv);
            }
        }
예제 #2
0
        /// <summary>
        /// 塌陷处理
        /// </summary>
        /// <param name="mesh"></param>
        protected static void CollapseMesh(LODMesh mesh)
        {
            RepeatedVertex rv = mesh.Pop();

            while (rv != null)
            {
                Collapse(mesh, rv);
                rv = mesh.Pop();
            }
        }
예제 #3
0
        /// <summary>
        /// 此处一次只会删一个点
        /// </summary>
        public void Delete(RepeatedVertex rv)
        {
            int split = rv.index;

            foreach (int n in rv.neighborVertices)
            {
                vertices[n].neighborVertices.Remove(split);
            }

            vertices.RemoveAt(split);
        }
예제 #4
0
        /// <summary>
        /// 初始化所有边塌陷代价值
        /// </summary>
        /// <param name="mesh"></param>
        protected static void InitializeAllEdgeCost(LODMesh mesh)
        {
            int cnt = mesh.vertices.Count;

            for (int i = 0; i < cnt; ++i)
            {
                RepeatedVertex v = mesh.vertices[i];
                v.collapsedTo = null;
                EdgeCostAtVertex(mesh, v);
                mesh.AddHeap(v);
            }
        }
예제 #5
0
        protected static void RefreshNeighbor(LODMesh mesh, RepeatedVertex rv)
        {
            List <int> neighbors = rv.neighborVertices;

            foreach (int n in neighbors)
            {
                if (mesh.vertices[n].deleteFlag)
                {
                    continue;
                }
                EdgeCostAtVertex(mesh, mesh.vertices[n]);
            }
        }
예제 #6
0
 /// <summary>
 /// 判断 点是否是 一条边界边的点
 /// </summary>
 protected static bool IsBorder(LODMesh mesh, RepeatedVertex v)
 {
     foreach (int nei in v.neighborVertices)
     {
         LODEdge tmp  = new LODEdge(v.index, nei);
         LODEdge edge = mesh.edges.Find((item) => { return(tmp.Equals(item)); });
         if (edge != null)
         {
             if (edge.shareCount == 1)
             {
                 return(true);
             }
         }
     }
     return(false);
 }
예제 #7
0
        protected static void EdgeCostAtVertex(LODMesh mesh, RepeatedVertex v)
        {
            bool isBorder = IsBorder(mesh, v);

            for (int j = 0; j < v.neighborVertices.Count; ++j)
            {
                int   ij                = v.neighborVertices[j];
                int   shareCount        = 0;
                float edgeCurvatureCost = EdgeCurvatureCost(mesh, v.index, ij, ref shareCount);
                float edgeLen           = EdgeLength(mesh, v.index, ij);

                float cost = edgeCurvatureCost * edgeLen;
                if (v.collapsedTo == null || cost < v.cost)
                {
                    v.collapsedTo = mesh.vertices[ij];
                    v.cost        = cost;
                }
            }
        }
예제 #8
0
        protected static List <int> GetEdgeShareFaces(LODMesh mesh, int iIdx, int jIdx, List <int> remain = null)
        {
            RepeatedVertex u          = mesh.vertices[iIdx];
            RepeatedVertex v          = mesh.vertices[jIdx];
            List <int>     totalFaces = u.neighborFaces;
            List <int>     uvFaces    = new List <int>();

            for (int k = 0; k < totalFaces.Count; ++k)
            {
                LODFace face = mesh.faces[totalFaces[k]];
                if (face.ContainVertex(jIdx))
                {
                    uvFaces.Add(totalFaces[k]);
                }
                else
                {
                    if (remain != null)
                    {
                        remain.Add(totalFaces[k]); // 保留不共享边的面
                    }
                }
            }
            return(uvFaces);
        }
예제 #9
0
        protected static LODMesh ParseMesh(Mesh meshIn)
        {
            LODMesh        lodMesh  = new LODMesh(meshIn);
            List <Vector3> vertices = new List <Vector3>();

            meshIn.GetVertices(vertices);
            List <LODVertex>      lodVertices = Convert(vertices);
            GroupHash <LODVertex> group       = new GroupHash <LODVertex>();

            group.Objects = lodVertices;

            List <List <LODVertex> >         merged = group.GetResult();
            Dictionary <int, RepeatedVertex> originalVertexMapRepeatedIndex = new Dictionary <int, RepeatedVertex>();

            for (int i = 0; i < merged.Count; ++i)
            {
                RepeatedVertex rpv = new RepeatedVertex(merged[i], i);
                lodMesh.vertices.Add(rpv);
                foreach (LODVertex v in merged[i])
                {
                    originalVertexMapRepeatedIndex.Add(v.originalIndex, rpv);
                }
            }
            Dictionary <int, LODSubMesh> originalFaceMapSubMeshIndex = new Dictionary <int, LODSubMesh>();

            int        count     = meshIn.subMeshCount;
            List <int> triangles = new List <int>();

            for (int i = 0; i < count; ++i)
            {
                LODSubMesh subMesh = new LODSubMesh(i);
                lodMesh.subMeshes.Add(subMesh);
                triangles.Clear();
                meshIn.GetTriangles(triangles, i);

                int cnt = triangles.Count;
                for (int j = 0; j < cnt; j += 3)
                {
                    int tmp0 = triangles[j];
                    int tmp1 = triangles[j + 1];
                    int tmp2 = triangles[j + 2];

                    int idx0 = originalVertexMapRepeatedIndex[tmp0].index;
                    int idx1 = originalVertexMapRepeatedIndex[tmp1].index;
                    int idx2 = originalVertexMapRepeatedIndex[tmp2].index;

                    int faceIndex = lodMesh.faces.Count;
                    originalFaceMapSubMeshIndex.Add(faceIndex, subMesh);
                    subMesh.faceIndices.Add(faceIndex);
                    lodMesh.faces.Add(new LODFace(lodMesh, lodMesh.subMeshes.Count - 1, idx0, idx1, idx2));

                    // 绑定临点
                    originalVertexMapRepeatedIndex[idx0].neighborVertices.Add(idx1);
                    originalVertexMapRepeatedIndex[idx0].neighborVertices.Add(idx2);

                    originalVertexMapRepeatedIndex[idx1].neighborVertices.Add(idx0);
                    originalVertexMapRepeatedIndex[idx1].neighborVertices.Add(idx2);

                    originalVertexMapRepeatedIndex[idx2].neighborVertices.Add(idx0);
                    originalVertexMapRepeatedIndex[idx2].neighborVertices.Add(idx1);

                    // 边
                    LODEdge e0 = new LODEdge(idx0, idx1);
                    LODEdge e1 = new LODEdge(idx0, idx2);
                    LODEdge e2 = new LODEdge(idx1, idx2);

                    LODEdge ee0 = lodMesh.edges.Find((item) => { return(e0.Equals(item)); });
                    LODEdge ee1 = lodMesh.edges.Find((item) => { return(e1.Equals(item)); });
                    LODEdge ee2 = lodMesh.edges.Find((item) => { return(e2.Equals(item)); });
                    if (ee0 != null)
                    {
                        ee0.Share();
                    }
                    else
                    {
                        lodMesh.edges.Add(e0);
                    }
                    if (ee1 != null)
                    {
                        ee1.Share();
                    }
                    else
                    {
                        lodMesh.edges.Add(e1);
                    }
                    if (ee2 != null)
                    {
                        ee2.Share();
                    }
                    else
                    {
                        lodMesh.edges.Add(e2);
                    }

                    // 临面
                    originalVertexMapRepeatedIndex[idx0].neighborFaces.Add(faceIndex);
                    originalVertexMapRepeatedIndex[idx1].neighborFaces.Add(faceIndex);
                    originalVertexMapRepeatedIndex[idx2].neighborFaces.Add(faceIndex);
                }
            }

            //for (int i = 0; i < lodMesh.faces.Count - 1; ++i)
            //{
            //    // Fill the neighbor faces information in face list
            //    for (int j = i + 1; j < lodMesh.faces.Count; ++j)
            //    {
            //        if (IsNeighbors(lodMesh, i, j))
            //        {
            //            lodMesh.faces[i].neighboringFaceIndexList.Add(j);
            //            lodMesh.faces[j].neighboringFaceIndexList.Add(i);
            //        }
            //    }
            //}

            return(lodMesh);
        }
예제 #10
0
        /// <summary>
        /// 判断 点是否是 一条边界边的点
        /// </summary>
        protected static bool IsBorder(LODMesh mesh, int iIdx)
        {
            RepeatedVertex v = mesh.vertices[iIdx];

            return(IsBorder(mesh, v));
        }
예제 #11
0
 public void AddHeap(RepeatedVertex rv)
 {
     m_heapCost.Enqueue(rv.index, rv, rv.cost);
 }