Esempio n. 1
0
        private TriMesh ChangeTopologyInit(TriMesh sourceMesh)
        {
            TriMesh mesh = new TriMesh();

            vMap    = new HalfEdgeMesh.Vertex[sourceMesh.Vertices.Count];
            faceMap = new HalfEdgeMesh.Vertex[sourceMesh.Faces.Count];
            foreach (var face in sourceMesh.Faces)
            {
                faceMap[face.Index] = mesh.Vertices.Add(
                    new VertexTraits(TriMeshUtil.GetMidPoint(face)));
            }

            foreach (var v in sourceMesh.Vertices)
            {
                vMap[v.Index] = mesh.Vertices.Add(new VertexTraits(v.Traits.Position));
                foreach (var hf in v.HalfEdges)
                {
                    if (hf.Face != null && hf.Opposite.Face != null)
                    {
                        mesh.Faces.AddTriangles(faceMap[hf.Face.Index],
                                                vMap[v.Index], faceMap[hf.Opposite.Face.Index]);
                    }
                }
            }

            foreach (var hf in sourceMesh.HalfEdges)
            {
                if (hf.Face == null)
                {
                    mesh.Faces.AddTriangles(vMap[hf.ToVertex.Index],
                                            vMap[hf.FromVertex.Index], faceMap[hf.Opposite.Face.Index]);
                }
            }
            return(mesh);
        }
Esempio n. 2
0
        public static TriMesh CreateGrid(int m, int n, double lengthx, double lengthy)
        {
            TriMesh mesh = new TriMesh();

            TriMesh.Vertex[,] arr = new HalfEdgeMesh.Vertex[m, n];
            double x0 = -m * lengthx / 2d;
            double y0 = -n * lengthy / 2d;

            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    arr[i, j]        = new HalfEdgeMesh.Vertex();
                    arr[i, j].Traits = new VertexTraits(x0 + i * lengthx, y0 + j * lengthy, 0d);
                    mesh.AppendToVertexList(arr[i, j]);
                }
            }

            for (int i = 0; i < m - 1; i++)
            {
                for (int j = 0; j < n - 1; j++)
                {
                    mesh.Faces.AddTriangles(arr[i + 1, j], arr[i, j + 1], arr[i, j]);
                    mesh.Faces.AddTriangles(arr[i + 1, j], arr[i + 1, j + 1], arr[i, j + 1]);
                }
            }
            return(mesh);
        }
Esempio n. 3
0
        public static TriMesh CreateCylinder(int m, int n, double r,
                                             double l, double maxU, double maxV, int diff)
        {
            TriMesh mesh = new TriMesh();

            TriMesh.Vertex[,] arr = new HalfEdgeMesh.Vertex[m, n];
            for (int i = 0; i < m; i++)
            {
                double z = l / m * i - l / 2;
                double v = maxV / m * i;
                for (int j = 0; j < n; j++)
                {
                    double       x     = r * Math.Cos(Math.PI * 2 / n * j);
                    double       y     = r * Math.Sin(Math.PI * 2 / n * j);
                    double       u     = maxU / n * j;
                    VertexTraits trait = new VertexTraits(x, y, z);
                    trait.UV  = new Vector2D(u, v);
                    arr[i, j] = mesh.Vertices.Add(trait);
                }
            }
            for (int i = 0; i < m - 1; i++)
            {
                for (int j = 0; j < n - diff; j++)
                {
                    int ni = i + 1;
                    int nj = (j + 1) % n;
                    mesh.Faces.AddTriangles(arr[i, nj], arr[ni, nj],
                                            arr[ni, j], arr[i, j]);
                }
            }
            return(mesh);
        }
Esempio n. 4
0
        public static TriMesh CreateCylinderPlane(int m, int n, double r,
                                                  double l, double maxU, double maxV, int diff)
        {
            TriMesh mesh = new TriMesh();

            TriMesh.Vertex[,] arr = new HalfEdgeMesh.Vertex[m, n];
            for (int i = 0; i < m; i++)
            {
                double x = l / m * i - l / 2;

                for (int j = 0; j < n; j++)
                {
                    double       y     = l / n * j - l / 2;
                    VertexTraits trait = new VertexTraits(x, y, 0);

                    trait.UV  = new Vector2D(x, y);
                    arr[i, j] = mesh.Vertices.Add(trait);
                }
            }
            for (int i = 0; i < m - 1; i++)
            {
                for (int j = 0; j < n - diff; j++)
                {
                    int ni = i + 1;
                    int nj = (j + 1) % n;
                    mesh.Faces.AddTriangles(arr[i, nj], arr[ni, nj],
                                            arr[ni, j], arr[i, j]);
                }
            }
            return(mesh);
        }
Esempio n. 5
0
        private TriMesh ChangeTopologyLoop(TriMesh sourceMesh)
        {
            TriMesh newMesh = new TriMesh();
            newMesh.Clear();
            vMap = new HalfEdgeMesh.Vertex[sourceMesh.Vertices.Count];
            eMap = new HalfEdgeMesh.Vertex[sourceMesh.Edges.Count];

            foreach (var v in sourceMesh.Vertices)
            {
                vMap[v.Index] = newMesh.Vertices.Add(new VertexTraits(v.Traits.Position));
            }

            foreach (var edge in sourceMesh.Edges)
            {
                eMap[edge.Index] = newMesh.Vertices.Add(
                    new VertexTraits(TriMeshUtil.GetMidPoint(edge)));
            }

            foreach(TriMesh.Face face in sourceMesh.Faces)
            {
                foreach (var hf in face.Halfedges)
                {
                    newMesh.Faces.AddTriangles(eMap[hf.Edge.Index], 
                        vMap[hf.ToVertex.Index], eMap[hf.Next.Edge.Index]);
                }
                newMesh.Faces.AddTriangles(
                    eMap[face.HalfEdge.Previous.Edge.Index],
                    eMap[face.HalfEdge.Edge.Index],
                    eMap[face.HalfEdge.Next.Edge.Index]);
            }
            return newMesh;
        }
