public static TriMesh.HalfEdge Split(TriMesh.HalfEdge hf, Vector3D v1Pos, Vector3D v2Pos) { TriMesh mesh = (TriMesh)hf.Mesh; List <TriMesh.HalfEdge> list = new List <HalfEdgeMesh.HalfEdge>(); TriMesh.HalfEdge cur = hf; list.Add(cur); do { cur = cur.Opposite.Next; list.Add(cur); } while (cur.Opposite.Face != null && cur != hf); for (int i = 1; i < list.Count; i++) { TriMeshModify.RemoveEdge(list[i].Edge); } hf.FromVertex.Traits.Position = v1Pos; TriMesh.Vertex v2 = new HalfEdgeMesh.Vertex(new VertexTraits(v2Pos)); mesh.AppendToVertexList(v2); for (int i = 1; i < list.Count; i++) { mesh.Faces.AddTriangles(list[i - 1].ToVertex, v2, list[i].ToVertex); } mesh.Faces.AddTriangles(list[0].ToVertex, hf.FromVertex, v2); return(hf.FromVertex.FindHalfedgeTo(v2)); }
public static void InverseFace(TriMesh mesh) { List<TriMesh.Vertex[]> faces = new List<HalfEdgeMesh.Vertex[]>(); foreach (TriMesh.Face face in mesh.Faces) { TriMesh.HalfEdge hf = face.HalfEdge; TriMesh.Vertex[] arr = new TriMesh.Vertex[]{ hf.Next.ToVertex, hf.ToVertex, hf.FromVertex }; faces.Add(arr); } TriMesh.Vertex[] vertices = new TriMesh.Vertex[mesh.Vertices.Count]; for (int i = 0; i < mesh.Vertices.Count; i++) { vertices[i] = mesh.Vertices[i]; vertices[i].HalfEdge = null; } mesh.Clear(); foreach (var v in vertices) { mesh.AppendToVertexList(v); } foreach (var face in faces) { mesh.Faces.AddTriangles(face); } }
public static List <TriMesh> SeperateComponent(TriMesh mesh) { List <TriMesh> meshes = new List <TriMesh>(); Dictionary <int, TriMesh.Vertex> map = new Dictionary <int, HalfEdgeMesh.Vertex>(); bool[] visited = new bool[mesh.Faces.Count]; Queue <TriMesh.Face> queue = new Queue <HalfEdgeMesh.Face>(); TriMesh newMesh = new TriMesh(); queue.Enqueue(mesh.Faces[0]); visited[0] = true; while (queue.Count != 0) { TriMesh.Face face = queue.Dequeue(); foreach (var hf in face.Halfedges) { if (!map.ContainsKey(hf.ToVertex.Index)) { TriMesh.Vertex v = new HalfEdgeMesh.Vertex(new VertexTraits(hf.ToVertex.Traits.Position)); newMesh.AppendToVertexList(v); map[hf.ToVertex.Index] = v; } if (hf.Opposite.Face != null && !visited[hf.Opposite.Face.Index]) { queue.Enqueue(hf.Opposite.Face); visited[hf.Opposite.Face.Index] = true; } } newMesh.Faces.AddTriangles( map[face.HalfEdge.FromVertex.Index], map[face.HalfEdge.ToVertex.Index], map[face.HalfEdge.Next.ToVertex.Index]); if (queue.Count == 0) { meshes.Add(newMesh); for (int i = 0; i < visited.Length; i++) { if (!visited[i]) { newMesh = new TriMesh(); queue.Enqueue(mesh.Faces[i]); visited[i] = true; break; } } } } foreach (TriMesh child in meshes) { TriMeshUtil.SetUpNormalVertex(child); } return(meshes); }
public static TriMesh CreateGrid(int m, int n, double lengthx, double lengthy) { TriMesh mesh = new TriMesh(); TriMesh.Vertex[,] arr = new HalfEdgeMesh.Vertex[m, n]; double x0 = -m * lengthx / 2d; double y0 = -n * lengthy / 2d; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { arr[i, j] = new HalfEdgeMesh.Vertex(); arr[i, j].Traits = new VertexTraits(x0 + i * lengthx, y0 + j * lengthy, 0d); mesh.AppendToVertexList(arr[i, j]); } } for (int i = 0; i < m - 1; i++) { for (int j = 0; j < n - 1; j++) { mesh.Faces.AddTriangles(arr[i + 1, j], arr[i, j + 1], arr[i, j]); mesh.Faces.AddTriangles(arr[i + 1, j], arr[i + 1, j + 1], arr[i, j + 1]); } } return(mesh); }
TriMesh Create(IEnumerable <TriMesh.Face> region) { TriMesh newMesh = new TriMesh(); foreach (var f in region) { TriMesh.Vertex[] arr = new HalfEdgeMesh.Vertex[3]; int i = 0; foreach (var v in f.Vertices) { if (!this.vMap.ContainsKey(v)) { TriMesh.Vertex newV = new HalfEdgeMesh.Vertex(new VertexTraits(v.Traits.Position)); this.vMap[v] = newV; newMesh.AppendToVertexList(newV); } arr[i++] = this.vMap[v]; } newMesh.Faces.AddTriangles(arr); this.fFlag[f.Index] = true; } return(newMesh); }
public static void InverseFace(TriMesh mesh) { List <TriMesh.Vertex[]> faces = new List <HalfEdgeMesh.Vertex[]>(); foreach (TriMesh.Face face in mesh.Faces) { TriMesh.HalfEdge hf = face.HalfEdge; TriMesh.Vertex[] arr = new TriMesh.Vertex[] { hf.Next.ToVertex, hf.ToVertex, hf.FromVertex }; faces.Add(arr); } TriMesh.Vertex[] vertices = new TriMesh.Vertex[mesh.Vertices.Count]; for (int i = 0; i < mesh.Vertices.Count; i++) { vertices[i] = mesh.Vertices[i]; vertices[i].HalfEdge = null; } mesh.Clear(); foreach (var v in vertices) { mesh.AppendToVertexList(v); } foreach (var face in faces) { mesh.Faces.AddTriangles(face); } }
public static List<TriMesh> SeperateComponent(TriMesh mesh) { List<TriMesh> meshes = new List<TriMesh>(); Dictionary<int, TriMesh.Vertex> map = new Dictionary<int, HalfEdgeMesh.Vertex>(); bool[] visited = new bool[mesh.Faces.Count]; Queue<TriMesh.Face> queue = new Queue<HalfEdgeMesh.Face>(); TriMesh newMesh = new TriMesh(); queue.Enqueue(mesh.Faces[0]); visited[0] = true; while (queue.Count != 0) { TriMesh.Face face = queue.Dequeue(); foreach (var hf in face.Halfedges) { if (!map.ContainsKey(hf.ToVertex.Index)) { TriMesh.Vertex v = new HalfEdgeMesh.Vertex(new VertexTraits(hf.ToVertex.Traits.Position)); newMesh.AppendToVertexList(v); map[hf.ToVertex.Index] = v; } if (hf.Opposite.Face != null && !visited[hf.Opposite.Face.Index]) { queue.Enqueue(hf.Opposite.Face); visited[hf.Opposite.Face.Index] = true; } } newMesh.Faces.AddTriangles( map[face.HalfEdge.FromVertex.Index], map[face.HalfEdge.ToVertex.Index], map[face.HalfEdge.Next.ToVertex.Index]); if (queue.Count == 0) { meshes.Add(newMesh); for (int i = 0; i < visited.Length; i++) { if (!visited[i]) { newMesh = new TriMesh(); queue.Enqueue(mesh.Faces[i]); visited[i] = true; break; } } } } foreach (TriMesh child in meshes) { TriMeshUtil.SetUpNormalVertex(child); } return meshes ; }
public static TriMesh.Vertex VertexSplit(TriMesh.Vertex v1, TriMesh.Vertex share1, TriMesh.Vertex share2, Vector3D v1Position, Vector3D v2Position, int fixedIndex) { TriMesh.HalfEdge[] hfs = FindGroup(v1, share1, share2); TriMesh mesh = (TriMesh)v1.Mesh; v1.Traits.Position = v1Position; v1.HalfEdge = hfs[0]; TriMesh.Vertex v2 = new TriMesh.Vertex(); v2.Traits = new VertexTraits(v2Position); v2.Traits.FixedIndex = fixedIndex; v2.HalfEdge = hfs[1]; mesh.AppendToVertexList(v2); for (int i = 0; i < hfs.Length - 1; i++) { hfs[i].Opposite.ToVertex = v2; } TriMesh.HalfEdge[] triangle1 = AddInnerTriangle(mesh, v1, v2, share1); InsertEdge(mesh, triangle1[1], hfs[0]); TriMesh.HalfEdge[] triangle2 = AddInnerTriangle(mesh, v2, v1, share2); InsertEdge(mesh, triangle2[1], hfs[hfs.Length - 1]); TriMesh.Edge edge = new TriMesh.Edge(); edge.HalfEdge0 = triangle1[0]; triangle1[0].Edge = edge; triangle2[0].Edge = edge; triangle1[0].Opposite = triangle2[0]; triangle2[0].Opposite = triangle1[0]; mesh.AppendToEdgeList(edge); return(v2); }
public static TriMesh CreateGrid(int m, int n, double lengthx,double lengthy) { TriMesh mesh = new TriMesh(); TriMesh.Vertex[,] arr = new HalfEdgeMesh.Vertex[m, n]; double x0 = -m * lengthx / 2d; double y0 = -n * lengthy / 2d; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { arr[i, j] = new HalfEdgeMesh.Vertex(); arr[i, j].Traits = new VertexTraits(x0 + i * lengthx, y0 + j * lengthy, 0d); mesh.AppendToVertexList(arr[i, j]); } } for (int i = 0; i < m - 1; i++) { for (int j = 0; j < n - 1; j++) { mesh.Faces.AddTriangles(arr[i + 1, j], arr[i, j + 1], arr[i, j]); mesh.Faces.AddTriangles(arr[i + 1, j], arr[i + 1, j + 1], arr[i, j + 1]); } } return mesh; }
public TriMesh Cut(IEnumerable<TriMesh.Vertex> region) { Dictionary<int, TriMesh.Vertex> vMap = new Dictionary<int, HalfEdgeMesh.Vertex>(); Dictionary<int, bool> fFlag = new Dictionary<int, bool>(); TriMesh newMesh = new TriMesh(); foreach (var v in region) { TriMesh.Vertex newV = new HalfEdgeMesh.Vertex( new VertexTraits(v.Traits.Position)); vMap[v.Index] = newV; newMesh.AppendToVertexList(newV); } foreach (var f in this.mesh.Faces) { bool inner = true; foreach (var v in f.Vertices) { if (!vMap.ContainsKey(v.Index)) { inner = false; break; } } if (inner) { TriMesh.HalfEdge hf = f.HalfEdge; newMesh.Faces.AddTriangles( vMap[hf.FromVertex.Index], vMap[hf.ToVertex.Index], vMap[hf.Next.ToVertex.Index]); fFlag[f.Index] = true; } } List<TriMesh.Edge> remove = new List<HalfEdgeMesh.Edge>(); foreach (var e in this.mesh.Edges) { if (fFlag.ContainsKey(e.Face0.Index) && fFlag.ContainsKey(e.Face1.Index)) { remove.Add(e); } } foreach (var e in remove) { TriMeshModify.RemoveEdge(e); } foreach (var v in region) { bool inner = true; foreach (var round in v.Vertices) { if (!vMap.ContainsKey(round.Index)) { inner = false; } } if (inner) { this.mesh.RemoveVertex(v); } } return newMesh; }
TriMesh Create(IEnumerable<TriMesh.Face> region) { TriMesh newMesh = new TriMesh(); foreach (var f in region) { TriMesh.Vertex[] arr = new HalfEdgeMesh.Vertex[3]; int i = 0; foreach (var v in f.Vertices) { if (!this.vMap.ContainsKey(v)) { TriMesh.Vertex newV = new HalfEdgeMesh.Vertex(new VertexTraits(v.Traits.Position)); this.vMap[v] = newV; newMesh.AppendToVertexList(newV); } arr[i++] = this.vMap[v]; } newMesh.Faces.AddTriangles(arr); this.fFlag[f.Index] = true; } return newMesh; }
public TriMesh.Vertex VertexSplit1(TriMesh.Vertex v, TriMesh.Vertex vshard1, TriMesh.Vertex vshard2, Vector3D v1Position, Vector3D v2Position, int v2FixedIndex) { //1.Get two group of verties TriMesh.HalfEdge[] processGroup = FindGroup(v, vshard1, vshard2); TriMesh mesh = (TriMesh)v.Mesh; TriMesh.Vertex v1 = null; TriMesh.Vertex v2 = null; TriMesh.Vertex newVertex = null; v1 = v; v.Traits.Position = v1Position; v2 = new TriMesh.Vertex(); v2.Traits = new VertexTraits(Vector3D.Zero); newVertex = v2; newVertex.Traits.FixedIndex = v2FixedIndex; v2.Mesh = v.Mesh; v2.Traits.Position = v2Position; //2.Process the Topology TriMesh.HalfEdge hf1Origin = processGroup[0]; TriMesh.HalfEdge hf2Origin = processGroup[processGroup.Length - 1]; //Add new edge TriMesh.HalfEdge hf3 = new TriMesh.HalfEdge(); TriMesh.HalfEdge hf3Oppsite = new TriMesh.HalfEdge(); TriMesh.Edge edge = new TriMesh.Edge(); hf3.Opposite = hf3Oppsite; hf3Oppsite.Opposite = hf3; edge.HalfEdge0 = hf3; edge.HalfEdge1 = hf3Oppsite; hf3.Edge = edge; hf3Oppsite.Edge = edge; hf3.ToVertex = v2; hf3Oppsite.ToVertex = v1; //Handle hf1Origin which is outter hafledge [INNER] TriMesh.HalfEdge hf1 = new TriMesh.HalfEdge(); hf1.Opposite = hf1Origin; hf1.ToVertex = v1; TriMesh.HalfEdge hf1Other = new TriMesh.HalfEdge(); hf1Other.Opposite = hf1Origin.Opposite; hf1Other.ToVertex = hf1Origin.ToVertex; hf1.Previous = hf1Other; hf1Other.Next = hf1; hf1.Next = hf3; hf3.Previous = hf1; hf1Other.Previous = hf3; hf3.Next = hf1Other; //Handle hf2Origin which is inner hafledge [INNER] TriMesh.HalfEdge hf2 = new TriMesh.HalfEdge(); hf2.Opposite = hf2Origin; hf2.ToVertex = v2; TriMesh.HalfEdge hf2Other = new TriMesh.HalfEdge(); hf2Other.Opposite = hf2Origin.Opposite; hf2Other.ToVertex = hf2Origin.ToVertex; hf2.Previous = hf2Other; hf2Other.Next = hf2; hf2.Next = hf3Oppsite; hf3Oppsite.Previous = hf2; hf2Other.Previous = hf3Oppsite; hf3Oppsite.Next = hf2Other; TriMesh.Face face1 = new TriMesh.Face(); TriMesh.Face face2 = new TriMesh.Face(); face1.HalfEdge = hf3; hf3.Face = face1; hf1.Face = face1; hf1Other.Face = face1; face2.HalfEdge = hf3Oppsite; hf3Oppsite.Face = face2; hf2.Face = face2; hf2Other.Face = face2; //Process the outside TriMesh.Edge edge1 = new TriMesh.Edge(); TriMesh.HalfEdge hf1OriginOppsite = hf1Origin.Opposite; hf1Origin.Opposite = hf1; hf1.Edge = hf1Origin.Edge; hf1OriginOppsite.Opposite = hf1Other; hf1OriginOppsite.ToVertex = v2; hf1OriginOppsite.Edge = edge1; hf1Other.Edge = edge1; edge1.HalfEdge0 = hf1Other; edge1.HalfEdge1 = hf1OriginOppsite; TriMesh.Edge edge2 = new TriMesh.Edge(); TriMesh.HalfEdge hf2OriginOppsite = hf2Origin.Opposite; hf2Origin.Opposite = hf2; hf2.Edge = hf2Origin.Edge; hf2OriginOppsite.Opposite = hf2Other; hf2OriginOppsite.ToVertex = v1; hf2OriginOppsite.Edge = edge2; hf2Other.Edge = edge2; edge2.HalfEdge0 = hf2Other; edge2.HalfEdge1 = hf2OriginOppsite; v1.HalfEdge = hf1Origin; v2.HalfEdge = hf2Origin; mesh.AppendToEdgeList(edge); mesh.AppendToEdgeList(edge1); mesh.AppendToEdgeList(edge2); mesh.AppendToFaceList(face1); mesh.AppendToFaceList(face2); mesh.AppendToHalfedgeList(hf1); mesh.AppendToHalfedgeList(hf1Other); mesh.AppendToHalfedgeList(hf2); mesh.AppendToHalfedgeList(hf2Other); mesh.AppendToHalfedgeList(hf3); mesh.AppendToHalfedgeList(hf3Oppsite); mesh.AppendToVertexList(newVertex); for (int i = 1; i < processGroup.Length - 1; i++) { processGroup[i].Opposite.ToVertex = newVertex; } //mesh.FixIndex(); return(newVertex); }
public TriMesh Cut(IEnumerable <TriMesh.Vertex> region) { Dictionary <int, TriMesh.Vertex> vMap = new Dictionary <int, HalfEdgeMesh.Vertex>(); Dictionary <int, bool> fFlag = new Dictionary <int, bool>(); TriMesh newMesh = new TriMesh(); foreach (var v in region) { TriMesh.Vertex newV = new HalfEdgeMesh.Vertex( new VertexTraits(v.Traits.Position)); vMap[v.Index] = newV; newMesh.AppendToVertexList(newV); } foreach (var f in this.mesh.Faces) { bool inner = true; foreach (var v in f.Vertices) { if (!vMap.ContainsKey(v.Index)) { inner = false; break; } } if (inner) { TriMesh.HalfEdge hf = f.HalfEdge; newMesh.Faces.AddTriangles( vMap[hf.FromVertex.Index], vMap[hf.ToVertex.Index], vMap[hf.Next.ToVertex.Index]); fFlag[f.Index] = true; } } List <TriMesh.Edge> remove = new List <HalfEdgeMesh.Edge>(); foreach (var e in this.mesh.Edges) { if (fFlag.ContainsKey(e.Face0.Index) && fFlag.ContainsKey(e.Face1.Index)) { remove.Add(e); } } foreach (var e in remove) { TriMeshModify.RemoveEdge(e); } foreach (var v in region) { bool inner = true; foreach (var round in v.Vertices) { if (!vMap.ContainsKey(round.Index)) { inner = false; } } if (inner) { this.mesh.RemoveVertex(v); } } return(newMesh); }