Пример #1
0
        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);
            }
        }
Пример #2
0
        private TriMesh.HalfEdge[] FindSaddleExtreme(TriMesh.Vertex v, bool maxOrMin)
        {
            List <TriMesh.HalfEdge> all = new List <HalfEdgeMesh.HalfEdge>();

            TriMesh.HalfEdge n2p = this.FindN2P(v);
            v.HalfEdge = n2p;
            List <TriMesh.HalfEdge> part = new List <HalfEdgeMesh.HalfEdge>();
            double mid = this.function[v.Index];

            foreach (TriMesh.HalfEdge hf in v.HalfEdges)
            {
                double round = this.function[hf.ToVertex.Index];
                if (this.Compare(round, mid, maxOrMin))
                {
                    part.Add(hf);
                }
                else
                {
                    if (part.Count != 0)
                    {
                        all.Add(this.FindExtreme(part, maxOrMin));
                    }
                    part.Clear();
                }
            }
            if (part.Count != 0)
            {
                all.Add(this.FindExtreme(part, maxOrMin));
            }
            return(all.ToArray());
        }
Пример #3
0
        public PrincipalCurvature ComputePrincipalCurvature(TriMesh.Vertex v)
        {
            Vector3D sum = Vector3D.Zero;
            Vector3D mid = v.Traits.Position;

            foreach (var hf in v.HalfEdges)
            {
                Vector3D buttom = hf.ToVertex.Traits.Position;
                Vector3D left   = hf.Opposite.Next.ToVertex.Traits.Position;
                Vector3D right  = hf.Next.ToVertex.Traits.Position;
                double   cota   = (mid - left).Dot(buttom - left) / (mid - left).Cross(buttom - left).Length();
                double   cotb   = (mid - right).Dot(buttom - right) / (mid - right).Cross(buttom - right).Length();
                sum += (cota + cotb) * (this.Normal[v.Index] - this.Normal[hf.ToVertex.Index]);
            }
            double   mixedArea = TriMeshUtil.ComputeAreaMixed(v);
            Vector3D laplace   = sum / mixedArea / 2d;
            double   square    = -laplace.Dot(this.Normal[v.Index]);
            double   k         = this.K[v.Index].Length();
            double   delta     = -k * k + 2d * square;

            if (delta < 0d)
            {
                delta = 0d;
            }
            PrincipalCurvature pc = new PrincipalCurvature();

            pc.max = (k + Math.Pow(delta, 0.5)) / 2d;
            pc.min = (k - Math.Pow(delta, 0.5)) / 2d;
            return(pc);
        }
Пример #4
0
        public TriMesh CreateSquareSpoke(int length, int width)
        {
            TriMesh mesh = new TriMesh();
            double  x0   = -this.GridSizeX * length / 2d;
            double  y0   = -this.GridSizeX * width / 2d;
            double  z0   = 0;
            double  d    = this.GridSizeX / 2;
            int     t    = 4;

            TriMesh.Vertex[,] v = new TriMesh.Vertex[length + 1, width + 1];
            for (int i = 0; i < length + 1; i++)
            {
                for (int j = 0; j < width + 1; j++)
                {
                    double x = x0 + this.GridSizeX * i;
                    double y = y0 + this.GridSizeX * j;
                    int    r = i % t == j % t ? i % t : 0;
                    double z = z0 - (Math.Abs(r - t / 2) - t / 2) * d;
                    v[i, j] = mesh.Vertices.Add(new VertexTraits(x, y, z));
                }
            }

            for (int i = 0; i < length; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    mesh.Faces.AddTriangles(v[i, j], v[i + 1, j], v[i + 1, j + 1], v[i, j + 1]);
                }
            }
            TriMeshUtil.SetUpNormalVertex(mesh);
            return(mesh);
        }
Пример #5
0
 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);
     }
 }
Пример #6
0
        public TriMesh CreateSquare(int length, int width)
        {
            TriMesh mesh = new TriMesh();
            double  x0   = -this.GridSizeX * length / 2d;
            double  y0   = -this.GridSizeX * width / 2d;
            double  z0   = 0;
            double  d    = this.GridSizeX / 2;

            TriMesh.Vertex[,] v = new TriMesh.Vertex[length + 1, width + 1];
            for (int i = 0; i < length + 1; i++)
            {
                for (int j = 0; j < width + 1; j++)
                {
                    double x = x0 + this.GridSizeX * i;
                    double y = y0 + this.GridSizeX * j;
                    double z = i % 2 == 1 && j % 2 == 1 ? d : z0;
                    v[i, j] = mesh.Vertices.Add(new VertexTraits(x, y, z));
                }
            }

            for (int i = 0; i < length; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    mesh.Faces.AddTriangles(v[i, j], v[i + 1, j], v[i + 1, j + 1], v[i, j + 1]);
                }
            }
            TriMeshUtil.SetUpNormalVertex(mesh);
            return(mesh);
        }
Пример #7
0
        public static void GrowByVertexArea(TriMesh mesh)
        {
            Queue <TriMesh.Vertex> queue = new Queue <HalfEdgeMesh.Vertex>();

            double[] avgArea = new double[mesh.Vertices.Count];
            foreach (var v in mesh.Vertices)
            {
                avgArea[v.Index] = TriMeshUtil.ComputeAreaOneRing(v);
                if (v.Traits.SelectedFlag != 0)
                {
                    queue.Enqueue(v);
                }
            }

            double k = 0.896;

            while (queue.Count != 0)
            {
                TriMesh.Vertex center = queue.Dequeue();
                foreach (var round in center.Vertices)
                {
                    if (round.Traits.SelectedFlag == 0)
                    {
                        if (Math.Abs(avgArea[center.Index] -
                                     avgArea[round.Index]) < k * avgArea[center.Index])
                        {
                            round.Traits.SelectedFlag = center.Traits.SelectedFlag;
                            queue.Enqueue(round);
                        }
                    }
                }
            }
        }
Пример #8
0
        TriMesh.Edge CreateNewEdge(TriMesh.Vertex from, TriMesh.Vertex to)
        {
            TriMesh mesh = (TriMesh)from.Mesh;

            // Create new edge
            TriMesh.Edge edge = new TriMesh.Edge();
            mesh.AppendToEdgeList(edge);
            // Create new halfedges
            TriMesh.HalfEdge hf0 = new TriMesh.HalfEdge();
            mesh.AppendToHalfedgeList(hf0);
            hf0.Opposite = new TriMesh.HalfEdge();
            mesh.AppendToHalfedgeList(hf0.Opposite);
            // Connect opposite halfedge to inner halfedge
            hf0.Opposite.Opposite = hf0;
            // Connect edge to halfedges
            edge.HalfEdge0 = hf0;
            // Connect halfedges to edge
            hf0.Edge          = edge;
            hf0.Opposite.Edge = edge;
            // Connect halfedges to vertices
            hf0.ToVertex          = to;
            hf0.Opposite.ToVertex = from;
            // Connect vertex to outgoing halfedge if it doesn't have one yet
            if (from.HalfEdge == null)
            {
                from.HalfEdge = hf0;
            }
            return(edge);
        }
Пример #9
0
 public bool Forward()
 {
     if (this.index < this.method.Logs.Count)
     {
         EdgeContext    ctx   = this.method.Logs[this.index];
         TriMesh.Vertex left  = null;
         TriMesh.Vertex right = null;
         foreach (var v in this.Mesh.Vertices)
         {
             if (v.Index == ctx.Left)
             {
                 left = v;
             }
             else if (v.Index == ctx.Right)
             {
                 right = v;
             }
         }
         TriMesh.Edge edge = left.FindEdgeTo(right);
         MergeEdge.Merge(edge, ctx.MidPos);
         index++;
         return(true);
     }
     else
     {
         int r = this.method.Run(this.Mesh.Faces.Count - 1);
         index += r;
         return(false);
     }
 }
Пример #10
0
        public static void Split(TriMesh mesh, EdgeContext ctx)
        {
            TriMesh.Vertex left   = null;
            TriMesh.Vertex top    = null;
            TriMesh.Vertex bottom = null;

            foreach (var v in mesh.Vertices)
            {
                if (v.Index == ctx.Left)
                {
                    left = v;
                }
                else if (v.Index == ctx.Top)
                {
                    top = v;
                }
                else if (v.Index == ctx.Bottom)
                {
                    bottom = v;
                }
            }

            TriMesh.Vertex   right = TriMeshModify.VertexSplit(left, top, bottom, ctx.LeftPos, ctx.RightPos);
            TriMesh.HalfEdge hf    = left.FindHalfedgeTo(right);
            right.Index                     = ctx.Right;
            hf.Next.ToVertex.Index          = ctx.Top;
            hf.Opposite.Next.ToVertex.Index = ctx.Bottom;
        }
Пример #11
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);
        }
Пример #12
0
        public TriMesh CreateSquare(int length, int width)
        {
            TriMesh mesh = new TriMesh();
            double x0 = -this.GridSizeX * length / 2d;
            double y0 = -this.GridSizeX * width / 2d;
            double z0 = 0;
            double d = this.GridSizeX / 2;

            TriMesh.Vertex[,] v = new TriMesh.Vertex[length + 1, width + 1];
            for (int i = 0; i < length + 1; i++)
            {
                for (int j = 0; j < width + 1; j++)
                {
                    double x=x0 + this.GridSizeX * i;
                    double y=y0 + this.GridSizeX * j;
                    double z = i % 2 == 1 && j % 2 == 1 ? d : z0;
                    v[i, j] = mesh.Vertices.Add(new VertexTraits(x, y, z));
                }
            }

            for (int i = 0; i < length; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    mesh.Faces.AddTriangles(v[i, j], v[i + 1, j], v[i + 1, j + 1], v[i, j + 1]);
                }
            }
            TriMeshUtil.SetUpNormalVertex(mesh);
            return mesh;
        }
