예제 #1
0
        public static void RepaireHoleTwo(List <TriMesh.Vertex> hole)
        {
            TriMesh  mesh   = (TriMesh)hole[0].Mesh;
            Vector3D center = Vector3D.Zero;

            for (int i = 0; i < hole.Count; i++)
            {
                center += hole[i].Traits.Position;
            }
            center /= hole.Count;

            TriMesh.Vertex vertex = mesh.Vertices.Add(new VertexTraits(center));

            if (hole.Count >= 3)
            {
                TriMesh.Vertex[] faceVertices = new TriMesh.Vertex[3];

                for (int i = 0; i < hole.Count; i++)
                {
                    faceVertices[0] = vertex;
                    faceVertices[1] = hole[i];
                    faceVertices[2] = hole[(i + 1) % hole.Count];
                    mesh.Faces.AddTriangles(faceVertices);
                }
            }

            TriMeshUtil.FixIndex(mesh);
        }
예제 #2
0
        public void Init()
        {
            TriMeshUtil.FixIndex(mesh);

            int vc = mesh.Vertices.Count;
            int ec = mesh.Edges.Count;
            int fc = mesh.Faces.Count;

            this.EdgeLength              = new double[ec];
            this.FaceArea                = new double[fc];
            this.FaceNormal              = new Vector3D[fc];
            this.VertexAreaSum           = new double[ec];
            this.VertexAreaWeightNormal  = new Vector3D[vc];
            this.VertexDiscreteCurvature = new double[vc];

            foreach (var edge in this.mesh.Edges)
            {
                this.UpdateLength(edge);
            }

            foreach (var face in this.mesh.Faces)
            {
                this.UpdateAreaAndNormal(face);
            }

            foreach (var v in this.mesh.Vertices)
            {
                this.UpdateAreaWeightNormal(v);
                this.UpdateVertexDiscreteCurvature(v);
            }
        }
예제 #3
0
        public static void RepaireOneHole(TriMesh mesh)
        {
            List <TriMesh.Vertex> hole = TriMeshUtil.RetrieveBoundarySingle(mesh);

            RepaireHole(hole);
            TriMeshUtil.FixIndex(mesh);
        }
예제 #4
0
        private void removeToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            var enhance = new TriMeshEnhancement(Mesh);

            enhance.RemoveCapWithPlane();
            TriMeshUtil.FixIndex(Mesh);
            TriMeshUtil.SetUpNormalVertex(Mesh);
        }
예제 #5
0
        public TriMesh SubdivisionSelectedLoop()
        {
            TriMesh loopedMesh = ChangeTopologyLoopSelected(Mesh);

            ChangeGeometryLoopSelected(Mesh, loopedMesh);
            TriMeshUtil.FixIndex(loopedMesh);
            return(loopedMesh);
        }
예제 #6
0
        private void showToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            var enhance = new TriMeshEnhancement(Mesh);

            enhance.PlaneCutTest();
            TriMeshUtil.FixIndex(Mesh);
            TriMeshUtil.SetUpNormalVertex(Mesh);
        }
예제 #7
0
        private void simplify567ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Test567 test = new Test567(Mesh);

            test.CollapseAll(this.faceCount);
            TriMeshUtil.FixIndex(Mesh);
            TriMeshUtil.SetUpNormalVertex(Mesh);
            OnChanged(EventArgs.Empty);
        }
예제 #8
0
        public TriMesh SubdivisonSqrt3()
        {
            TriMesh sqrt = ChangeTopologyInit(Mesh);

            ChangeGeometrySqrt3(Mesh, sqrt);
            TriMeshUtil.FixIndex(sqrt);

            return(sqrt);
        }
예제 #9
0
        public static void RemoveSelectedFaces(TriMesh mesh)
        {
            List <TriMesh.Face> selected = TriMeshUtil.RetrieveSelectedFace(mesh);

            for (int i = 0; i < selected.Count; i++)
            {
                RemoveFace(selected[i]);
            }
            TriMeshUtil.FixIndex(mesh);
        }
예제 #10
0
        private void removeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var enhance = new TriMeshEnhancement(Mesh);

            enhance.RemoveCapWithSplit();

            TriMeshUtil.FixIndex(Mesh);
            TriMeshUtil.SetUpNormalVertex(Mesh);
            OnChanged(EventArgs.Empty);
        }
