public static void RepaireOneHole(TriMesh mesh) { List <TriMesh.Vertex> hole = TriMeshUtil.RetrieveBoundarySingle(mesh); RepaireHole(hole); TriMeshUtil.FixIndex(mesh); }
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); }
public static List <TriMesh.Vertex> RetrieveTwoFixBoundaryPoint(TriMesh mesh) { List <TriMesh.Vertex> two = new List <HalfEdgeMesh.Vertex>(); List <TriMesh.Vertex> bound = TriMeshUtil.RetrieveBoundarySingle(mesh); foreach (TriMesh.Vertex vertex in bound) { if (vertex.Traits.SelectedFlag > 0) { two.Add(vertex); } } if (two.Count < 2) { two.Add(bound[0]); two.Add(bound[bound.Count / 2]); } return(two); }
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 } }