Пример #13
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);
        }
Пример #14
0
        public double Distance(TriMesh.Vertex c, TriMesh.Vertex d)   //利用距离公式计算点到中心集的点的距离
        {
            double average;

            average = Math.Sqrt(Math.Pow((c.Traits.Position.x - d.Traits.Position.x), 2) + Math.Pow((c.Traits.Position.y - d.Traits.Position.y), 2) + Math.Pow((c.Traits.Position.z - d.Traits.Position.z), 2));
            return(average);
        }
Пример #15
0
 void OuterHalfedgeBothNew(TriMesh.HalfEdge cur, TriMesh.HalfEdge next, bool vertexIsUsed)
 {
     if (vertexIsUsed)  // Both edges are new and vertex has faces connected already
     {
         TriMesh.Vertex   vertex        = cur.ToVertex;
         TriMesh.HalfEdge closeHalfedge = null;
         // Find the closing halfedge of the first available opening
         foreach (TriMesh.HalfEdge h in vertex.HalfEdges)
         {
             if (h.Face == null)
             {
                 closeHalfedge = h;
                 break;
             }
         }
         TriMesh.HalfEdge openHalfedge = closeHalfedge.Previous;
         // Link new outer halfedges into this opening
         cur.Opposite.Previous  = openHalfedge;
         openHalfedge.Next      = cur.Opposite;
         next.Opposite.Next     = closeHalfedge;
         closeHalfedge.Previous = next.Opposite;
     }
     else
     {
         cur.Opposite.Previous = next.Opposite;
         next.Opposite.Next    = cur.Opposite;
     }
 }
Пример #16
0
        public static TriMesh Clone(TriMesh mesh)
        {
            TriMesh newMesh = new TriMesh();
            for (int i = 0; i < mesh.Vertices.Count; i++)
            {
                VertexTraits traits = new VertexTraits(mesh.Vertices[i].Traits.Position.x,
                                                       mesh.Vertices[i].Traits.Position.y,
                                                       mesh.Vertices[i].Traits.Position.z);
                newMesh.Vertices.Add(traits);
            }

            TriMesh.Vertex[] faceVetices = new TriMesh.Vertex[3];
            for (int i = 0; i < mesh.Faces.Count; i++)
            {
                int faceVertexIndex1 = mesh.Faces[i].GetVertex(0).Index;
                int faceVertexIndex2 = mesh.Faces[i].GetVertex(1).Index;
                int faceVertexIndex3 = mesh.Faces[i].GetVertex(2).Index;

                faceVetices[0] = newMesh.Vertices[faceVertexIndex1];
                faceVetices[1] = newMesh.Vertices[faceVertexIndex2];
                faceVetices[2] = newMesh.Vertices[faceVertexIndex3];
                newMesh.Faces.AddTriangles(faceVetices);
            }
            newMesh.TrimExcess();
            return newMesh;
        }
Пример #17
0
        public static TriMesh.Vertex MergeEdge(TriMesh.Edge edge, Vector3D position)
        {
            TriMesh mesh = (TriMesh)edge.Mesh;

            TriMesh.Vertex   v0  = edge.Vertex0;
            TriMesh.Vertex   v1  = edge.Vertex1;
            TriMesh.HalfEdge hf0 = edge.HalfEdge0;
            TriMesh.HalfEdge hf1 = edge.HalfEdge1;

            v0.Traits.Position = position;

            foreach (var item in v1.HalfEdges)
            {
                //if (item.ToVertex != v0)
                {
                    item.Opposite.ToVertex = v0;
                }
            }

            MergeOneSide(hf0);
            MergeOneSide(hf1);

            mesh.RemoveVertex(v1);
            mesh.RemoveEdge(edge);
            v1.HalfEdge    = null;
            edge.HalfEdge0 = null;

            return(v0);
        }
Пример #18
0
        public void PlaneCut(TriMesh.HalfEdge above, Vector3D normal, double maxAngle)
        {
            Plane plane = new Plane(above.Next.ToVertex.Traits.Position, normal);
            Nullable <Vector3D> point = this.Intersect(plane, above.Edge);
            double angle = this.GetAngle(plane, above);

            while (point != null && angle > maxAngle)
            {
                TriMesh.Vertex left   = above.FromVertex;
                TriMesh.Vertex right  = above.ToVertex;
                TriMesh.Vertex buttom = above.Opposite.Next.ToVertex;

                this.Cut(above, point.Value);

                if (above.Opposite.OnBoundary)
                {
                    break;
                }

                TriMesh.HalfEdge[] below = new[] { left.FindHalfedgeTo(buttom), buttom.FindHalfedgeTo(right) };
                foreach (var hf in below)
                {
                    point = this.Intersect(plane, hf.Edge);
                    if (point != null)
                    {
                        angle = this.GetAngle(plane, hf);
                        above = hf;
                        break;
                    }
                }
            }
        }
Пример #19
0
        public bool Backward()
        {
            if (this.index == 0)
            {
                return(false);
            }
            else
            {
                index--;
                EdgeContext ctx = this.method.Logs[this.index];
                SplitVertex.Split(this.Mesh, ctx);
                TriMesh.Vertex left  = null;
                TriMesh.Vertex right = null;
                foreach (var v in this.Mesh.Vertices)
                {
                    if (v.Index == ctx.Left)
                    {
                        left = v;
                    }
                    else if (v.Index == ctx.Right)
                    {
                        right = v;
                    }
                }

                TriMesh.HalfEdge hf = left.FindHalfedgeTo(right);
                hf.Face.Traits.Normal          = TriMeshUtil.ComputeNormalFace(hf.Face);
                hf.Opposite.Face.Traits.Normal = TriMeshUtil.ComputeNormalFace(hf.Opposite.Face);
                left.Traits.Normal             = TriMeshUtil.ComputeNormalAreaWeight(left);
                right.Traits.Normal            = TriMeshUtil.ComputeNormalAreaWeight(right);
                return(true);
            }
        }
Пример #20
0
 protected override void BeforeMerge(TriMesh.Edge edge)
 {
     base.BeforeMerge(edge);
     TriMesh.Vertex v1 = edge.Vertex0;
     TriMesh.Vertex v2 = edge.Vertex1;
     vertexMatrix[v1] += vertexMatrix[v2];
 }
Пример #21
0
        private static double[] SimplifyComputePlane(TriMesh.Vertex vertexA,
                                                     TriMesh.Vertex vertexB, TriMesh.Vertex vertexC)
        {
            double x1 = vertexA.Traits.Position.x;
            double x2 = vertexB.Traits.Position.x;
            double x3 = vertexC.Traits.Position.x;

            double y1 = vertexA.Traits.Position.y;
            double y2 = vertexB.Traits.Position.y;
            double y3 = vertexC.Traits.Position.y;

            double z1 = vertexA.Traits.Position.z;
            double z2 = vertexB.Traits.Position.z;
            double z3 = vertexC.Traits.Position.z;

            double[] plane = new double[4];

            double a = (y2 - y1) * (z3 - z1) - (z2 - z1) * (y3 - y1);
            double b = (z2 - z1) * (x3 - x1) - (x2 - x1) * (z3 - z1);
            double c = (x2 - x1) * (y3 - y1) - (y2 - y1) * (x3 - x1);
            double M = Math.Sqrt(a * a + b * b + c * c);

            a = a / M;
            b = b / M;
            c = c / M;

            double d = -1 * (a * x1 + b * y1 + c * z1);

            plane[0] = a;
            plane[1] = b;
            plane[2] = c;
            plane[3] = d;

            return(plane);
        }
Пример #22
0
 public static bool EdgeSwap(TriMesh.Edge edge)
 {
     if (edge.OnBoundary)
     {
         return(false);
     }
     //逆时针90度,左右变为下上
     TriMesh.HalfEdge hf1         = edge.HalfEdge0;
     TriMesh.HalfEdge hf2         = edge.HalfEdge1;
     TriMesh.Vertex   top         = hf1.ToVertex;
     TriMesh.Vertex   buttom      = hf2.ToVertex;
     TriMesh.HalfEdge topLeft     = hf1.Next;
     TriMesh.HalfEdge buttomLeft  = hf1.Previous;
     TriMesh.HalfEdge topRight    = hf2.Previous;
     TriMesh.HalfEdge buttomRight = hf2.Next;
     top.HalfEdge      = topLeft;
     buttom.HalfEdge   = buttomRight;
     hf1.ToVertex      = topLeft.ToVertex;
     hf2.ToVertex      = buttomRight.ToVertex;
     hf1.Face.HalfEdge = hf1;
     hf2.Face.HalfEdge = hf2;
     topLeft.Face      = hf2.Face;
     buttomRight.Face  = hf1.Face;
     ConnectHalfEdge(topLeft, hf2, topRight);
     ConnectHalfEdge(buttomRight, hf1, buttomLeft);
     return(true);
 }