예제 #11
0
        public static void RemoveTwoRingOfVertex(TriMesh mesh)
        {
            List <TriMesh.Vertex> selected = TriMeshUtil.RetrieveSelectedVertex(mesh);

            for (int i = 0; i < selected.Count; i++)
            {
                RemoveTwoRingOfVertex(selected[i]);
            }
            TriMeshUtil.FixIndex(mesh);
        }
예제 #12
0
        public static void RemoveOneRingOfEdge(TriMesh mesh)
        {
            List <TriMesh.Edge> selected = TriMeshUtil.RetrieveSelectedEdge(mesh);

            for (int i = 0; i < selected.Count; i++)
            {
                RemoveOneRingOfEdge(selected[i]);
            }
            TriMeshUtil.FixIndex(mesh);
        }
예제 #13
0
        public static void RepaireAllHole(TriMesh mesh)
        {
            List <List <TriMesh.Vertex> > holes = TriMeshUtil.RetrieveBoundaryAllVertex(mesh);

            for (int i = 0; i < holes.Count; i++)
            {
                RepaireHoleTwo(holes[i]);
            }

            TriMeshUtil.FixIndex(mesh);
        }
예제 #14
0
        public static void RepaireHole(List <TriMesh.Vertex> hole)
        {
            TriMesh mesh = (TriMesh)hole[0].Mesh;

            if (hole.Count >= 3)
            {
                mesh.Faces.AddTriangles(hole.ToArray());
            }

            TriMeshUtil.FixIndex(mesh);
        }
예제 #15
0
        public static int Simplify(TriMesh mesh, EnumSimplicationType type, int preservedFace)
        {
            int i = 0;

            switch (type)
            {
            case EnumSimplicationType.CornerCutting:
                CornerCuttingSimplication corner = new CornerCuttingSimplication(mesh);
                i = corner.Run(preservedFace);
                break;

            case EnumSimplicationType.LengthAngle:
                LengthAndAngleSimplication lenghtAngle = new LengthAndAngleSimplication(mesh);
                i = lenghtAngle.Run(preservedFace);
                break;

            case EnumSimplicationType.MinCurvature:
                MinCurvatureSimplication minCurvature = new MinCurvatureSimplication(mesh);
                i = minCurvature.Run(preservedFace);
                break;

            case EnumSimplicationType.QEM:
                QEMSimplication qem = new QEMSimplication(mesh);
                i = qem.Run(preservedFace);
                break;

            case EnumSimplicationType.ShortEdge:
                ShortEdgeSimplication shortedge = new ShortEdgeSimplication(mesh);
                i = shortedge.Run(preservedFace);
                break;

            case EnumSimplicationType.SmallFace:
                SmallFaceSimplication smallFace = new SmallFaceSimplication(mesh);
                i = smallFace.Run(preservedFace);
                break;

            case EnumSimplicationType.SquareVolume:
                SquareVolumeSimplication squareVolume = new SquareVolumeSimplication(mesh);
                i = squareVolume.Run(preservedFace);
                break;

            case EnumSimplicationType.SurfaceFitting:
                SurfaceFittingSimplication surfaceFitting = new SurfaceFittingSimplication(mesh);
                i = surfaceFitting.Run(preservedFace);
                break;
            }
            TriMeshUtil.FixIndex(mesh);
            TriMeshUtil.SetUpNormalVertex(mesh);
            return(i);
        }
예제 #16
0
        private void Cut_Click(object sender, EventArgs e)
        {
            TriMeshModify.ComputeSelectedEdgeFromColor(Mesh);
            double move = TriMeshUtil.ComputeEdgeAvgLength(Mesh) * 0.1;
            TriMeshEdgeCutFromBoundary cut = new TriMeshEdgeCutFromBoundary(Mesh);

            cut.Cut(move);

            TriMeshUtil.ClearMeshColor(Mesh);
            TriMeshUtil.ShowBoundary(Mesh);
            TriMeshUtil.FixIndex(Mesh);
            TriMeshUtil.SetUpNormalVertex(Mesh);
            OnChanged(EventArgs.Empty);
        }
예제 #17
0
        private void remove567ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Test567 test = new Test567(Mesh);

            this.faceCount = test.Mesh.Faces.Count;
            test.Step3();
            test.Step4();
            test.Subdivision();
            test.StepGT7();
            TriMeshUtil.FixIndex(Mesh);

            TriMeshUtil.SetUpNormalVertex(Mesh);
            OnChanged(EventArgs.Empty);
        }
