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)); }
/// <summary> /// 两端点都在边界上 /// </summary> /// <param name="edge"></param> void CutBothBoundary(TriMesh.Edge edge) { TriMesh.HalfEdge hf = edge.HalfEdge0; TriMesh.HalfEdge[] leftArr = this.GetToBoundaryAntiClockWise(hf); TriMesh.HalfEdge[] rightArr = this.GetToBoundaryClockWise(hf.Next); for (int i = 1; i < leftArr.Length; i++) { TriMeshModify.RemoveEdge(leftArr[i].Edge); } for (int i = 0; i < rightArr.Length; i++) { TriMeshModify.RemoveEdge(rightArr[i].Edge); } Vector3D vec = this.GetMoveVector(hf.Opposite); TriMesh.Vertex left = this.Clone(hf.FromVertex, vec); TriMesh.Vertex right = this.Clone(hf.ToVertex, vec); for (int i = 2; i < leftArr.Length; i++) { this.mesh.Faces.AddTriangles(left, leftArr[i - 1].ToVertex, leftArr[i].ToVertex); } for (int i = 1; i < rightArr.Length; i++) { this.mesh.Faces.AddTriangles(right, rightArr[i].ToVertex, rightArr[i - 1].ToVertex); } this.mesh.Faces.AddTriangles(left, right, leftArr[1].ToVertex); }
public void Remove(IEnumerable <TriMesh.Face> region) { foreach (var f in region) { TriMeshModify.RemoveFace(f); } foreach (var e in removeEdge) { TriMeshModify.RemoveEdge(e); } foreach (var v in removeVertex) { TriMeshModify.RemoveVertex(v); } }
bool RemoveVertex3(TriMesh.Vertex top) { /* * top * / \ * / \ * /face \ * left-----right * \ / * \ / * \ / * buttom */ TriMesh.HalfEdge leftToRight = null; //找到一个可用的面,top顶点的对边不在边界上 foreach (var item in top.HalfEdges) { if (!item.Next.OnBoundary) { leftToRight = item.Next; break; } } if (leftToRight == null) { return(false); } TriMesh.Vertex left, buttom, right, mid; left = leftToRight.FromVertex; right = leftToRight.ToVertex; mid = this.AddMid(left, right); buttom = leftToRight.Opposite.Next.ToVertex; TriMeshModify.RemoveEdge(leftToRight.Edge); //连接中点,把2个三角形拆成4个 this.CreateFace(top, left, mid); this.CreateFace(top, mid, right); this.CreateFace(buttom, right, mid); this.CreateFace(buttom, mid, left); return(true); }
void CutInner(TriMesh.HalfEdge cur, TriMesh.HalfEdge next) { TriMesh.Vertex share1 = cur.FromVertex; TriMesh.Vertex share2 = next.ToVertex; TriMesh.Vertex mid = cur.ToVertex; Vector3D normal = TriMeshUtil.ComputeNormalFace(cur.Face); Vector3D vec = next.ToVertex.Traits.Position - cur.FromVertex.Traits.Position; Vector3D dir = normal.Cross(vec).Normalize(); TriMesh.Vertex v2 = TriMeshModify.VertexSplit(mid, share1, share2, mid.Traits.Position - dir * move, mid.Traits.Position + dir * move); TriMesh.HalfEdge hf = mid.FindHalfedgeTo(v2); TriMeshModify.RemoveEdge(hf.Edge); this.vertexMap.Add(mid, v2); }
/// <summary> /// 源点在边界上 /// </summary> /// <param name="hf"></param> void CutFromBoundary(TriMesh.HalfEdge hf) { TriMesh.HalfEdge[] arr = this.GetToBoundaryAntiClockWise(hf); for (int i = 1; i < arr.Length; i++) { TriMeshModify.RemoveEdge(arr[i].Edge); } Vector3D vec = this.GetMoveVector(hf.Opposite); TriMesh.Vertex v2 = this.Clone(hf.FromVertex, vec); for (int i = 1; i < arr.Length; i++) { this.mesh.Faces.AddTriangles(v2, arr[i - 1].ToVertex, arr[i].ToVertex); } }
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); }
public bool RemoveVertex4(TriMesh.Vertex cur) { /* cur * vl vr /\ * |\ /| / \ * | \ / | / \ * | \ / | / \ * | cur | / \ * | / \ | / \ * | / \ | lm-----sm-----rm * |/face \| / \ /\ / \ * left-----right / \ / \ / \ * \ / / sl____sr \ * \ / / \ / \ * \ / / \ / \ * vm / \/ \ * left----------mm----------right * * 中部三角形放大图 */ TriMesh.HalfEdge curToLeft = null; //找到一个可用的面,这个面的3个邻面必须都存在 foreach (var item in cur.HalfEdges) { if (item.Face != null && item.Face.FaceCount == 3) { curToLeft = item; break; } } if (curToLeft == null) { return(false); } TriMesh.Vertex left, right, vl, vr, vm, lm, sm, rm, sl, sr, mm; TriMesh.HalfEdge leftToRight = curToLeft.Next; TriMesh.HalfEdge rightToCur = leftToRight.Next; left = curToLeft.ToVertex; right = leftToRight.ToVertex; vl = curToLeft.Opposite.Next.ToVertex; vr = rightToCur.Opposite.Next.ToVertex; vm = leftToRight.Opposite.Next.ToVertex; lm = this.AddMid(left, cur); rm = this.AddMid(right, cur); mm = this.AddMid(left, right); sm = this.AddMid(lm, rm); sl = this.AddMid(lm, mm); sr = this.AddMid(mm, rm); TriMeshModify.RemoveEdge(curToLeft.Edge); TriMeshModify.RemoveEdge(leftToRight.Edge); TriMeshModify.RemoveEdge(rightToCur.Edge); //图1外圈三角形 this.CreateFace(vl, left, lm); this.CreateFace(vl, lm, cur); this.CreateFace(vr, cur, rm); this.CreateFace(vr, rm, right); this.CreateFace(mm, left, vm); this.CreateFace(mm, vm, right); //图2外圈三角形 this.CreateFace(cur, lm, sm); this.CreateFace(cur, sm, rm); this.CreateFace(lm, left, sl); this.CreateFace(sl, left, mm); this.CreateFace(rm, sr, right); this.CreateFace(sr, mm, right); //图2内圈三角形 this.CreateFace(sm, lm, sl); this.CreateFace(sm, sr, rm); this.CreateFace(sm, sl, sr); this.CreateFace(sl, mm, sr); return(true); }
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); }