Пример #23
0
        public static TriMesh Clone(TriMesh mesh)
        {
            TriMesh newMesh = new TriMesh();

            for (int i = 0; i < mesh.Vertices.Count; i++)
            {
                VertexTraits traits = new VertexTraits(mesh.Vertices[i].Traits.Position.x,
                                                       mesh.Vertices[i].Traits.Position.y,
                                                       mesh.Vertices[i].Traits.Position.z);
                newMesh.Vertices.Add(traits);
            }

            TriMesh.Vertex[] faceVetices = new TriMesh.Vertex[3];
            for (int i = 0; i < mesh.Faces.Count; i++)
            {
                int faceVertexIndex1 = mesh.Faces[i].GetVertex(0).Index;
                int faceVertexIndex2 = mesh.Faces[i].GetVertex(1).Index;
                int faceVertexIndex3 = mesh.Faces[i].GetVertex(2).Index;

                faceVetices[0] = newMesh.Vertices[faceVertexIndex1];
                faceVetices[1] = newMesh.Vertices[faceVertexIndex2];
                faceVetices[2] = newMesh.Vertices[faceVertexIndex3];
                newMesh.Faces.AddTriangles(faceVetices);
            }
            newMesh.TrimExcess();
            return(newMesh);
        }
Пример #24
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);
        }
Пример #25
0
        public static void RemoveVertex(TriMesh.Vertex vertex)
        {
            TriMesh mesh = (TriMesh)vertex.Mesh;

            foreach (TriMesh.HalfEdge halfEdge in vertex.HalfEdges)
            {
                if (halfEdge.Next != null)
                {
                    halfEdge.Next.Face = null;
                    halfEdge.Opposite.Previous.Next = halfEdge.Next;
                    halfEdge.Next.Previous          = halfEdge.Opposite.Previous;
                }
                if (halfEdge.ToVertex.HalfEdge == halfEdge.Opposite)
                {
                    halfEdge.ToVertex.HalfEdge = halfEdge.Next;
                }
                mesh.RemoveHalfedge(halfEdge.Opposite);
                mesh.RemoveHalfedge(halfEdge);
            }
            foreach (TriMesh.Face face in vertex.Faces)
            {
                mesh.RemoveFace(face);
            }
            foreach (TriMesh.Edge edge in vertex.Edges)
            {
                mesh.RemoveEdge(edge);
            }
            mesh.RemoveVertex(vertex);
        }
Пример #26
0
        public static TriMesh Combine(List <TriMesh> meshes)
        {
            TriMesh combine = new TriMesh();

            foreach (TriMesh mesh in meshes)
            {
                if (mesh != null)
                {
                    TriMesh.Vertex[] arr = new TriMesh.Vertex[mesh.Vertices.Count];
                    foreach (TriMesh.Vertex v in mesh.Vertices)
                    {
                        arr[v.Index]        = combine.Vertices.Add(new VertexTraits(v.Traits.Position));
                        arr[v.Index].Traits = v.Traits;
                    }
                    foreach (TriMesh.Face face in mesh.Faces)
                    {
                        TriMesh.Face faceNew = combine.Faces.Add(arr[face.GetVertex(0).Index],
                                                                 arr[face.GetVertex(1).Index],
                                                                 arr[face.GetVertex(2).Index]);
                        faceNew.Traits = face.Traits;
                    }
                }
            }
            return(combine);
        }
Пример #27
0
        public static TriMesh ToTriMesh(QuadMesh mesh)
        {
            TriMesh trimesh = new TriMesh();

            for (int i = 0; i < mesh.Vertices.Count; i++)
            {
                Vector3D position = mesh.Vertices[i].Traits.Position;
                trimesh.Vertices.Add(new VertexTraits(position.x, position.y, position.z));
            }

            foreach (QuadMesh.Face face in mesh.Faces)
            {
                int v0 = face.GetVertex(0).Index;
                int v1 = face.GetVertex(1).Index;
                int v2 = face.GetVertex(2).Index;
                int v3 = face.GetVertex(3).Index;
                TriMesh.Vertex[] faceVertices = new TriMesh.Vertex[3];
                faceVertices[0] = trimesh.Vertices[v0];
                faceVertices[1] = trimesh.Vertices[v1];
                faceVertices[2] = trimesh.Vertices[v2];
                trimesh.Faces.AddTriangles(faceVertices);

                faceVertices[0] = trimesh.Vertices[v2];
                faceVertices[1] = trimesh.Vertices[v3];
                faceVertices[2] = trimesh.Vertices[v0];
                trimesh.Faces.AddTriangles(faceVertices);
            }

            return(trimesh);
        }
Пример #28
0
        public static void WriteToObjFile(string filePath, TriMesh mesh)
        {
            FileStream   fs = new FileStream(filePath, FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);

            sw.WriteLine("#Vertices:" + mesh.Vertices.Count);
            sw.WriteLine("#Faces:" + mesh.Faces.Count);

            foreach (TriMesh.Vertex item in mesh.Vertices)
            {
                sw.WriteLine("v {0} {1} {2}", item.Traits.Position.x, item.Traits.Position.y, item.Traits.Position.z);
            }

            sw.WriteLine();

            foreach (TriMesh.Face item in mesh.Faces)
            {
                TriMesh.Vertex v1 = item.GetVertex(0);
                TriMesh.Vertex v2 = item.GetVertex(1);
                TriMesh.Vertex v3 = item.GetVertex(2);

                sw.WriteLine("f {0} {1} {2}", v1.Index + 1, v2.Index + 1, v3.Index + 1);
            }

            sw.Close();
            fs.Close();
        }
Пример #29
0
        public static PrincipalCurvature ComputePricipalCurvature(TriMesh.Vertex v)
        {
            double mean  = ComputeMeanCurvature(v);
            double gauss = ComputeGaussianCurvature(v);

            return(ComputePricipalCurvature(mean, gauss));
        }
Пример #30
0
        public TriMesh CreateCylinder(int length, int width, int height)
        {
            TriMesh mesh = new TriMesh();
            double  x0   = -this.GridSizeX * length / 2d;
            double  y0   = -this.GridSizeY * width / 2d;
            double  z0   = -this.GridSizeZ * height / 2d;

            TriMesh.Vertex[,] top = new TriMesh.Vertex[length + 1, width + 1];
            TriMesh.Vertex[,] btm = new TriMesh.Vertex[length + 1, width + 1];
            for (int i = 0; i < length + 1; i++)
            {
                for (int j = 0; j < width + 1; j++)
                {
                    double x = x0 + this.GridSizeX * i;
                    double y = y0 + this.GridSizeY * j;
                    top[i, j] = mesh.Vertices.Add(new VertexTraits(x, y, -z0));
                    btm[i, j] = mesh.Vertices.Add(new VertexTraits(x, y, z0));
                }
            }

            for (int i = 0; i < length; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    mesh.Faces.AddTriangles(top[i, j], top[i + 1, j], top[i + 1, j + 1], top[i, j + 1]);
                    mesh.Faces.AddTriangles(btm[i, j], btm[i, j + 1], btm[i + 1, j + 1], btm[i + 1, j]);
                }
            }

            int round = (length + width) * 2;

            TriMesh.Vertex[,] side = new TriMesh.Vertex[round, height + 1];
            int s = 0, t = 0;

            for (int i = 0; i < round; i++)
            {
                int      ol = i < length ? 1 : i >= round / 2d && i < round - width ? -1 : 0;
                int      ow = i >= round - width ? -1 : i >= length && i < round / 2d ? 1 : 0;
                Vector3D v  = btm[s, t].Traits.Position;
                side[i, 0] = btm[s, t];
                for (int j = 1; j < height; j++)
                {
                    side[i, j] = mesh.Vertices.Add(new VertexTraits(v.x, v.y, z0 + this.GridSizeZ * j));
                }
                side[i, height] = top[s, t];
                s += ol; t += ow;
            }

            for (int i = 0; i < round; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    mesh.Faces.AddTriangles(side[i, j], side[(i + 1) % round, j], side[(i + 1) % round, j + 1], side[i, j + 1]);
                }
            }

            TriMeshUtil.SetUpNormalVertex(mesh);
            return(mesh);
        }
Пример #31
0
 private static void BulidSphereFace(int v1, int v2, int v3, TriMesh mesh)//添加面
 {
     TriMesh.Vertex[] faceVertices = new TriMesh.Vertex[3];
     faceVertices[0] = mesh.Vertices[v1];
     faceVertices[1] = mesh.Vertices[v2];
     faceVertices[2] = mesh.Vertices[v3];
     TriMesh.Face[] addedFaces = mesh.Faces.AddTriangles(faceVertices);
 }
Пример #32
0
 private void BulidBoneFace(int v1, int v2, int v3)//为正方形添加面
 {
     TriMesh.Vertex[] faceVertices = new TriMesh.Vertex[3];
     faceVertices[0] = this.Vertices[v1];
     faceVertices[1] = this.Vertices[v2];
     faceVertices[2] = this.Vertices[v3];
     TriMesh.Face[] addedFaces = this.Faces.AddTriangles(faceVertices);
 }
Пример #33
0
 public static void ShowOneRingEdgeOfVertex(TriMesh.Vertex vertex)
 {
     foreach (TriMesh.HalfEdge neighbors in vertex.HalfEdges)
     {
         neighbors.Next.Edge.Traits.SelectedFlag = 10;
         neighbors.Next.Edge.Traits.Color        = RetrieveResult.Instance.EdgeResult;
     }
 }
Пример #34
0
 public static void ShowOneRingVertexOfVertex(TriMesh.Vertex vertex)
 {
     foreach (TriMesh.Vertex neighbors in vertex.Vertices)
     {
         neighbors.Traits.SelectedFlag = 8;
         neighbors.Traits.Color        = RetrieveResult.Instance.VertexResult;
     }
 }