Esempio n. 6
0
        public static TriMesh CreatePlaneTest(int m, int n, double l)
        {
            TriMesh mesh = new TriMesh();

            TriMesh.Vertex[,] arr = new HalfEdgeMesh.Vertex[m + 1, n + 1];
            for (int i = 0; i <= m; i++)
            {
                double x = l / m * i;

                for (int j = 0; j <= n; j++)
                {
                    double       y     = l / n * j;
                    VertexTraits trait = new VertexTraits(x, y, 0);

                    trait.UV  = new Vector2D(x, y);
                    arr[i, j] = mesh.Vertices.Add(trait);
                }
            }
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    int ni = i + 1;
                    int nj = j + 1;
                    mesh.Faces.AddTriangles(arr[i, nj], arr[ni, nj],
                                            arr[ni, j], arr[i, j]);
                }
            }
            return(mesh);
        }
Esempio n. 7
0
        TriMesh Create(IEnumerable <TriMesh.Face> region)
        {
            TriMesh newMesh = new TriMesh();

            foreach (var f in region)
            {
                TriMesh.Vertex[] arr = new HalfEdgeMesh.Vertex[3];
                int i = 0;
                foreach (var v in f.Vertices)
                {
                    if (!this.vMap.ContainsKey(v))
                    {
                        TriMesh.Vertex newV =
                            new HalfEdgeMesh.Vertex(new VertexTraits(v.Traits.Position));
                        this.vMap[v] = newV;
                        newMesh.AppendToVertexList(newV);
                    }
                    arr[i++] = this.vMap[v];
                }
                newMesh.Faces.AddTriangles(arr);
                this.fFlag[f.Index] = true;
            }

            return(newMesh);
        }
Esempio n. 8
0
        public static List <TriMesh> SeperateComponent(TriMesh mesh)
        {
            List <TriMesh> meshes = new List <TriMesh>();
            Dictionary <int, TriMesh.Vertex> map = new Dictionary <int, HalfEdgeMesh.Vertex>();

            bool[] visited             = new bool[mesh.Faces.Count];
            Queue <TriMesh.Face> queue = new Queue <HalfEdgeMesh.Face>();

            TriMesh newMesh = new TriMesh();

            queue.Enqueue(mesh.Faces[0]);
            visited[0] = true;
            while (queue.Count != 0)
            {
                TriMesh.Face face = queue.Dequeue();
                foreach (var hf in face.Halfedges)
                {
                    if (!map.ContainsKey(hf.ToVertex.Index))
                    {
                        TriMesh.Vertex v =
                            new HalfEdgeMesh.Vertex(new VertexTraits(hf.ToVertex.Traits.Position));
                        newMesh.AppendToVertexList(v);
                        map[hf.ToVertex.Index] = v;
                    }
                    if (hf.Opposite.Face != null && !visited[hf.Opposite.Face.Index])
                    {
                        queue.Enqueue(hf.Opposite.Face);
                        visited[hf.Opposite.Face.Index] = true;
                    }
                }

                newMesh.Faces.AddTriangles(
                    map[face.HalfEdge.FromVertex.Index],
                    map[face.HalfEdge.ToVertex.Index],
                    map[face.HalfEdge.Next.ToVertex.Index]);

                if (queue.Count == 0)
                {
                    meshes.Add(newMesh);

                    for (int i = 0; i < visited.Length; i++)
                    {
                        if (!visited[i])
                        {
                            newMesh = new TriMesh();
                            queue.Enqueue(mesh.Faces[i]);
                            visited[i] = true;
                            break;
                        }
                    }
                }
            }


            foreach (TriMesh child in meshes)
            {
                TriMeshUtil.SetUpNormalVertex(child);
            }
            return(meshes);
        }
Esempio n. 9
0
        private TriMesh ChangeTopologyInit(TriMesh sourceMesh)
        {
            TriMesh mesh = new TriMesh();

            vMap = new HalfEdgeMesh.Vertex[sourceMesh.Vertices.Count];
            faceMap = new HalfEdgeMesh.Vertex[sourceMesh.Faces.Count];
            foreach (var face in sourceMesh.Faces)
            {
                faceMap[face.Index] = mesh.Vertices.Add(
                    new VertexTraits(TriMeshUtil.GetMidPoint(face)));
            }

            foreach (var v in sourceMesh.Vertices)
            {
                vMap[v.Index] = mesh.Vertices.Add(new VertexTraits(v.Traits.Position));
                foreach (var hf in v.HalfEdges)
                {
                    if (hf.Face != null && hf.Opposite.Face != null)
                    {
                        mesh.Faces.AddTriangles(faceMap[hf.Face.Index], 
                            vMap[v.Index], faceMap[hf.Opposite.Face.Index]);
                    }
                }
            }

            foreach (var hf in sourceMesh.HalfEdges)
            {
                if (hf.Face == null)
                {
                    mesh.Faces.AddTriangles(vMap[hf.ToVertex.Index], 
                        vMap[hf.FromVertex.Index], faceMap[hf.Opposite.Face.Index]);
                }
            }
            return mesh;
        }
