예제 #1
0
        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));
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        /// <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);
            }
        }
예제 #7
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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        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);
        }