Пример #35
0
        public TriMesh CreateCylinder(int length, int width, int height)
        {
            TriMesh mesh = new TriMesh();
            double x0 = -this.GridSizeX * length / 2d;
            double y0 = -this.GridSizeY * width / 2d;
            double z0 = -this.GridSizeZ * height / 2d;

            TriMesh.Vertex[,] top = new TriMesh.Vertex[length + 1, width + 1];
            TriMesh.Vertex[,] btm = new TriMesh.Vertex[length + 1, width + 1];
            for (int i = 0; i < length + 1; i++)
            {
                for (int j = 0; j < width + 1; j++)
                {
                    double x = x0 + this.GridSizeX * i;
                    double y = y0 + this.GridSizeY * j;
                    top[i, j] = mesh.Vertices.Add(new VertexTraits(x, y, -z0));
                    btm[i, j] = mesh.Vertices.Add(new VertexTraits(x, y, z0));
                }
            }

            for (int i = 0; i < length; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    mesh.Faces.AddTriangles(top[i, j], top[i + 1, j], top[i + 1, j + 1], top[i, j + 1]);
                    mesh.Faces.AddTriangles(btm[i, j], btm[i, j + 1], btm[i + 1, j + 1], btm[i + 1, j]);
                }
            }

            int round = (length + width) * 2;
            TriMesh.Vertex[,] side = new TriMesh.Vertex[round, height + 1];
            int s = 0, t = 0;
            for (int i = 0; i < round; i++)
            {
                int ol = i < length ? 1 : i >= round / 2d && i < round - width ? -1 : 0;
                int ow = i >= round - width ? -1 : i >= length && i < round / 2d ? 1 : 0;
                Vector3D v = btm[s, t].Traits.Position;
                side[i, 0] = btm[s, t];
                for (int j = 1; j < height; j++)
                {
                    side[i, j] = mesh.Vertices.Add(new VertexTraits(v.x, v.y, z0 + this.GridSizeZ * j));
                }
                side[i, height] = top[s, t];
                s += ol; t += ow;
            }

            for (int i = 0; i < round; i++)
            {
                for (int j = 0; j < height; j++)
                {
                    mesh.Faces.AddTriangles(side[i, j], side[(i + 1) % round, j], side[(i + 1) % round, j + 1], side[i, j + 1]);
                }
            }
            
            TriMeshUtil.SetUpNormalVertex(mesh);
            return mesh;
        }
Пример #36
0
 public void ComputeGeometryB(PolygonMesh dualMesh)
 {
     TriMesh.Vertex[] edgeVertices = new TriMesh.Vertex[mesh.Faces.Count * 3];
     foreach (TriMesh.Edge e in mesh.Edges)
     {    
         Vector3D midVertex0 = TriMeshUtil.GetMidPoint(e);  
         dualMesh.Vertices.Add(new VertexTraits(midVertex0.x, midVertex0.y, midVertex0.z));
     }
     foreach (TriMesh.Face f in mesh.Faces)
     {
          
         Vector3D baryCenter = TriMeshUtil.GetMidPoint(f);
         dualMesh.Vertices.Add(new VertexTraits(baryCenter.x, baryCenter.y, baryCenter.z));
     }
 }
Пример #37
0
 public void CutHalfEdge(TriMesh.HalfEdge hf)
 {
     Vector3D p1 = hf.FromVertex.Traits.Position;
     Vector3D p2 = hf.ToVertex.Traits.Position;
     double d1 = TriMeshUtil.GetDistance(plane, p1);
     double d2 = TriMeshUtil.GetDistance(plane, p2);
     if (d1 < 0 && d2 > 0)
     {
         d1 = Math.Abs(d1);
         d2 = Math.Abs(d2);
         Vector3D pos = p1 + (p2 - p1) * d1 / (d1 + d2);
         TriMesh.Vertex v1 = new TriMesh.Vertex(new VertexTraits(pos));
         this.mesh.AppendToVertexList(v1);
         TriMesh.Vertex v2 = new TriMesh.Vertex(new VertexTraits(pos));
         this.mesh.AppendToVertexList(v2);
         this.cutPoint[hf.Index] = new CutPoint { Left = v1, Right = v2 };
     }
 }
Пример #38
0
 public static TriMesh Combine(List<TriMesh> meshes)
 {
     TriMesh combine = new TriMesh();
     foreach (TriMesh mesh in meshes)
     {
         if (mesh != null)
         {
             TriMesh.Vertex[] arr = new TriMesh.Vertex[mesh.Vertices.Count];
             foreach (TriMesh.Vertex v in mesh.Vertices)
             { 
                 arr[v.Index] = combine.Vertices.Add(new VertexTraits(v.Traits.Position));
                 arr[v.Index].Traits = v.Traits;
             }
             foreach (TriMesh.Face face in mesh.Faces)
             {
                 TriMesh.Face faceNew=combine.Faces.Add(arr[face.GetVertex(0).Index],
                                   arr[face.GetVertex(1).Index],
                                   arr[face.GetVertex(2).Index]);
                 faceNew.Traits = face.Traits;
             }
         }
     }
     return combine;
 }
Пример #39
0
 private void BulidBoneFace(int v1, int v2, int v3)//为正方形添加面
 {
     TriMesh.Vertex[] faceVertices = new TriMesh.Vertex[3];
     faceVertices[0] = this.Vertices[v1];
     faceVertices[1] = this.Vertices[v2];
     faceVertices[2] = this.Vertices[v3];
     TriMesh.Face[] addedFaces = this.Faces.AddTriangles(faceVertices);
 }
Пример #40
0
        DenseMatrixQuaternion BuildOmega(DenseMatrixQuaternion lamda)
        {
            DenseMatrixQuaternion Omega = new DenseMatrixQuaternion(mesh.Vertices.Count, 1);

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

            foreach (TriMesh.Face face in mesh.Faces)
            {
                index[0] = face.GetVertex(2);
                index[1] = face.GetVertex(0);
                index[2] = face.GetVertex(1);

                for (int i = 0; i < 3; i++)
                {
                    Quaternion f0 = new Quaternion(index[(i + 0) % 3].Traits.Position, 0);
                    Quaternion f1 = new Quaternion(index[(i + 1) % 3].Traits.Position, 0);
                    Quaternion f2 = new Quaternion(index[(i + 2) % 3].Traits.Position, 0);

                    //Setting Orientation Swap it
                    TriMesh.Vertex aI = index[(i + 1) % 3];
                    TriMesh.Vertex bI = index[(i + 2) % 3];
                    if (aI.Index > bI.Index)
                    {
                        aI = index[(i + 2) % 3];
                        bI = index[(i + 1) % 3];
                    }

                    Quaternion aLamda = lamda[aI.Index, 0];
                    Quaternion bLamda = lamda[bI.Index, 0];
                    Quaternion e = new Quaternion(bI.Traits.Position, 0) - new Quaternion(aI.Traits.Position, 0);
                    Quaternion conj = aLamda.Conjugate();
                    Quaternion bconj = bLamda.Conjugate();
                    Quaternion partA = conj * e * aLamda;
                    Quaternion eTilde = (1f / 3f) * partA +
                                        (1f / 6f) * aLamda.Conjugate() * e * bLamda +
                                        (1f / 6f) * bLamda.Conjugate() * e * aLamda +
                                        (1f / 3f) * bLamda.Conjugate() * e * bLamda;

                    Vector3D u1 = index[(i + 1) % 3].Traits.Position - index[(i + 0) % 3].Traits.Position;
                    Vector3D u2 = index[(i + 2) % 3].Traits.Position - index[(i + 0) % 3].Traits.Position;

                    double cotAlpha = u1.Dot(u2) / u1.Cross(u2).Length();

                    Quaternion q = cotAlpha * eTilde / 2;

                    Omega[aI.Index, 0] -= q;
                    Omega[bI.Index, 0] += q;
                }

            }

            RemoveMean(ref Omega);
            return Omega;
        }
Пример #41
0
        public static TriMesh ToTriMesh(QuadMesh mesh)
        {
            TriMesh trimesh = new TriMesh();
            for (int i = 0; i < mesh.Vertices.Count; i++)
            {
                Vector3D position = mesh.Vertices[i].Traits.Position;
                trimesh.Vertices.Add(new VertexTraits(position.x, position.y, position.z));
            }

            foreach (QuadMesh.Face face in mesh.Faces)
            {
                int v0 = face.GetVertex(0).Index;
                int v1 = face.GetVertex(1).Index;
                int v2 = face.GetVertex(2).Index;
                int v3 = face.GetVertex(3).Index;
                TriMesh.Vertex[] faceVertices = new TriMesh.Vertex[3];
                faceVertices[0] = trimesh.Vertices[v0];
                faceVertices[1] = trimesh.Vertices[v1];
                faceVertices[2] = trimesh.Vertices[v2];
                trimesh.Faces.AddTriangles(faceVertices);

                faceVertices[0] = trimesh.Vertices[v2];
                faceVertices[1] = trimesh.Vertices[v3];
                faceVertices[2] = trimesh.Vertices[v0];
                trimesh.Faces.AddTriangles(faceVertices);

            }

            return trimesh;
        }