Esempio n. 10
0
        private TriMesh ChangeTopologyLoop(TriMesh sourceMesh)
        {
            TriMesh newMesh = new TriMesh();

            newMesh.Clear();
            vMap = new HalfEdgeMesh.Vertex[sourceMesh.Vertices.Count];
            eMap = new HalfEdgeMesh.Vertex[sourceMesh.Edges.Count];

            foreach (var v in sourceMesh.Vertices)
            {
                vMap[v.Index] = newMesh.Vertices.Add(new VertexTraits(v.Traits.Position));
            }

            foreach (var edge in sourceMesh.Edges)
            {
                eMap[edge.Index] = newMesh.Vertices.Add(
                    new VertexTraits(TriMeshUtil.GetMidPoint(edge)));
            }

            foreach (TriMesh.Face face in sourceMesh.Faces)
            {
                foreach (var hf in face.Halfedges)
                {
                    newMesh.Faces.AddTriangles(eMap[hf.Edge.Index],
                                               vMap[hf.ToVertex.Index], eMap[hf.Next.Edge.Index]);
                }
                newMesh.Faces.AddTriangles(
                    eMap[face.HalfEdge.Previous.Edge.Index],
                    eMap[face.HalfEdge.Edge.Index],
                    eMap[face.HalfEdge.Next.Edge.Index]);
            }
            return(newMesh);
        }
Esempio n. 11
0
        public static TriMesh.HalfEdge Split(TriMesh.HalfEdge hf, Vector3D v1Pos, Vector3D v2Pos)
        {
            TriMesh mesh = (TriMesh)hf.Mesh;

            List <TriMesh.HalfEdge> list = new List <HalfEdgeMesh.HalfEdge>();

            TriMesh.HalfEdge cur = hf;
            list.Add(cur);
            do
            {
                cur = cur.Opposite.Next;
                list.Add(cur);
            } while (cur.Opposite.Face != null && cur != hf);


            for (int i = 1; i < list.Count; i++)
            {
                TriMeshModify.RemoveEdge(list[i].Edge);
            }
            hf.FromVertex.Traits.Position = v1Pos;
            TriMesh.Vertex v2 = new HalfEdgeMesh.Vertex(new VertexTraits(v2Pos));
            mesh.AppendToVertexList(v2);

            for (int i = 1; i < list.Count; i++)
            {
                mesh.Faces.AddTriangles(list[i - 1].ToVertex, v2, list[i].ToVertex);
            }
            mesh.Faces.AddTriangles(list[0].ToVertex, hf.FromVertex, v2);
            return(hf.FromVertex.FindHalfedgeTo(v2));
        }
Esempio n. 12
0
        public static List<TriMesh> SeperateComponent(TriMesh mesh)
        {
            List<TriMesh> meshes = new List<TriMesh>();
            Dictionary<int, TriMesh.Vertex> map = new Dictionary<int, HalfEdgeMesh.Vertex>();
            bool[] visited = new bool[mesh.Faces.Count];
            Queue<TriMesh.Face> queue = new Queue<HalfEdgeMesh.Face>();

            TriMesh newMesh = new TriMesh();
            queue.Enqueue(mesh.Faces[0]);
            visited[0] = true;
            while (queue.Count != 0)
            {
                TriMesh.Face face = queue.Dequeue();
                foreach (var hf in face.Halfedges)
                {
                    if (!map.ContainsKey(hf.ToVertex.Index))
                    {
                        TriMesh.Vertex v = 
                            new HalfEdgeMesh.Vertex(new VertexTraits(hf.ToVertex.Traits.Position));
                        newMesh.AppendToVertexList(v);
                        map[hf.ToVertex.Index] = v;
                    }
                    if (hf.Opposite.Face != null && !visited[hf.Opposite.Face.Index])
                    {
                        queue.Enqueue(hf.Opposite.Face);
                        visited[hf.Opposite.Face.Index] = true;
                    }
                }

                newMesh.Faces.AddTriangles(
                    map[face.HalfEdge.FromVertex.Index],
                    map[face.HalfEdge.ToVertex.Index],
                    map[face.HalfEdge.Next.ToVertex.Index]);

                if (queue.Count == 0)
                {
                    
                    meshes.Add(newMesh);

                    for (int i = 0; i < visited.Length; i++)
                    {
                        if (!visited[i])
                        {
                            newMesh = new TriMesh();
                            queue.Enqueue(mesh.Faces[i]);
                            visited[i] = true;
                            break;
                        }
                    }
                }
            }


            foreach (TriMesh child in meshes)
            {
                TriMeshUtil.SetUpNormalVertex(child);
            }
            return meshes ;
        }
Esempio n. 13
0
        public static PolygonMesh BuildDual(TriMesh mesh, EnumDual type)
        {
            TriMeshModify.RepaireAllHole(mesh);

            PolygonMesh.Vertex[] faceMap = new HalfEdgeMesh.Vertex[mesh.Faces.Count];
            PolygonMesh.Vertex[] edgeMap = new HalfEdgeMesh.Vertex[mesh.Edges.Count];
            PolygonMesh          pm      = new PolygonMesh();

            foreach (var face in mesh.Faces)
            {
                Vector3D center = Vector3D.Zero;
                switch (type)
                {
                case EnumDual.DualA:
                    center = TriMeshUtil.GetMidPoint(face);
                    break;

                case EnumDual.DualB:
                    TriMesh.Vertex vertex0  = face.GetVertex(0);
                    TriMesh.Vertex vertex1  = face.GetVertex(1);
                    TriMesh.Vertex vertex2  = face.GetVertex(2);
                    Triangle       triangle = new Triangle(vertex0.Traits.Position,
                                                           vertex1.Traits.Position,
                                                           vertex2.Traits.Position);
                    center = triangle.ComputeCircumCenter();
                    break;

                default:
                    break;
                }
                PolygonMesh.Vertex v = new HalfEdgeMesh.Vertex(new VertexTraits(center));
                faceMap[face.Index] = v;
                pm.AppendToVertexList(v);
            }

            foreach (var edge in mesh.Edges)
            {
                VertexTraits       trait = new VertexTraits(TriMeshUtil.GetMidPoint(edge));
                PolygonMesh.Vertex v     = new HalfEdgeMesh.Vertex(trait);
                edgeMap[edge.Index] = v;
                pm.AppendToVertexList(v);
            }

            foreach (var v in mesh.Vertices)
            {
                List <PolygonMesh.Vertex> list = new List <HalfEdgeMesh.Vertex>();
                foreach (var hf in v.HalfEdges)
                {
                    list.Add(faceMap[hf.Face.Index]);
                    list.Add(edgeMap[hf.Edge.Index]);
                }
                list.Reverse();
                pm.Faces.Add(list.ToArray());
            }
            return(pm);
        }