예제 #18
0
        public static void RepairSimpleHoles(TriMesh mesh)
        {
            List <List <TriMesh.HalfEdge> > holes = TriMeshUtil.RetrieveBoundaryEdgeAll(mesh);

            foreach (List <TriMesh.HalfEdge> hole in holes)
            {
                for (int i = 2; i < hole.Count; i++)
                {
                    mesh.Faces.AddTriangles(hole[0].ToVertex, hole[i - 1].ToVertex, hole[i].ToVertex);
                }
            }

            TriMeshUtil.FixIndex(mesh);
        }
예제 #19
0
        public static void RepairHole(TriMesh mesh)
        {
            List <TriMesh.Vertex> hole = new List <TriMesh.Vertex>();

            hole = TriMeshUtil.RetrieveBoundarySingle(mesh);
            TriMesh.Vertex[] faceVertices = new TriMesh.Vertex[3];
            for (int i = 0; i < hole.Count - 2; i++)
            {
                faceVertices[0] = mesh.Vertices[hole[0].Index];
                faceVertices[1] = mesh.Vertices[hole[i + 1].Index];
                faceVertices[2] = mesh.Vertices[hole[i + 2].Index];

                mesh.Faces.AddTriangles(faceVertices);
            }

            TriMeshUtil.FixIndex(mesh);
        }
예제 #20
0
 public static void MergeTriangle(TriMesh mesh)
 {
     for (int i = 0; i < mesh.Faces.Count; i++)
     {
         if (mesh.Faces[i].Traits.SelectedFlag != 0)
         {
             if (IsMergeable(mesh.Faces[i]))
             {
                 MergeTriangle(mesh.Faces[i]);
                 i = Math.Max(0, i - 3);
             }
             else
             {
                 mesh.Faces[i].Traits.SelectedFlag = 1;
             }
         }
     }
     TriMeshUtil.FixIndex(mesh);
     TriMeshUtil.SetUpNormalVertex(mesh);
 }
예제 #21
0
        public static void VertexSplit(TriMesh mesh)
        {
            List <TriMesh.Vertex> newvertex = new List <HalfEdgeMesh.Vertex>();

            for (int i = 0; i < mesh.Vertices.Count; i++)
            {
                if (mesh.Vertices[i].Traits.SelectedFlag != 0)
                {
                    TriMesh.Vertex vertex = VertexSplit(mesh.Vertices[i]);
                    newvertex.Add(vertex);
                }
            }

            foreach (TriMesh.Vertex vertex in newvertex)
            {
                vertex.Traits.selectedFlag = 1;
            }
            TriMeshUtil.FixIndex(mesh);
            TriMeshUtil.SetUpNormalVertex(mesh);
        }
예제 #22
0
        public void ClusterProcess()
        {
            for (int x = 0; x < Xcount; x++)
            {
                for (int y = 0; y < Ycount; y++)
                {
                    for (int z = 0; z < Zcount; z++)
                    {
                        TriMesh.Vertex[] group = FindVerticesInRange(x * cubeWeight + startX,
                                                                     y * cubeWeight + startY, z * cubeWeight + startZ);
                        if (group.Length != 0)
                        {
                            Vector3D avg = AvgOfCluster(group);
                            ClusterVertexs(group, avg);
                        }
                    }
                }
            }

            TriMeshUtil.FixIndex(mesh);
        }
예제 #23
0
        public void Cut(Plane plane)
        {
            this.plane    = plane;
            this.list     = new List <Triangle>();
            this.cutPoint = new Dictionary <int, CutPoint>();

            foreach (var hf in this.mesh.HalfEdges)
            {
                this.CutHalfEdge(hf);
            }

            foreach (var face in this.mesh.Faces)
            {
                this.CutFace(face);
            }

            List <TriMesh.Edge> edges = new List <HalfEdgeMesh.Edge>();

            foreach (var hf in this.mesh.HalfEdges)
            {
                if (this.cutPoint.ContainsKey(hf.Index))
                {
                    edges.Add(hf.Edge);
                }
            }
            foreach (var item in edges)
            {
                TriMeshModify.RemoveEdge(item);
            }

            foreach (var item in this.list)
            {
                this.mesh.Faces.AddTriangles(item.V1, item.V2, item.V3);
            }
            TriMeshUtil.FixIndex(mesh);
            TriMeshUtil.SetUpNormalVertex(mesh);
        }