Пример #42
0
        private static void ProcessPlyLine(TriMesh mesh, string line, PlyFileProcessorState state)
        {
            // Trim out comments (allow comments trailing on a line)
            int commentStart = line.IndexOf("ply");
            if (commentStart != -1)
            {
                line = line.Substring(0, commentStart);
            }

            // Tokenize line
            string[] tokens = line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);

            // Process line based on the keyword used
            if (tokens.Length > 0)
            {
                int? v;
                float x, y, z;
                TriMesh.Vertex[] faceVertices;
                int?[] vt, vn;
                if (tokens[0] == "element" && tokens[1] == "vertex")
                {
                    state.Vnum = Int32.Parse(tokens[2]);
                }
                else if (tokens[0] == "element" && tokens[1] == "face")
                {
                    state.Fnum = Int32.Parse(tokens[2]);
                }
                else if (tokens[0] == "end_header")
                {
                    state.startv = true;
                }
                else if (state.startv == true  )
                {
                    x = Single.Parse(tokens[0]);
                    y = Single.Parse(tokens[1]);
                    z = Single.Parse(tokens[2]);

                    double r = Single.Parse(tokens[3]);
                    double g = Single.Parse(tokens[4]);
                    double b = Single.Parse(tokens[5]);

                    double nx = Single.Parse(tokens[6]);
                    double ny = Single.Parse(tokens[7]);
                    double nz = Single.Parse(tokens[8]);

                    int sel = int.Parse(tokens[9]);

                    double tx = Single.Parse(tokens[10]);
                    double ty = Single.Parse(tokens[11]);

                    TriMesh.Vertex vertex= mesh.Vertices.Add(new VertexTraits(x, y, z));
                    vertex.Traits.Color = new Color4(r, g, b);
                    vertex.Traits.SelectedFlag = (byte)sel;

                    vertex.Traits.UV.x = tx;
                    vertex.Traits.UV.y = ty;
                    state.countv += 1;
                    if (state.countv == state.Vnum)
                    {
                        state.startf = true;
                        state.startv = false;
                    }
                }
                else if (state.startf == true)
                {
                    int vCount = int.Parse(tokens[0]);

                    faceVertices = new TriMesh.Vertex[vCount];
                   

                    // Parse vertex/texture coordinate/normal indices
                    for (int i = 0; i < faceVertices.Length; ++i)
                    {
                        //string[] vertexTokens = tokens[i + 1].Split("/".ToCharArray());
                        v = Int32.Parse(tokens[i + 1]);
                        faceVertices[i] = mesh.Vertices[v.Value];
                    }

                    TriMesh.Face[] addedFaces = mesh.Faces.AddTriangles(faceVertices);

                    double r = Single.Parse(tokens[vCount+1]);
                    double g = Single.Parse(tokens[vCount + 2]);
                    double b = Single.Parse(tokens[vCount + 3]); 
                    int sel = int.Parse(tokens[vCount + 4]);

                    //double vx = Single.Parse(tokens[vCount + 5]);
                    //double vy = Single.Parse(tokens[vCount + 6]);

                    addedFaces[0].Traits.SelectedFlag = (byte)sel;
                    addedFaces[0].Traits.Color = new Color4(r, g, b);
                 


                    state.countf+= 1;
                    if (state.countf== state.Fnum)
                    {
                        state.starte = true;
                        state.startf = false;
                    }
                }

                else if (state.starte == true)
                {

                    int sel = int.Parse(tokens[0]);
                    mesh.Edges[state.counte].Traits.SelectedFlag =(byte)sel;
                    state.counte += 1;
                }

            }
        }
Пример #43
0
        public TriMesh CreateSquareSpoke(int length, int width)
        {
            TriMesh mesh = new TriMesh();
            double x0 = -this.GridSizeX * length / 2d;
            double y0 = -this.GridSizeX * width / 2d;
            double z0 = 0;
            double d = this.GridSizeX / 2;
            int t = 4;

            TriMesh.Vertex[,] v = new TriMesh.Vertex[length + 1, width + 1];
            for (int i = 0; i < length + 1; i++)
            {
                for (int j = 0; j < width + 1; j++)
                {
                    double x = x0 + this.GridSizeX * i;
                    double y = y0 + this.GridSizeX * j;
                    int r = i % t == j % t ? i % t : 0;
                    double z = z0 - (Math.Abs(r - t / 2) - t / 2) * d;
                    v[i, j] = mesh.Vertices.Add(new VertexTraits(x, y, z));
                }
            }

            for (int i = 0; i < length; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    mesh.Faces.AddTriangles(v[i, j], v[i + 1, j], v[i + 1, j + 1], v[i, j + 1]);
                }
            }
            TriMeshUtil.SetUpNormalVertex(mesh);
            return mesh;
        }
Пример #44
0
        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;
        }
Пример #45
0
        /// <summary>
        /// Computes vertex normals.
        /// </summary>
        /// <param name="cornerArea">A halfedge dynamic trait with face vertex angular areas.</param>
        /// <param name="pointArea">A vertex dynamic trait with vertex angular areas.</param>
        public void ComputeFaceVertexNormals(TriMesh mesh, TriMesh.HalfedgeDynamicTrait<float> cornerArea, TriMesh.VertexDynamicTrait<float> pointArea)
        {
            TriMesh.FaceDynamicTrait<Vector3D> normal = new TriMesh.FaceDynamicTrait<Vector3D>(mesh);

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

            // Compute normal for each face
            foreach (TriMesh.Face f in mesh.Faces)
            {
                int i = 0;
                foreach (TriMesh.Vertex v in f.Vertices)
                {
                    fv[i] = v;
                    ++i;
                }

                // Compute normal for this face
                normal[f] = (fv[2].Traits.Position - fv[1].Traits.Position).Cross(fv[0].Traits.Position - fv[2].Traits.Position);
                normal[f] = normal[f].Normalize();
                f.Traits.Normal = normal[f];
            }

            // Compute normal for each vertex
            foreach (TriMesh.HalfEdge h in  mesh.HalfEdges)
            {
                if (!h.OnBoundary)  // Ignore halfedges that don't have a face
                {
                    float weight = cornerArea[h] / pointArea[h.ToVertex];
                    h.ToVertex.Traits.Normal += weight * normal[h.Face];
                }
            }

            // Normalize normals
            foreach (TriMesh.Vertex v in mesh.Vertices)
            {
                if (Math.Sqrt(v.Traits.Normal.Length()) > 0.0f)    // Ignore isolated points
                {
                    v.Traits.Normal.Normalize();
                }
            }
        }
Пример #46
0
        private static void ProcessOffLine(TriMesh mesh, string line, OffFileProcessorState state, ref bool ignoreFirstThreeNum)
        {
            // Trim out comments (allow comments trailing on a line)
            int commentStart = line.IndexOf("OFF");
            if (commentStart != -1)
            {
                line = line.Substring(0, commentStart);
            }

            // Tokenize line
            string[] tokens = line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);

            // Process line based on the keyword used
            if (tokens.Length > 0)
            {
                int? v;
                float x, y, z;
                TriMesh.Vertex[] faceVertices;
                int?[] vt, vn;

                if (tokens.Length == 3)
                {
                    if (!ignoreFirstThreeNum)
                    {
                        x = Single.Parse(tokens[0]);
                        y = Single.Parse(tokens[1]);
                        z = Single.Parse(tokens[2]);

                        mesh.Vertices.Add(new VertexTraits(x, y, z));
                    }

                    ignoreFirstThreeNum = false;
                }
                else if (tokens.Length == 4 || tokens.Length == 5)
                {
                    faceVertices = new TriMesh.Vertex[tokens.Length - 1];
                    vt = new int?[tokens.Length - 1];
                    vn = new int?[tokens.Length - 1];

                    // Parse vertex/texture coordinate/normal indices
                    for (int i = 0; i < faceVertices.Length; ++i)
                    {
                        //string[] vertexTokens = tokens[i + 1].Split("/".ToCharArray());
                        v = Int32.Parse(tokens[i + 1]);
                        faceVertices[i] = mesh.Vertices[v.Value];
                    }

                    TriMesh.Face[] addedFaces = mesh.Faces.AddTriangles(faceVertices);

                    // Set texture coordinates and normals if any are given
                    for (int i = 0; i < faceVertices.Length; ++i)
                    {
                        TriMesh.HalfEdge faceVertex;
                        if (vt[i].HasValue || vn[i].HasValue)
                        {
                            foreach (TriMesh.Face f in addedFaces)
                            {
                                faceVertex = f.FindHalfedgeTo(faceVertices[i]);
                                if (faceVertex != null) // Make sure vertex belongs to face if triangularization is on
                                {
                                    if (vt[i].HasValue)
                                    {
                                        faceVertex.Traits.TextureCoordinate = state.VertexTextureCoords[vt[i].Value - 1];
                                    }
                                    if (vn[i].HasValue)
                                    {
                                        faceVertex.Traits.Normal = state.VertexNormals[vn[i].Value - 1];
                                    }
                                }
                            }
                        }
                    }
                }


            }
        }