Esempio n. 14
0
 TriMesh.Vertex Clone(TriMesh.Vertex oldV, Vector3D moveVec)
 {
     TriMesh.Vertex newV = new HalfEdgeMesh.Vertex();
     newV.Traits = new VertexTraits(oldV.Traits.Position);
     this.vertexMap.Add(oldV, newV);
     this.mesh.AppendToVertexList(newV);
     oldV.Traits.Position += moveVec;
     newV.Traits.Position -= moveVec;
     return(newV);
 }
Esempio n. 15
0
        public static PolygonMesh BuildDual(TriMesh mesh, EnumDual type)
        {
            TriMeshModify.RepaireAllHole(mesh);

            PolygonMesh.Vertex[] faceMap = new HalfEdgeMesh.Vertex[mesh.Faces.Count];
            PolygonMesh.Vertex[] edgeMap = new HalfEdgeMesh.Vertex[mesh.Edges.Count];
            PolygonMesh pm = new PolygonMesh();

            foreach (var face in mesh.Faces)
            {
                Vector3D center = Vector3D.Zero;
                switch (type)
                {
                    case EnumDual.DualA:
                        center = TriMeshUtil.GetMidPoint(face);
                        break;
                    case EnumDual.DualB:
                        TriMesh.Vertex vertex0 = face.GetVertex(0);
                        TriMesh.Vertex vertex1 = face.GetVertex(1);
                        TriMesh.Vertex vertex2 = face.GetVertex(2);
                        Triangle triangle = new Triangle(vertex0.Traits.Position, 
                                                         vertex1.Traits.Position, 
                                                         vertex2.Traits.Position);
                        center = triangle.ComputeCircumCenter();
                        break;
                    default:
                        break;
                }
                PolygonMesh.Vertex v = new HalfEdgeMesh.Vertex(new VertexTraits(center));
                faceMap[face.Index] = v;
                pm.AppendToVertexList(v);
            }

            foreach (var edge in mesh.Edges)
            {
                VertexTraits trait = new VertexTraits(TriMeshUtil.GetMidPoint(edge));
                PolygonMesh.Vertex v = new HalfEdgeMesh.Vertex(trait);
                edgeMap[edge.Index] = v;
                pm.AppendToVertexList(v);
            }

            foreach (var v in mesh.Vertices)
            {
                List<PolygonMesh.Vertex> list = new List<HalfEdgeMesh.Vertex>();
                foreach (var hf in v.HalfEdges)
                {
                    list.Add(faceMap[hf.Face.Index]);
                    list.Add(edgeMap[hf.Edge.Index]);
                }
                list.Reverse();
                pm.Faces.Add(list.ToArray());
            }
            return pm;
        }
Esempio n. 16
0
        public void Subdivision()
        {
            /*        /\                  /\
             *       /  \                /__\
             *      /    \              /\  /\
             *     /      \            /__\/__\
             *    /        \          /\  /\  /\
             *   /__________\        /__\/__\/__\
             *
             *   为了让每个顶点周围都有它专属的一圈价为6的点,把每个三角形拆成9个
             */
            TriMesh copy = TriMeshIO.Clone(this.mesh);

            this.mesh.Clear();

            TriMesh.Vertex[] faceMap = new HalfEdgeMesh.Vertex[copy.Faces.Count];
            TriMesh.Vertex[] hfMap   = new HalfEdgeMesh.Vertex[copy.HalfEdges.Count];

            foreach (var v in copy.Vertices)
            {
                this.mesh.Vertices.Add(new VertexTraits(v.Traits.Position));
            }

            foreach (var face in copy.Faces)
            {
                faceMap[face.Index] = this.mesh.Vertices.Add(new VertexTraits(TriMeshUtil.GetMidPoint(face)));
            }

            foreach (var hf in copy.HalfEdges)
            {
                Vector3D pos = hf.FromVertex.Traits.Position * 2 / 3 + hf.ToVertex.Traits.Position * 1 / 3;
                hfMap[hf.Index] = this.mesh.Vertices.Add(new VertexTraits(pos));
            }

            foreach (var face in copy.Faces)
            {
                foreach (var hf in face.Halfedges)
                {
                    this.mesh.Faces.AddTriangles(faceMap[face.Index], hfMap[hf.Index], hfMap[hf.Opposite.Index]);
                    this.mesh.Faces.AddTriangles(faceMap[face.Index], hfMap[hf.Opposite.Index], hfMap[hf.Next.Index]);
                }
            }

            foreach (var v in copy.Vertices)
            {
                foreach (var hf in v.HalfEdges)
                {
                    if (hf.Face != null)
                    {
                        this.mesh.Faces.AddTriangles(this.mesh.Vertices[v.Index], hfMap[hf.Index], hfMap[hf.Previous.Opposite.Index]);
                    }
                }
            }
        }