예제 #24
0
        public static void RepairComplexHole(TriMesh mesh)
        {
            List <TriMesh.Vertex> hole = new List <TriMesh.Vertex>();

            TriMesh.Vertex[] faceVertices = new TriMesh.Vertex[3];



            while (true)//此循环只限单洞修补
            {
                //计算边界边的平均值
                #region 计算边界边的平均值
                hole = TriMeshUtil.RetrieveBoundarySingle(mesh);
                double   aver_l     = 0;
                double[] edgeLength = new double[hole.Count];
                for (int i = 0; i < hole.Count; i++)
                {
                    if (i == hole.Count - 1)
                    {
                        edgeLength[i] = Math.Sqrt(Math.Pow(hole[i].Traits.Position.x - hole[0].Traits.Position.x, 2) + Math.Pow(hole[i].Traits.Position.y - hole[0].Traits.Position.y, 2) + Math.Pow(hole[i].Traits.Position.z - hole[0].Traits.Position.z, 2));
                        break;
                    }
                    edgeLength[i] = Math.Sqrt(Math.Pow(hole[i].Traits.Position.x - hole[i + 1].Traits.Position.x, 2) + Math.Pow(hole[i].Traits.Position.y - hole[i + 1].Traits.Position.y, 2) + Math.Pow(hole[i].Traits.Position.z - hole[i + 1].Traits.Position.z, 2));
                }
                for (int i = 0; i < hole.Count; i++)
                {
                    aver_l += edgeLength[i];
                }
                aver_l = aver_l / hole.Count;
                #endregion

                hole = TriMeshUtil.RetrieveBoundarySingle(mesh);

                //计算角度值
                #region 计算角度值
                double[] angle = new double[hole.Count];
                double   a = 0, b = 0, c = 0;
                for (int i = 0; i < hole.Count; i++)
                {
                    if (i == 0)
                    {
                        a        = Math.Sqrt(Math.Pow(hole[hole.Count - 1].Traits.Position.x - hole[i + 1].Traits.Position.x, 2) + Math.Pow(hole[hole.Count - 1].Traits.Position.y - hole[i + 1].Traits.Position.y, 2) + Math.Pow(hole[hole.Count - 1].Traits.Position.z - hole[i + 1].Traits.Position.z, 2));
                        b        = Math.Sqrt(Math.Pow(hole[i].Traits.Position.x - hole[i + 1].Traits.Position.x, 2) + Math.Pow(hole[i].Traits.Position.y - hole[i + 1].Traits.Position.y, 2) + Math.Pow(hole[i].Traits.Position.z - hole[i + 1].Traits.Position.z, 2));
                        c        = Math.Sqrt(Math.Pow(hole[hole.Count - 1].Traits.Position.x - hole[i].Traits.Position.x, 2) + Math.Pow(hole[hole.Count - 1].Traits.Position.y - hole[i].Traits.Position.y, 2) + Math.Pow(hole[hole.Count - 1].Traits.Position.z - hole[i].Traits.Position.z, 2));
                        angle[i] = Math.Acos((b * b + c * c - a * a) / (2 * b * c));
                    }
                    else if (i == hole.Count - 1)
                    {
                        a        = Math.Sqrt(Math.Pow(hole[i - 1].Traits.Position.x - hole[0].Traits.Position.x, 2) + Math.Pow(hole[i - 1].Traits.Position.y - hole[0].Traits.Position.y, 2) + Math.Pow(hole[i - 1].Traits.Position.z - hole[0].Traits.Position.z, 2));
                        b        = Math.Sqrt(Math.Pow(hole[i].Traits.Position.x - hole[0].Traits.Position.x, 2) + Math.Pow(hole[i].Traits.Position.y - hole[0].Traits.Position.y, 2) + Math.Pow(hole[i].Traits.Position.z - hole[0].Traits.Position.z, 2));
                        c        = Math.Sqrt(Math.Pow(hole[i - 1].Traits.Position.x - hole[i].Traits.Position.x, 2) + Math.Pow(hole[i - 1].Traits.Position.y - hole[i].Traits.Position.y, 2) + Math.Pow(hole[i - 1].Traits.Position.z - hole[i].Traits.Position.z, 2));
                        angle[i] = Math.Acos((b * b + c * c - a * a) / (2 * b * c));
                    }
                    else
                    {
                        a        = Math.Sqrt(Math.Pow(hole[i - 1].Traits.Position.x - hole[i + 1].Traits.Position.x, 2) + Math.Pow(hole[i - 1].Traits.Position.y - hole[i + 1].Traits.Position.y, 2) + Math.Pow(hole[i - 1].Traits.Position.z - hole[i + 1].Traits.Position.z, 2));
                        b        = Math.Sqrt(Math.Pow(hole[i].Traits.Position.x - hole[i + 1].Traits.Position.x, 2) + Math.Pow(hole[i].Traits.Position.y - hole[i + 1].Traits.Position.y, 2) + Math.Pow(hole[i].Traits.Position.z - hole[i + 1].Traits.Position.z, 2));
                        c        = Math.Sqrt(Math.Pow(hole[i - 1].Traits.Position.x - hole[i].Traits.Position.x, 2) + Math.Pow(hole[i - 1].Traits.Position.y - hole[i].Traits.Position.y, 2) + Math.Pow(hole[i - 1].Traits.Position.z - hole[i].Traits.Position.z, 2));
                        angle[i] = Math.Acos((b * b + c * c - a * a) / (2 * b * c));
                    }
                }
                #endregion


                //取得最小的角度
                #region 取得最小的角度
                int min = 0;
                for (int i = 0; i < hole.Count - 1; i++)
                {
                    if (angle[i] < angle[i + 1])
                    {
                        min = i;
                    }
                    else
                    {
                        min = i + 1;
                    }
                }
                #endregion


                //求最小角度对应的边长
                #region 求最小角度对应的边长
                double temp = 0;
                if (min == hole.Count - 1)
                {
                    temp = Math.Sqrt(Math.Pow(hole[min - 1].Traits.Position.x - hole[0].Traits.Position.x, 2) + Math.Pow(hole[min - 1].Traits.Position.y - hole[0].Traits.Position.y, 2) + Math.Pow(hole[min - 1].Traits.Position.z - hole[0].Traits.Position.z, 2));
                }
                else if (min == 0)
                {
                    temp = Math.Sqrt(Math.Pow(hole[hole.Count - 1].Traits.Position.x - hole[min + 1].Traits.Position.x, 2) + Math.Pow(hole[hole.Count - 1].Traits.Position.y - hole[min + 1].Traits.Position.y, 2) + Math.Pow(hole[hole.Count - 1].Traits.Position.z - hole[min + 1].Traits.Position.z, 2));
                }
                else
                {
                    temp = Math.Sqrt(Math.Pow(hole[min - 1].Traits.Position.x - hole[min + 1].Traits.Position.x, 2) + Math.Pow(hole[min - 1].Traits.Position.y - hole[min + 1].Traits.Position.y, 2) + Math.Pow(hole[min - 1].Traits.Position.z - hole[min + 1].Traits.Position.z, 2));
                }
                #endregion


                //判断最小角对应的边与平均边界边长,并进行修补
                #region 判断最小角对应的边与平均边界边长,并进行修补
                if (temp > aver_l)
                {
                    if (min == hole.Count - 1)
                    {
                        faceVertices[0] = mesh.Vertices[hole[min].Index];
                        faceVertices[1] = mesh.Vertices[hole[0].Index];
                        faceVertices[2] = mesh.Vertices[hole[min - 1].Index];
                        mesh.Faces.AddTriangles(faceVertices);
                    }
                    else if (min == 0)
                    {
                        faceVertices[0] = mesh.Vertices[hole[min].Index];
                        faceVertices[1] = mesh.Vertices[hole[min + 1].Index];
                        faceVertices[2] = mesh.Vertices[hole[hole.Count - 1].Index];
                        mesh.Faces.AddTriangles(faceVertices);
                    }
                    else
                    {
                        faceVertices[0] = mesh.Vertices[hole[min].Index];
                        faceVertices[1] = mesh.Vertices[hole[min + 1].Index];
                        faceVertices[2] = mesh.Vertices[hole[min - 1].Index];
                        mesh.Faces.AddTriangles(faceVertices);
                    }
                }

                else
                {
                    if (min == hole.Count - 1)
                    {
                        Vector3D midPosition;
                        midPosition = (hole[min - 1].Traits.Position + hole[0].Traits.Position) / 2;
                        mesh.Vertices.Add(new VertexTraits(midPosition.x, midPosition.y, midPosition.z));

                        faceVertices[0] = mesh.Vertices[hole[min].Index];
                        faceVertices[1] = mesh.Vertices[mesh.Vertices.Count - 1];
                        faceVertices[2] = mesh.Vertices[hole[min - 1].Index];
                        mesh.Faces.AddTriangles(faceVertices);

                        faceVertices[0] = mesh.Vertices[hole[min].Index];
                        faceVertices[1] = mesh.Vertices[hole[0].Index];
                        faceVertices[2] = mesh.Vertices[mesh.Vertices.Count - 1];
                        mesh.Faces.AddTriangles(faceVertices);
                    }
                    else if (min == 0)
                    {
                        Vector3D midPosition;
                        midPosition = (hole[hole.Count - 1].Traits.Position + hole[min + 1].Traits.Position) / 2;
                        mesh.Vertices.Add(new VertexTraits(midPosition.x, midPosition.y, midPosition.z));

                        faceVertices[0] = mesh.Vertices[hole[min].Index];
                        faceVertices[1] = mesh.Vertices[mesh.Vertices.Count - 1];
                        faceVertices[2] = mesh.Vertices[hole[hole.Count - 1].Index];
                        mesh.Faces.AddTriangles(faceVertices);

                        faceVertices[0] = mesh.Vertices[hole[min].Index];
                        faceVertices[1] = mesh.Vertices[hole[min + 1].Index];
                        faceVertices[2] = mesh.Vertices[mesh.Vertices.Count - 1];
                        mesh.Faces.AddTriangles(faceVertices);
                    }
                    else
                    {
                        Vector3D midPosition;
                        midPosition = (hole[min - 1].Traits.Position + hole[min + 1].Traits.Position) / 2;
                        mesh.Vertices.Add(new VertexTraits(midPosition.x, midPosition.y, midPosition.z));

                        faceVertices[0] = mesh.Vertices[hole[min].Index];
                        faceVertices[1] = mesh.Vertices[mesh.Vertices.Count - 1];
                        faceVertices[2] = mesh.Vertices[hole[min - 1].Index];
                        mesh.Faces.AddTriangles(faceVertices);

                        faceVertices[0] = mesh.Vertices[hole[min].Index];
                        faceVertices[1] = mesh.Vertices[hole[min + 1].Index];
                        faceVertices[2] = mesh.Vertices[mesh.Vertices.Count - 1];
                        mesh.Faces.AddTriangles(faceVertices);
                    }
                }
                #endregion


                //更新边界点,并判断空洞是否完整
                #region 更新边界点,并判断空洞是否完整

                TriMeshUtil.FixIndex(mesh);
                hole = TriMeshUtil.RetrieveBoundarySingle(mesh);
                if (hole.Count < 3)
                {
                    break;
                }
                #endregion
            }
        }