Пример #47
0
        public void MakeTheTopologyB(PolygonMesh dualMesh)
        {
            List<TriMesh.Vertex> boundaryVertices = new List<TriMesh.Vertex>();

            boundaryVertices = TriMeshUtil.RetrieveAllBoundaryVertex(mesh);
            foreach (TriMesh.Face face in mesh.Faces)
            {
                int index = face.Index;
                int baryVertexIndex = mesh.Edges.Count;
                int edgeVertexIndex;
                int faceIndex = index;
                TriMesh.Edge boundaryEdge = new TriMesh.Edge();
                TriMesh.HalfEdge tempHalfedge = new TriMesh.HalfEdge();
                TriMesh.Vertex vertex0 = mesh.Faces[index].GetVertex(0);
                TriMesh.Vertex vertex1 = mesh.Faces[index].GetVertex(1);
                TriMesh.Vertex vertex2 = mesh.Faces[index].GetVertex(2);
                TriMesh.HalfEdge halfedge0 = vertex0.FindHalfedgeTo(vertex1);
                TriMesh.HalfEdge halfedge1 = vertex1.FindHalfedgeTo(vertex2);
                TriMesh.HalfEdge halfedge2 = vertex2.FindHalfedgeTo(vertex0);
                TriMesh.HalfEdge boundaryHalfedge = new TriMesh.HalfEdge();
                tempHalfedge = halfedge0;
                
                edgeVertexIndex = halfedge0.Edge.Index;
                TriMesh.Vertex firstVertex = dualMesh.Vertices[baryVertexIndex + faceIndex];
                TriMesh.Vertex secondVertex = dualMesh.Vertices[edgeVertexIndex];
                if (firstVertex.FindHalfedgeTo(secondVertex) == null)
                {
                    List<TriMesh.Vertex> ringVertices = new List<TriMesh.Vertex>();
                    do
                    {
                        ringVertices.Add(dualMesh.Vertices[baryVertexIndex + faceIndex]);
                        ringVertices.Add(dualMesh.Vertices[edgeVertexIndex]);
                        if (tempHalfedge.Opposite.Next.Face != null)
                        {
                            tempHalfedge = tempHalfedge.Opposite.Next;
                            faceIndex = tempHalfedge.Face.Index;
                            edgeVertexIndex = tempHalfedge.Edge.Index;
                        }
                        else
                        {
                            tempHalfedge = tempHalfedge.Opposite.Next;
                            edgeVertexIndex = tempHalfedge.Edge.Index;
                            faceIndex = tempHalfedge.Opposite.Next.Face.Index;
                        }
                    } while (tempHalfedge != halfedge0);
                    TriMesh.Vertex[] newFaceVertices = new TriMesh.Vertex[ringVertices.Count];
                    for (int i = 0; i < ringVertices.Count; i++)
                    {
                        newFaceVertices[i] = ringVertices[i];
                    }
                    dualMesh.Faces.Add(newFaceVertices);
                }
                tempHalfedge = halfedge1;
                edgeVertexIndex = halfedge1.Edge.Index;
                firstVertex = dualMesh.Vertices[baryVertexIndex + faceIndex];
                secondVertex = dualMesh.Vertices[edgeVertexIndex];
                if (firstVertex.FindHalfedgeTo(secondVertex) == null)
                {
                    List<TriMesh.Vertex> ringVertices = new List<TriMesh.Vertex>();
                    do
                    {
                        ringVertices.Add(dualMesh.Vertices[baryVertexIndex + faceIndex]);
                        ringVertices.Add(dualMesh.Vertices[edgeVertexIndex]);
                        if (tempHalfedge.Opposite.Next != null)
                        {
                            tempHalfedge = tempHalfedge.Opposite.Next;
                            faceIndex = tempHalfedge.Face.Index;
                            edgeVertexIndex = tempHalfedge.Edge.Index;
                        }
                        else
                        {
                            continue;
                        }
                    } while (tempHalfedge != halfedge1);
                    TriMesh.Vertex[] newFaceVertices = new TriMesh.Vertex[ringVertices.Count];
                    for (int i = 0; i < ringVertices.Count; i++)
                    {
                        newFaceVertices[i] = ringVertices[i];

                    }
                    dualMesh.Faces.Add(newFaceVertices);
                }
                tempHalfedge = halfedge2;
                edgeVertexIndex = halfedge2.Edge.Index;
                firstVertex = dualMesh.Vertices[baryVertexIndex + faceIndex];
                secondVertex = dualMesh.Vertices[edgeVertexIndex];
                if (firstVertex.FindHalfedgeTo(secondVertex) == null)
                {
                    List<TriMesh.Vertex> ringVertices = new List<TriMesh.Vertex>();
                    do
                    {
                        ringVertices.Add(dualMesh.Vertices[baryVertexIndex + faceIndex]);
                        ringVertices.Add(dualMesh.Vertices[edgeVertexIndex]);
                        if (tempHalfedge.Opposite.Next != null)
                        {
                            tempHalfedge = tempHalfedge.Opposite.Next;
                            faceIndex = tempHalfedge.Face.Index;
                            edgeVertexIndex = tempHalfedge.Edge.Index;
                        }
                        else
                        {
                            continue;
                        }
                    } while (tempHalfedge != halfedge2);
                    TriMesh.Vertex[] newFaceVertices = new TriMesh.Vertex[ringVertices.Count];
                    for (int i = 0; i < ringVertices.Count; i++)
                    {
                        newFaceVertices[i] = ringVertices[i];

                    }
                    dualMesh.Faces.Add(newFaceVertices);
                }
            }
        }
Пример #48
0
        public void ComputeGeometryC(PolygonMesh dualMesh)
        {
            //get the mid-Vertex of each edges
            TriMesh.Vertex[] edgeVertices = new TriMesh.Vertex[mesh.Faces.Count * 3];
            foreach (TriMesh.Edge e in mesh.Edges)
            {
                Vector3D midVertex0 = TriMeshUtil.GetMidPoint(e);  
                dualMesh.Vertices.Add(new VertexTraits(midVertex0.x,
                                                       midVertex0.y,
                                                       midVertex0.z));
            }
            //get circumcentre of each faces
            foreach (TriMesh.Face f in mesh.Faces)
            {
                TriMesh.Vertex vertex0 = f.GetVertex(0);
                TriMesh.Vertex vertex1 = f.GetVertex(1);
                TriMesh.Vertex vertex2 = f.GetVertex(2);
                Triangle triangle = new Triangle(vertex0.Traits.Position, vertex1.Traits.Position, vertex2.Traits.Position);
                Vector3D circumCenter = triangle.ComputeCircumCenter();
                dualMesh.Vertices.Add(new VertexTraits(circumCenter.x,
                                                       circumCenter.y,
                                                       circumCenter.z));

            }
        }
Пример #49
0
        public static TriMesh ConvertToTriMesh(NonManifoldMesh mesh)
        {
            TriMesh triMesh = new GraphicResearchHuiZhao.TriMesh();
            triMesh.Traits.HasFaceVertexNormals = true;
            triMesh.Traits.HasTextureCoordinates = true;

            if (mesh.VertexNormal == null)
            {
                triMesh.Traits.HasFaceVertexNormals = false;

            }
            else
            {
                triMesh.Traits.HasFaceVertexNormals = true;
            }

            if (mesh.TextextCoordinate == null)
            {
                triMesh.Traits.HasTextureCoordinates = false;
            }
            else
            {
                triMesh.Traits.HasTextureCoordinates = true;
            }

            int vertexCount = mesh.VertexCount;
            int faceCount = mesh.FaceCount;
            for (int i = 0; i < vertexCount; i++)
            {
                VertexTraits traits = new VertexTraits((float)mesh.VertexPos[i * 3], (float)mesh.VertexPos[i * 3 + 1], (float)mesh.VertexPos[i * 3 + 2]);
                triMesh.Vertices.Add(traits);

            }

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

            for (int i = 0; i < faceCount; i++)
            {
                vertices[0] = triMesh.Vertices[mesh.FaceIndex[i * 3]];
                vertices[1] = triMesh.Vertices[mesh.FaceIndex[i * 3 + 1]];
                vertices[2] = triMesh.Vertices[mesh.FaceIndex[i * 3 + 2]];


                triMesh.Faces.AddTriangles(vertices);
            }

            if (triMesh.Traits.HasTextureCoordinates)
            {
                TriMesh.HalfEdge faceVertex;
                foreach (TriMesh.Face face in triMesh.Faces)
                {
                    foreach (TriMesh.Vertex vertex in face.Vertices)
                    {
                        faceVertex = face.FindHalfedgeTo(vertex);
                        if (faceVertex != null) // Make sure vertex belongs to face if triangularization is on
                        {

                            faceVertex.Traits.TextureCoordinate = new Vector2D(mesh.TextextCoordinate[vertex.Index * 2], mesh.TextextCoordinate[vertex.Index * 2 + 1]);

                        }
                    }
                }
            }

            if (triMesh.Traits.HasFaceVertexNormals)
            {
                TriMesh.HalfEdge faceVertex;
                foreach (TriMesh.Face face in triMesh.Faces)
                {
                    foreach (TriMesh.Vertex vertex in face.Vertices)
                    {
                        faceVertex = face.FindHalfedgeTo(vertex);
                        if (faceVertex != null) // Make sure vertex belongs to face if triangularization is on
                        {

                            faceVertex.Traits.Normal = new Vector3D(mesh.FaceNormal, vertex.Index);

                        }
                    }
                }
            }



            //if (triMesh.Traits.HasTextureCoordinates)
            //{

            //    foreach (HalfEdgeMesh.TriMesh.Vertex vertex in triMesh.Vertices )
            //    {

            //       vertex.Traits.TextureCoordinate = new Vector2d(mesh.TextextCoordinate[vertex.Index * 2], mesh.TextextCoordinate[vertex.Index * 2 + 1]);


            //    }
            //}

            //if (triMesh.Traits.HasFaceVertexNormals)
            //{
            //   foreach (HalfEdgeMesh.TriMesh.Vertex vertex in triMesh.Vertices)
            //   { 
            //       vertex.Traits.Normal = new Vector3d(mesh.FaceNormal, vertex.Index);

            //    }
            //}


            return triMesh;
        }