Esempio n. 17
0
 public TriMesh.Vertex[] GetAllCascade(TriMesh.Vertex v)
 {
     TriMesh.Vertex   src = this.GetSrcVertex(v);
     TriMesh.Vertex[] dst = this.GetOtherCascade(src, false);
     TriMesh.Vertex[] all = new HalfEdgeMesh.Vertex[dst.Length + 1];
     all[0] = src;
     for (int i = 0; i < dst.Length; i++)
     {
         all[i + 1] = dst[i];
     }
     return(all);
 }
Esempio n. 18
0
        protected override void AfterMerge(HalfEdgeMesh.Vertex v)
        {
            foreach (var face in this.removed)
            {
                this.heap.Del(handle[face.Index]);
            }

            this.traits.MergeUpdate(v);
            foreach (var face in v.Faces)
            {
                ErrorPair pair = this.GetErrorPair(face);
                this.faceError[face.Index] = pair;
                this.heap.Update(handle[face.Index], pair.Error);
            }
        }
Esempio n. 19
0
        public static void BoundaryExpand(TriMesh mesh)
        {
            double length = TriMeshUtil.ComputeEdgeAvgLength(mesh);
            List <List <TriMesh.HalfEdge> > holes = TriMeshUtil.RetrieveBoundaryEdgeAll(mesh);

            foreach (var hole in holes)
            {
                TriMesh.Vertex[] arr = new HalfEdgeMesh.Vertex[hole.Count];
                for (int i = 0; i < hole.Count; i++)
                {
                    Vector3D normal = Vector3D.UnitX;
                    if (hole[i].Opposite.Face != null)
                    {
                        normal = TriMeshUtil.ComputeNormalFace(hole[i].Opposite.Face);
                    }
                    Vector3D toPos   = hole[i].ToVertex.Traits.Position;
                    Vector3D fromPos = hole[i].FromVertex.Traits.Position;
                    Vector3D hfDir   = toPos - fromPos;
                    Vector3D hfMid   = (toPos + fromPos) / 2;
                    Vector3D pos     = hfMid + normal.Cross(hfDir).Normalize() * length;
                    arr[i] = mesh.Vertices.Add(new VertexTraits(pos));
                }
                for (int i = 0; i < hole.Count; i++)
                {
                    int          next = (i + 1) % hole.Count;
                    TriMesh.Face face = mesh.Faces.Add(arr[i],
                                                       hole[i].ToVertex,
                                                       hole[next].ToVertex);
                    face.Traits.SelectedFlag = 1;
                    face = mesh.Faces.Add(arr[i],
                                          hole[next].ToVertex,
                                          arr[next]);
                    face.Traits.SelectedFlag = 1;
                }
            }
        }
Esempio n. 20
0
        public static TriMesh CreateGrid(int m, int n, double lengthx,double lengthy)
        {
            TriMesh mesh = new TriMesh();
            TriMesh.Vertex[,] arr = new HalfEdgeMesh.Vertex[m, n];
            double x0 = -m * lengthx / 2d;
            double y0 = -n * lengthy / 2d;
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    arr[i, j] = new HalfEdgeMesh.Vertex();
                    arr[i, j].Traits = new VertexTraits(x0 + i * lengthx, y0 + j * lengthy, 0d);
                    mesh.AppendToVertexList(arr[i, j]);
                }
            }

            for (int i = 0; i < m - 1; i++)
            {
                for (int j = 0; j < n - 1; j++)
                {
                    mesh.Faces.AddTriangles(arr[i + 1, j], arr[i, j + 1], arr[i, j]);
                    mesh.Faces.AddTriangles(arr[i + 1, j], arr[i + 1, j + 1], arr[i, j + 1]);
                }
            }
            return mesh;
        }
Esempio n. 21
0
        public static TriMesh CreateCylinderPlane(int m, int n, double r,
                                double l, double maxU, double maxV, int diff)
        {
            TriMesh mesh = new TriMesh();
            TriMesh.Vertex[,] arr = new HalfEdgeMesh.Vertex[m, n];
            for (int i = 0; i < m; i++)
            {
                double x = l / m * i - l / 2;
              
                for (int j = 0; j < n; j++)
                { 
                    double y = l / n * j - l / 2;
                    VertexTraits trait = new VertexTraits(x,y, 0);

                    trait.UV = new Vector2D(x, y);
                    arr[i, j] = mesh.Vertices.Add(trait);
                }
            }
            for (int i = 0; i < m - 1; i++)
            {
                for (int j = 0; j < n - diff; j++)
                {
                    int ni = i + 1;
                    int nj = (j + 1) % n;
                    mesh.Faces.AddTriangles(arr[i, nj], arr[ni, nj],
                                            arr[ni, j], arr[i, j]);
                }
            }
            return mesh;
        }
Esempio n. 22
0
 public static TriMesh CreateCylinder(int m, int n, double r, 
                          double l, double maxU, double maxV,int diff)
 {
     TriMesh mesh = new TriMesh();
     TriMesh.Vertex[,] arr = new HalfEdgeMesh.Vertex[m, n];
     for (int i = 0; i < m; i++)
     {
         double z = l / m * i - l / 2;
         double v = maxV / m * i;
         for (int j = 0; j < n; j++)
         {
             double x = r * Math.Cos(Math.PI * 2 / n * j);
             double y = r * Math.Sin(Math.PI * 2 / n * j);
             double u = maxU / n * j;
             VertexTraits trait = new VertexTraits(x, y, z);
             trait.UV = new Vector2D(u, v);
             arr[i, j] = mesh.Vertices.Add(trait);
         }
     }
     for (int i = 0; i < m - 1; i++)
     {
         for (int j = 0; j < n-diff; j++)
         {
             int ni = i + 1;
             int nj = (j + 1) % n;
             mesh.Faces.AddTriangles(arr[i, nj], arr[ni, nj], 
                                     arr[ni, j], arr[i, j]);
         }
     }
     return mesh;
 }