예제 #25
0
        public VertexMap Cut(double move)
        {
            this.vertexMap = new VertexMap(this.mesh);
            this.edgeQueue = new Queue <VertexPair>();
            this.move      = move;

            foreach (var edge in this.mesh.Edges)
            {
                if (edge.Traits.SelectedFlag != 0)
                {
                    this.edgeQueue.Enqueue(new VertexPair(edge.Vertex0, edge.Vertex1));
                }
            }

            bool boundary = false;

            foreach (var edge in this.edgeQueue)
            {
                if (edge.Src.OnBoundary || edge.Dst.OnBoundary)
                {
                    boundary = true;
                    break;
                }
            }

            if (!boundary)
            {
                this.CutStart();
            }

            int count = 1;

            while (this.edgeQueue.Count != 0 && count < this.edgeQueue.Count)
            {
                VertexPair   pair = this.edgeQueue.Dequeue();
                TriMesh.Edge edge = pair.Src.FindEdgeTo(pair.Dst);
                if (edge != null)
                {
                    if (this.Cut(edge))
                    {
                        count = 0;
                    }
                    else
                    {
                        this.edgeQueue.Enqueue(pair);
                        count++;
                    }
                }
                else
                {
                    TriMesh.Vertex[] map1 = this.vertexMap.GetOther(pair.Src, false);
                    TriMesh.Vertex[] map2 = this.vertexMap.GetOther(pair.Dst, false);

                    for (int m = 0; m < map1.Length; m++)
                    {
                        this.edgeQueue.Enqueue(new VertexPair(map1[m], pair.Dst));
                    }

                    for (int n = 0; n < map2.Length; n++)
                    {
                        this.edgeQueue.Enqueue(new VertexPair(pair.Src, map2[n]));
                    }

                    for (int m = 0; m < map1.Length; m++)
                    {
                        for (int n = 0; n < map2.Length; n++)
                        {
                            this.edgeQueue.Enqueue(new VertexPair(map1[m], map2[n]));
                        }
                    }
                    count = 0;
                }
            }
            TriMeshUtil.FixIndex(mesh);

            return(this.vertexMap);
        }