Пример #50
0
        /// <summary>
        /// Processes a line from an OBJ file.
        /// </summary>
        /// <param name="line">A line from an OBJ file.</param>
        /// <param name="state">An object that manages state between calls.</param>
        private static void ProcessObjLine(TriMesh mesh, string line, ObjFileProcessorState state)
        {
            // Trim out comments (allow comments trailing on a line)
            int commentStart = line.IndexOf('#');
            if (commentStart != -1)
            {
                line = line.Substring(0, commentStart);
            }

            // Tokenize line
            string[] tokens = line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);

            // Process line based on the keyword used
            if (tokens.Length > 0)
            {
                int? v;
                float x, y, z;
                TriMesh.Vertex[] faceVertices;
                int?[] vt, vn;

                switch (tokens[0])
                {
                    case "v":   // Vertex
                        if (tokens.Length != 4)
                        {
                            throw new IOException("Vertices in the OBJ file must have 3 coordinates.");
                        }

                        x = Single.Parse(tokens[1]);
                        y = Single.Parse(tokens[2]);
                        z = Single.Parse(tokens[3]);

                        mesh.Vertices.Add(new VertexTraits(x, y, z));
                        break;

                    case "vt":   // Vertex texture
                        if (tokens.Length != 3 && tokens.Length != 4)
                        {
                            throw new IOException("Texture coordinates in the OBJ file must have 2 or 3 coordinates.");
                        }

                        x = Single.Parse(tokens[1]);
                        y = Single.Parse(tokens[2]);


                        state.VertexTextureCoords.Add(new Vector2D(x, y));
                        break;

                    case "vn":   // Vertex normal
                        if (tokens.Length != 4)
                        {
                            throw new IOException("Vertex normals in the OBJ file must have 3 coordinates.");
                        }

                        x = Single.Parse(tokens[1]);
                        y = Single.Parse(tokens[2]);
                        z = Single.Parse(tokens[3]);

                        state.VertexNormals.Add(new Vector3D(x, y, z));
                        break;

                    case "f":   // Face
                        faceVertices = new TriMesh.Vertex[tokens.Length - 1];
                        vt = new int?[tokens.Length - 1];
                        vn = new int?[tokens.Length - 1];

                        // Parse vertex/texture coordinate/normal indices
                        for (int i = 0; i < faceVertices.Length; ++i)
                        {
                            string[] vertexTokens = tokens[i + 1].Split("/".ToCharArray());

                            v = Int32.Parse(vertexTokens[0]);

                            if (vertexTokens.Length > 1 && vertexTokens[1].Length > 0)
                            {
                                vt[i] = Int32.Parse(vertexTokens[1]);
                            }
                            else
                            {
                                mesh.Traits.HasTextureCoordinates = false;
                            }

                            if (vertexTokens.Length > 2 && vertexTokens[2].Length > 0)
                            {
                                vn[i] = Int32.Parse(vertexTokens[2]);
                            }
                            else
                            {
                                mesh.Traits.HasFaceVertexNormals = false;
                            }

                            faceVertices[i] = mesh.Vertices[v.Value - 1];
                        }

                        try
                        {
                            TriMesh.Face[] addedFaces = mesh.Faces.AddTriangles(faceVertices);

                            // Set texture coordinates and normals if any are given
                            for (int i = 0; i < faceVertices.Length; ++i)
                            {
                                TriMesh.HalfEdge faceVertex;
                                if (vt[i].HasValue || vn[i].HasValue)
                                {
                                    foreach (TriMesh.Face f in addedFaces)
                                    {
                                        faceVertex = f.FindHalfedgeTo(faceVertices[i]);
                                        if (faceVertex != null) // Make sure vertex belongs to face if triangularization is on
                                        {
                                            if (vt[i].HasValue)
                                            {
                                                faceVertex.Traits.TextureCoordinate = state.VertexTextureCoords[vt[i].Value - 1];
                                            }
                                            if (vn[i].HasValue)
                                            {
                                                faceVertex.Traits.Normal = state.VertexNormals[vn[i].Value - 1];
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        catch { }

                        break;
                }
            }
        }
Пример #51
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);

        }
Пример #52
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
            } 

        }
Пример #53
0
        public static Vector4D[] ComputeDCruv(TriMesh mesh, double[] CornerArea, double[] PointArea)
        {
            PrincipalCurvature[] PrincipalCurv = ComputePrincipleCurvatures(mesh, CornerArea, PointArea);

            Vector4D[] dcurv = new Vector4D[mesh.Vertices.Count];

            TriMesh.HalfEdge[] fh = new TriMesh.HalfEdge[3];
            TriMesh.Vertex[] fv = new TriMesh.Vertex[3];
            Vector3D[] e = new Vector3D[3];
            Vector3D t, b, faceNormal;

            // Compute curvature for each face
            foreach (TriMesh.Face f in mesh.Faces)
            {
                // Get halfedges for this face
                fh[0] = f.HalfEdge;
                fh[1] = fh[0].Next;
                fh[2] = fh[1].Next;

                // Get vertices for this face
                fv[0] = fh[0].ToVertex;
                fv[1] = fh[1].ToVertex;
                fv[2] = fh[2].ToVertex;

                // Edge vectors
                e[0] = fv[2].Traits.Position - fv[1].Traits.Position;
                e[1] = fv[0].Traits.Position - fv[2].Traits.Position;
                e[2] = fv[1].Traits.Position - fv[0].Traits.Position;

                t = e[0];
                t.Normalize();

                faceNormal = e[0].Cross(e[1]);

                b = faceNormal.Cross(t);
                b.Normalize();

                KUV[] fcurv = new KUV[3];
                for (int i = 0; i < 3; i++)
                {
                    PrincipalCurvature pc =  PrincipalCurv[fv[i].Index];
                    UV src = new UV { U = pc.maxDir, V = pc.minDir };
                    KUV mk = new KUV { U = pc.max, UV = 0, V = pc.min };
                    UV tb = new UV { U = t, V = b };
                    fcurv[i] = Transform.ProjectCurvature(src, mk, tb);
                }

                double[] m = new double[4];
                double[,] w = new double[4, 4];
                for (int i = 0; i < 3; i++)
                {
                    KUV prev = fcurv[(i + 2) % 3];
                    KUV next = fcurv[(i + 1) % 3];
                    KUV dfcurv = new KUV { U = prev.U - next.U, UV = prev.UV - next.UV, V = prev.V - next.V };
                    double u = e[i].Dot(t);
                    double v = e[i].Dot(b);
                    w[0, 0] += u * u;
                    w[0, 1] += u * v;
                    w[3, 3] += v * v;
                    m[0] += u * dfcurv.U;
                    m[1] += v * dfcurv.U + 2d * u * dfcurv.UV;
                    m[2] += 2d * v * dfcurv.UV + u * dfcurv.V;
                    m[3] += v * dfcurv.V;
                }
                w[1, 1] = 2d * w[0, 0] + w[3, 3];
                w[1, 2] = 2d * w[0, 1];
                w[2, 2] = w[0, 0] + 2d * w[3, 3];
                w[2, 3] = w[0, 1];

                double[] diag = new double[4];
                if (Transform.LdlTransposeDecomp(w, diag))
                {
                    Transform.LdlTransposeSolveInPlace(w, diag, m);
                    Vector4D d = new Vector4D(m);
                    // Adjust curvature for vertices of this face
                    for (int i = 0; i < 3; ++i)
                    {
                        UV tb = new UV { U = t, V = b };
                        
                        PrincipalCurvature pc =  PrincipalCurv[fv[i].Index];
                        UV dst = new UV { U = pc.maxDir, V = pc.minDir };
                        Vector4D c = Transform.ProjectDCurvature(tb, d, dst);

                        double weight =  CornerArea[fh[i].Index] / PointArea[fv[i].Index];
                        dcurv[fv[i].Index] += weight * d;
                    }
                }
            }

            return dcurv;
        }
Пример #54
0
        public TriMesh CreateMesh()
        {
            TriMesh mesh = new TriMesh();

            mesh.Vertices.Add(new VertexTraits(this.A));
            mesh.Vertices.Add(new VertexTraits(this.B));
            mesh.Vertices.Add(new VertexTraits(this.C));


            TriMesh.Vertex[] faceVertices = new TriMesh.Vertex[3];
            faceVertices[0] = mesh.Vertices[0];
            faceVertices[1] = mesh.Vertices[1];
            faceVertices[2] = mesh.Vertices[2];
            mesh.Faces.AddTriangles(faceVertices);

            return mesh;


        }
Пример #55
0
        public static PrincipalCurvature[] ComputePrincipleCurvatures(TriMesh mesh, double[] CornerArea, double[] PointArea)
        {

            Vector3D[] vertexNormal = TriMeshUtil.ComputeNormalVertex(mesh);

            // Add dynamic trait for principle curvature computation
            double[] curv = new double[mesh.Vertices.Count];
            PrincipalCurvature[] pc = new PrincipalCurvature[mesh.Vertices.Count];

            // Initialize a coordinate system for each vertex
            foreach (TriMesh.Vertex v in mesh.Vertices)
            {
                pc[v.Index] = new PrincipalCurvature();
                // Vector that points from this vertex to an adjacent one
                pc[v.Index].maxDir = (v.HalfEdge.ToVertex.Traits.Position - v.Traits.Position).Cross(vertexNormal[v.Index]).Normalize();
                // Get a vector orthogonal to this vector and the vertex normal
                pc[v.Index].minDir = vertexNormal[v.Index].Cross(pc[v.Index].maxDir);
            }

            TriMesh.HalfEdge[] fh = new TriMesh.HalfEdge[3];
            TriMesh.Vertex[] fv = new TriMesh.Vertex[3];
            Vector3D[] e = new Vector3D[3];
            Vector3D t, b, dn, faceNormal;

            // Compute curvature for each face
            foreach (TriMesh.Face f in mesh.Faces)
            {
                // Get halfedges for this face
                fh[0] = f.HalfEdge;
                fh[1] = fh[0].Next;
                fh[2] = fh[1].Next;

                // Get vertices for this face
                fv[0] = fh[0].ToVertex;
                fv[1] = fh[1].ToVertex;
                fv[2] = fh[2].ToVertex;

                // Edge vectors
                e[0] = fv[2].Traits.Position - fv[1].Traits.Position;
                e[1] = fv[0].Traits.Position - fv[2].Traits.Position;
                e[2] = fv[1].Traits.Position - fv[0].Traits.Position;

                t = e[0];
                t.Normalize();

                faceNormal = e[0].Cross(e[1]);
                faceNormal.Normalize();

                b = faceNormal.Cross(t);
                b.Normalize();

                // Estimate curvature by variation of normals along edges
                double[] m = new double[3];
                double[,] w = new double[3, 3];

                for (int i = 0; i < 3; ++i)
                {
                    double u = e[i].Dot(t);
                    double v = e[i].Dot(b);

                    w[0, 0] += u * u;
                    w[0, 1] += u * v;
                    w[2, 2] += v * v;

                    dn = vertexNormal[fv[(i + 2) % 3].Index] - vertexNormal[fv[(i + 1) % 3].Index];

                    double dnu = dn.Dot(t);
                    double dnv = dn.Dot(b);

                    m[0] += dnu * u;
                    m[1] += dnu * v + dnv * u;
                    m[2] += dnv * v;
                }

                w[1, 1] = w[0, 0] + w[2, 2];
                w[1, 2] = w[0, 1];

                // Least squares solution
                double[] diag = new double[3];
                if (Transform.LdlTransposeDecomp(w, diag))
                {
                    Transform.LdlTransposeSolveInPlace(w, diag, m);

                    // Adjust curvature for vertices of this face
                    for (int i = 0; i < 3; ++i)
                    {
                        UV tb = new UV { U = t, V = b };
                        KUV mk = new KUV { U = m[0], UV = m[1], V = m[2] };
                        UV dst = new UV { U = pc[fv[i].Index].maxDir, V = pc[fv[i].Index].minDir };
                        KUV c = Transform.ProjectCurvature(tb, mk, dst);

                        double weight =  CornerArea[fh[i].Index] /  PointArea[fv[i].Index];
                        pc[fv[i].Index].max += weight * c.U;
                        curv[fv[i].Index] += weight * c.UV;
                        pc[fv[i].Index].min += weight * c.V;
                    }
                }
            }

            // Compute curvature for each vertex
            foreach (TriMesh.Vertex v in mesh.Vertices)
            {
                UV src = new UV { U = pc[v.Index].maxDir, V = pc[v.Index].minDir };
                KUV srcK = new KUV { U = pc[v.Index].max, UV = curv[v.Index], V = pc[v.Index].min };
                pc[v.Index] = Transform.DiagonalizeCurvature(src, srcK, vertexNormal[v.Index]);
            }

            return pc;
        }
Пример #56
0
        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;
        }