Esempio n. 23
0
        public static TriMesh CreatePlaneFolded(int m, int n, double l)
        {
            TriMesh mesh = new TriMesh();
            TriMesh.Vertex[,] arr = new HalfEdgeMesh.Vertex[m + 1, n + 1];
            for (int i = 0; i <= m; i++)
            {
                double x = l / m * i  ;

                double temp = 0;
                for (int j = 0; j <= n/2; j++)
                {
                    double y = l / n * j  ;
                    VertexTraits trait = new VertexTraits(x, y, 0);

                    trait.UV = new Vector2D(x, y);
                    arr[i, j] = mesh.Vertices.Add(trait);


                    temp = y;
                }


                for (int j = 1; j <= n / 2; j++)
                {
                    double y = l / n * j;
                    VertexTraits trait = new VertexTraits(x, temp, y);

                    trait.UV = new Vector2D(x, y);
                    arr[i,  n / 2+j] = mesh.Vertices.Add(trait);
                }

            }
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    int ni = i + 1;
                    int nj = j + 1;
                    mesh.Faces.AddTriangles(arr[i, nj], arr[ni, nj],
                                            arr[ni, j], arr[i, j]);
                }
            }
            return mesh;
        }
Esempio n. 24
0
        private TriMesh ChangeTopologyLoopSelected(TriMesh sourceMesh)
        {
            TriMesh newMesh = new TriMesh();

            newMesh.Clear();

            vMap = new HalfEdgeMesh.Vertex[sourceMesh.Vertices.Count];
            eMap = new HalfEdgeMesh.Vertex[Mesh.Edges.Count];

            foreach (var v in sourceMesh.Vertices)
            {
                vMap[v.Index] = newMesh.Vertices.Add(new VertexTraits(v.Traits.Position));
            }

            foreach (var edge in sourceMesh.Edges)
            {
                if (edge.Vertex0.Traits.SelectedFlag != 0 && edge.Vertex1.Traits.SelectedFlag != 0)
                {
                    eMap[edge.Index] = newMesh.Vertices.Add(new VertexTraits(TriMeshUtil.GetMidPoint(edge)));
                }
            }

            foreach (TriMesh.Face face in sourceMesh.Faces)
            {
                List <TriMesh.HalfEdge> list = new List <HalfEdgeMesh.HalfEdge>();
                foreach (var hf in face.Halfedges)
                {
                    if (hf.ToVertex.Traits.SelectedFlag != 0 && hf.FromVertex.Traits.SelectedFlag != 0)
                    {
                        list.Add(hf);
                    }
                }

                switch (list.Count)
                {
                case 0:
                    newMesh.Faces.AddTriangles(
                        vMap[face.GetVertex(0).Index],
                        vMap[face.GetVertex(1).Index],
                        vMap[face.GetVertex(2).Index]);
                    break;

                case 1:
                    TriMesh.HalfEdge h = list[0];
                    newMesh.Faces.AddTriangles(
                        eMap[h.Edge.Index],
                        vMap[h.ToVertex.Index],
                        vMap[h.Next.ToVertex.Index]);
                    newMesh.Faces.AddTriangles(
                        eMap[h.Edge.Index],
                        vMap[h.Next.ToVertex.Index],
                        vMap[h.FromVertex.Index]);
                    break;

                case 3:
                    foreach (var hf in face.Halfedges)
                    {
                        newMesh.Faces.AddTriangles(eMap[hf.Edge.Index], vMap[hf.ToVertex.Index], eMap[hf.Next.Edge.Index]);
                    }
                    newMesh.Faces.AddTriangles(
                        eMap[face.HalfEdge.Previous.Edge.Index],
                        eMap[face.HalfEdge.Edge.Index],
                        eMap[face.HalfEdge.Next.Edge.Index]);
                    break;

                default:
                    break;
                }
            }
            return(newMesh);
        }
Esempio n. 25
0
        public void Subdivision()
        {
            /*        /\                  /\
             *       /  \                /__\
             *      /    \              /\  /\
             *     /      \            /__\/__\
             *    /        \          /\  /\  /\
             *   /__________\        /__\/__\/__\
             *   
             *   为了让每个顶点周围都有它专属的一圈价为6的点,把每个三角形拆成9个
             */
            TriMesh copy = TriMeshIO.Clone(this.mesh);
            this.mesh.Clear();

            TriMesh.Vertex[] faceMap = new HalfEdgeMesh.Vertex[copy.Faces.Count];
            TriMesh.Vertex[] hfMap = new HalfEdgeMesh.Vertex[copy.HalfEdges.Count];

            foreach (var v in copy.Vertices)
            {
                this.mesh.Vertices.Add(new VertexTraits(v.Traits.Position));
            }

            foreach (var face in copy.Faces)
            {
                faceMap[face.Index] = this.mesh.Vertices.Add(new VertexTraits(TriMeshUtil.GetMidPoint(face)));
            }

            foreach (var hf in copy.HalfEdges)
            {
                Vector3D pos = hf.FromVertex.Traits.Position * 2 / 3 + hf.ToVertex.Traits.Position * 1 / 3;
                hfMap[hf.Index] = this.mesh.Vertices.Add(new VertexTraits(pos));
            }

            foreach (var face in copy.Faces)
            {
                foreach (var hf in face.Halfedges)
                {
                    this.mesh.Faces.AddTriangles(faceMap[face.Index], hfMap[hf.Index], hfMap[hf.Opposite.Index]);
                    this.mesh.Faces.AddTriangles(faceMap[face.Index], hfMap[hf.Opposite.Index], hfMap[hf.Next.Index]);
                }
            }

            foreach (var v in copy.Vertices)
            {
                foreach (var hf in v.HalfEdges)
                {
                    if (hf.Face != null)
                    {
                        this.mesh.Faces.AddTriangles(this.mesh.Vertices[v.Index], hfMap[hf.Index], hfMap[hf.Previous.Opposite.Index]);
                    }
                }
            }
        }
Esempio n. 26
0
        public TriMesh Cut(IEnumerable<TriMesh.Vertex> region)
        {
            Dictionary<int, TriMesh.Vertex> vMap = new Dictionary<int, HalfEdgeMesh.Vertex>();
            Dictionary<int, bool> fFlag = new Dictionary<int, bool>();

      
            TriMesh newMesh = new TriMesh();

            foreach (var v in region)
            {
                TriMesh.Vertex newV = new HalfEdgeMesh.Vertex(
                    new VertexTraits(v.Traits.Position));
                vMap[v.Index] = newV;
                newMesh.AppendToVertexList(newV);
            }

            foreach (var f in this.mesh.Faces)
            {
                bool inner = true;
                foreach (var v in f.Vertices)
                {
                    if (!vMap.ContainsKey(v.Index))
                    {
                        inner = false;
                        break;
                    }
                }
                if (inner)
                {
                    TriMesh.HalfEdge hf = f.HalfEdge;
                    newMesh.Faces.AddTriangles(
                        vMap[hf.FromVertex.Index],
                        vMap[hf.ToVertex.Index],
                        vMap[hf.Next.ToVertex.Index]);
                    fFlag[f.Index] = true;
                }
            }

            List<TriMesh.Edge> remove = new List<HalfEdgeMesh.Edge>();

            foreach (var e in this.mesh.Edges)
            {
                if (fFlag.ContainsKey(e.Face0.Index) 
                    && fFlag.ContainsKey(e.Face1.Index))
                {
                    remove.Add(e);
                }
            }
            foreach (var e in remove)
            {
                TriMeshModify.RemoveEdge(e);
            }

            foreach (var v in region)
            {
                bool inner = true;
                foreach (var round in v.Vertices)
                {
                    if (!vMap.ContainsKey(round.Index))
                    {
                        inner = false;
                    }
                }
                if (inner)
                {
                    this.mesh.RemoveVertex(v);
                }
            }

            return newMesh;
        }
Esempio n. 27
0
        TriMesh Create(IEnumerable<TriMesh.Face> region)
        {
            TriMesh newMesh = new TriMesh();

            foreach (var f in region)
            {
                TriMesh.Vertex[] arr = new HalfEdgeMesh.Vertex[3];
                int i = 0;
                foreach (var v in f.Vertices)
                {
                    if (!this.vMap.ContainsKey(v))
                    {
                        TriMesh.Vertex newV =
                            new HalfEdgeMesh.Vertex(new VertexTraits(v.Traits.Position));
                        this.vMap[v] = newV;
                        newMesh.AppendToVertexList(newV);
                    }
                    arr[i++] = this.vMap[v];
                }
                newMesh.Faces.AddTriangles(arr);
                this.fFlag[f.Index] = true;
            }

            return newMesh;
        }
Esempio n. 28
0
 public static void BoundaryExpand(TriMesh mesh)
 {
     double length = TriMeshUtil.ComputeEdgeAvgLength(mesh);
     List<List<TriMesh.HalfEdge>> holes = TriMeshUtil.RetrieveBoundaryEdgeAll(mesh);
     foreach (var hole in holes)
     {
     TriMesh.Vertex[] arr = new HalfEdgeMesh.Vertex[hole.Count];
     for (int i = 0; i < hole.Count; i++)
     {
         Vector3D normal = Vector3D.UnitX;
         if (hole[i].Opposite.Face != null)
         {
             normal = TriMeshUtil.ComputeNormalFace(hole[i].Opposite.Face);
         }
         Vector3D toPos = hole[i].ToVertex.Traits.Position;
         Vector3D fromPos = hole[i].FromVertex.Traits.Position;
         Vector3D hfDir = toPos - fromPos;
         Vector3D hfMid = (toPos + fromPos) / 2;
         Vector3D pos = hfMid + normal.Cross(hfDir).Normalize() * length;
         arr[i] = mesh.Vertices.Add(new VertexTraits(pos));
     }
     for (int i = 0; i < hole.Count; i++)
     {
         int next = (i + 1) % hole.Count;
         TriMesh.Face face= mesh.Faces.Add(arr[i], 
                                           hole[i].ToVertex, 
                                           hole[next].ToVertex);
         face.Traits.SelectedFlag = 1;
         face = mesh.Faces.Add(arr[i], 
                               hole[next].ToVertex, 
                               arr[next]);
         face.Traits.SelectedFlag = 1;
     }
     }
 }