Пример #57
0
 private static void BulidSphereFace(int v1, int v2, int v3,TriMesh mesh)//添加面
 {
     TriMesh.Vertex[] faceVertices = new TriMesh.Vertex[3];
     faceVertices[0] = mesh.Vertices[v1];
     faceVertices[1] = mesh.Vertices[v2];
     faceVertices[2] = mesh.Vertices[v3];
     TriMesh.Face[] addedFaces = mesh.Faces.AddTriangles(faceVertices);
 }
Пример #58
0
        /// <summary>
        /// Computes principle curvatures on the vertices.
        /// </summary>
        /// <param name="cornerArea">A halfedge dynamic trait with face vertex angular areas.</param>
        /// <param name="pointArea">A vertex dynamic trait with vertex angular areas.</param>
        /// <remarks>
        /// Portions of this method are based on code from the C++ trimesh2 library
        /// (from TriMesh_curvature.cc).
        /// </remarks>
        public void ComputePrincipleCurvatures(TriMesh mesh,TriMesh.HalfedgeDynamicTrait<float> cornerArea, TriMesh.VertexDynamicTrait<float> pointArea)
        {
            // Add dynamic trait for principle curvature computation
            TriMesh.VertexDynamicTrait<float> curv = new TriMesh.VertexDynamicTrait<float>(mesh);

            // Initialize principle curvatures to zero
            foreach (TriMesh.Vertex v in mesh.Vertices)
            {
                v.Traits.MaxCurvature = 0.0f;
                v.Traits.MinCurvature = 0.0f;
            }

            // Initialize a coordinate system for each vertex
            foreach (TriMesh.Vertex v in mesh.Vertices)
            {
                if (Math.Sqrt(v.Traits.Normal.Length()) > 0.0f)    // Ignore isolated points
                {
                    // Vector that points from this vertex to an adjacent one
                    v.Traits.MaxCurvatureDirection = v.HalfEdge.ToVertex.Traits.Position - v.Traits.Position;
                    v.Traits.MaxCurvatureDirection.Normalize();

                    // Get a vector orthogonal to this vector and the vertex normal
                    v.Traits.MinCurvatureDirection = v.Traits.Normal.Cross(v.Traits.MaxCurvatureDirection);
                }
            }

            TriMesh.HalfEdge[] fh = new TriMesh.HalfEdge[3];
            TriMesh.Vertex[] fv = new TriMesh.Vertex[3];
            Vector3D[] e = new Vector3D[3];
            Vector3D t, b, dn, faceNormal;

            // Compute curvature for each face
            foreach (TriMesh.Face f in mesh.Faces)
            {
                // Get halfedges for this face
                fh[0] = f.HalfEdge;
                fh[1] = fh[0].Next;
                fh[2] = fh[1].Next;

                // Get vertices for this face
                fv[0] = fh[0].ToVertex;
                fv[1] = fh[1].ToVertex;
                fv[2] = fh[2].ToVertex;

                // Edge vectors
                e[0] = fv[2].Traits.Position - fv[1].Traits.Position;
                e[1] = fv[0].Traits.Position - fv[2].Traits.Position;
                e[2] = fv[1].Traits.Position - fv[0].Traits.Position;

                t = e[0];
                t.Normalize();

                faceNormal = e[0].Cross(e[1]);
                faceNormal.Normalize();

                b = faceNormal.Cross(t);
                b.Normalize();

                // Estimate curvature by variation of normals along edges
                float[] m = new float[3];
                float[,] w = new float[3, 3];

                for (int i = 0; i < 3; ++i)
                {
                    float u = (float)e[i].Dot(t);
                    float v = (float)e[i].Dot(b);

                    w[0, 0] += u * u;
                    w[0, 1] += u * v;
                    w[2, 2] += v * v;

                    dn = fv[(i + 2) % 3].Traits.Normal - fv[(i + 1) % 3].Traits.Normal;

                    float dnu = (float)dn.Dot(t);
                    float dnv = (float)dn.Dot(b);

                    m[0] += dnu * u;
                    m[1] += dnu * v + dnv * u;
                    m[2] += dnv * v;
                }

                w[1, 1] = w[0, 0] + w[2, 2];
                w[1, 2] = w[0, 1];

                // Least squares solution
                float[] diag = new float[3];
                if (Curvature.LdlTransposeDecomp(w, diag))
                {
                    Curvature.LdlTransposeSolveInPlace(w, diag, m);

                    // Adjust curvature for vertices of this face
                    for (int i = 0; i < 3; ++i)
                    {
                        float c1, c12, c2;
                        Curvature.ProjectCurvature(t, b, m[0], m[1], m[2], fv[i].Traits.MaxCurvatureDirection, fv[i].Traits.MinCurvatureDirection, out c1, out c12, out c2);

                        float weight = cornerArea[fh[i]] / pointArea[fv[i]];
                        fv[i].Traits.MaxCurvature += weight * c1;
                        curv[fv[i]] += weight * c12;
                        fv[i].Traits.MinCurvature += weight * c2;
                    }
                }
            }

            // Compute curvature for each vertex
            foreach (TriMesh.Vertex v in mesh.Vertices)
            {
                if (Math.Sqrt(v.Traits.Normal.Length()) > 0.0f)    // Ignore isolated points
                {
                    Curvature.DiagonalizeCurvature(v.Traits.MaxCurvatureDirection, v.Traits.MinCurvatureDirection, v.Traits.MaxCurvature, curv[v], v.Traits.MinCurvature, v.Traits.Normal,
                        out v.Traits.MaxCurvatureDirection, out v.Traits.MinCurvatureDirection, out v.Traits.MaxCurvature, out v.Traits.MinCurvature);
                }
            }
        }
Пример #59
0
        public static TriMesh CreateSquare()
        {
            double length = 0.5;
            double width = 0.3;
            TriMesh Shape = new TriMesh();
            Shape.Vertices.Add(new VertexTraits(-width, -length, 0));
            Shape.Vertices.Add(new VertexTraits(width, -length, 0));
            Shape.Vertices.Add(new VertexTraits(-width, length, 0));
            Shape.Vertices.Add(new VertexTraits(width, length, 0));

            TriMesh.Vertex[] faceVertices = new TriMesh.Vertex[3];
            faceVertices[0] = Shape.Vertices[0];
            faceVertices[1] = Shape.Vertices[1];
            faceVertices[2] = Shape.Vertices[2];
            CreateFace(Shape,faceVertices);

            faceVertices = new TriMesh.Vertex[3];
            faceVertices[0] = Shape.Vertices[1];
            faceVertices[1] = Shape.Vertices[3];
            faceVertices[2] = Shape.Vertices[2];
            CreateFace(Shape, faceVertices);

            faceVertices = new TriMesh.Vertex[3];
            faceVertices[0] = Shape.Vertices[2];
            faceVertices[1] = Shape.Vertices[3];
            faceVertices[2] = Shape.Vertices[0];
            CreateFace(Shape, faceVertices);

            faceVertices = new TriMesh.Vertex[3];
            faceVertices[0] = Shape.Vertices[3];
            faceVertices[1] = Shape.Vertices[1];
            faceVertices[2] = Shape.Vertices[0];
            CreateFace(Shape, faceVertices);


            return Shape;

        }