Esempio n. 29
0
        public TriMesh Cut(IEnumerable <TriMesh.Vertex> region)
        {
            Dictionary <int, TriMesh.Vertex> vMap  = new Dictionary <int, HalfEdgeMesh.Vertex>();
            Dictionary <int, bool>           fFlag = new Dictionary <int, bool>();


            TriMesh newMesh = new TriMesh();

            foreach (var v in region)
            {
                TriMesh.Vertex newV = new HalfEdgeMesh.Vertex(
                    new VertexTraits(v.Traits.Position));
                vMap[v.Index] = newV;
                newMesh.AppendToVertexList(newV);
            }

            foreach (var f in this.mesh.Faces)
            {
                bool inner = true;
                foreach (var v in f.Vertices)
                {
                    if (!vMap.ContainsKey(v.Index))
                    {
                        inner = false;
                        break;
                    }
                }
                if (inner)
                {
                    TriMesh.HalfEdge hf = f.HalfEdge;
                    newMesh.Faces.AddTriangles(
                        vMap[hf.FromVertex.Index],
                        vMap[hf.ToVertex.Index],
                        vMap[hf.Next.ToVertex.Index]);
                    fFlag[f.Index] = true;
                }
            }

            List <TriMesh.Edge> remove = new List <HalfEdgeMesh.Edge>();

            foreach (var e in this.mesh.Edges)
            {
                if (fFlag.ContainsKey(e.Face0.Index) &&
                    fFlag.ContainsKey(e.Face1.Index))
                {
                    remove.Add(e);
                }
            }
            foreach (var e in remove)
            {
                TriMeshModify.RemoveEdge(e);
            }

            foreach (var v in region)
            {
                bool inner = true;
                foreach (var round in v.Vertices)
                {
                    if (!vMap.ContainsKey(round.Index))
                    {
                        inner = false;
                    }
                }
                if (inner)
                {
                    this.mesh.RemoveVertex(v);
                }
            }

            return(newMesh);
        }
Esempio n. 30
0
        public static TriMesh.HalfEdge Split(TriMesh.HalfEdge hf, Vector3D v1Pos, Vector3D v2Pos)
        {
            TriMesh mesh = (TriMesh)hf.Mesh;

            List<TriMesh.HalfEdge> list = new List<HalfEdgeMesh.HalfEdge>();
            TriMesh.HalfEdge cur = hf;
            list.Add(cur);
            do
            {
                cur = cur.Opposite.Next;
                list.Add(cur);
            } while (cur.Opposite.Face != null && cur != hf);

           
            for (int i = 1; i < list.Count; i++)
            {
                TriMeshModify.RemoveEdge(list[i].Edge);
            }
            hf.FromVertex.Traits.Position = v1Pos;
            TriMesh.Vertex v2 = new HalfEdgeMesh.Vertex(new VertexTraits(v2Pos));
            mesh.AppendToVertexList(v2);

            for (int i = 1; i < list.Count; i++)
            {
                mesh.Faces.AddTriangles(list[i - 1].ToVertex, v2, list[i].ToVertex);
            }
            mesh.Faces.AddTriangles(list[0].ToVertex, hf.FromVertex, v2);
            return hf.FromVertex.FindHalfedgeTo(v2);
        }
Esempio n. 31
0
 TriMesh.Vertex Clone(TriMesh.Vertex oldV, Vector3D moveVec)
 {
     TriMesh.Vertex newV = new HalfEdgeMesh.Vertex();
     newV.Traits = new VertexTraits(oldV.Traits.Position);
     this.vertexMap.Add(oldV, newV);
     this.mesh.AppendToVertexList(newV);
     oldV.Traits.Position += moveVec;
     newV.Traits.Position -= moveVec;
     return newV;
 }
Esempio n. 32
0
        private TriMesh ChangeTopologyLoopSelected(TriMesh sourceMesh)
        {
            TriMesh newMesh = new TriMesh();
            newMesh.Clear();

            vMap = new HalfEdgeMesh.Vertex[sourceMesh.Vertices.Count];
            eMap = new HalfEdgeMesh.Vertex[Mesh.Edges.Count];

            foreach (var v in sourceMesh.Vertices)
            {
                vMap[v.Index] = newMesh.Vertices.Add(new VertexTraits(v.Traits.Position));
            }

            foreach (var edge in sourceMesh.Edges)
            {
                if (edge.Vertex0.Traits.SelectedFlag != 0 && edge.Vertex1.Traits.SelectedFlag != 0)
                {
                    eMap[edge.Index] = newMesh.Vertices.Add(new VertexTraits(TriMeshUtil.GetMidPoint(edge)));
                }
            }

            foreach (TriMesh.Face face in sourceMesh.Faces)
            {
                List<TriMesh.HalfEdge> list = new List<HalfEdgeMesh.HalfEdge>();
                foreach (var hf in face.Halfedges)
                {
                    if (hf.ToVertex.Traits.SelectedFlag != 0 && hf.FromVertex.Traits.SelectedFlag != 0)
                    {
                        list.Add(hf);
                    }
                }

                switch (list.Count)
                {
                    case 0:
                        newMesh.Faces.AddTriangles(
                            vMap[face.GetVertex(0).Index],
                            vMap[face.GetVertex(1).Index],
                            vMap[face.GetVertex(2).Index]);
                        break;
                    case 1:
                        TriMesh.HalfEdge h = list[0];
                        newMesh.Faces.AddTriangles(
                            eMap[h.Edge.Index],
                            vMap[h.ToVertex.Index],
                            vMap[h.Next.ToVertex.Index]);
                        newMesh.Faces.AddTriangles(
                            eMap[h.Edge.Index],
                            vMap[h.Next.ToVertex.Index],
                            vMap[h.FromVertex.Index]);
                        break;
                    case 3:
                        foreach (var hf in face.Halfedges)
                        {
                            newMesh.Faces.AddTriangles(eMap[hf.Edge.Index], vMap[hf.ToVertex.Index], eMap[hf.Next.Edge.Index]);
                        }
                        newMesh.Faces.AddTriangles(
                            eMap[face.HalfEdge.Previous.Edge.Index],
                            eMap[face.HalfEdge.Edge.Index],
                            eMap[face.HalfEdge.Next.Edge.Index]);
                        break;
                    default:
                        break;
                }
            }
            return newMesh;
        }