• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

C# GraphicResearchHuiZhao.TriMesh类代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了C#中GraphicResearchHuiZhao.TriMesh的典型用法代码示例。如果您正苦于以下问题:C# TriMesh类的具体用法?C# TriMesh怎么用?C# TriMesh使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。



TriMesh类属于GraphicResearchHuiZhao命名空间,在下文中一共展示了TriMesh类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C#代码示例。

示例1: UpdateHodgeStar

        public void UpdateHodgeStar(TriMesh mesh)
        {
            foreach (TriMesh.Edge edge in mesh.Edges)
            {
                double sum = 0;

                TriMesh.HalfEdge currentHe = edge.HalfEdge0;
                do
                {
                    Vector3D a = currentHe.FromVertex.Traits.Position;
                    Vector3D b = currentHe.Next.FromVertex.Traits.Position;
                    Vector3D c = currentHe.Next.Next.FromVertex.Traits.Position;

                    Vector3D u = a - c;
                    Vector3D v = b - c;

                    double cotTheta = (u.Dot(v)) / u.Cross(v).Length();

                    sum += 0.5 * cotTheta;

                } while (currentHe != edge.HalfEdge0);

                EdgeHodgeStar1[edge.Index] = Math.Max(sum, 0);

            }


        }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:28,代码来源:PriorNonTrivalConnection.cs


示例2: GrowByFaceAngle

        public static void GrowByFaceAngle(TriMesh mesh)
        {
            Queue<TriMesh.Face> queue = new Queue<HalfEdgeMesh.Face>();
            Vector3D[] normal = TriMeshUtil.ComputeNormalFace(mesh);
            foreach (var face in mesh.Faces)
            {
                if (face.Traits.SelectedFlag != 0)
                {
                    queue.Enqueue(face);
                }
            }

            double k = 0.449;
            while (queue.Count != 0)
            {
                TriMesh.Face center = queue.Dequeue();
                foreach (var round in center.Faces)
                {
                    if (round.Traits.SelectedFlag == 0)
                    {
                        if (normal[center.Index].Dot(normal[round.Index]) > k)
                        {
                            round.Traits.SelectedFlag = center.Traits.SelectedFlag;
                            queue.Enqueue(round);
                        }
                    }
                }
            }
        }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:29,代码来源:SegementationGrow.cs


示例3: KMean

        public static void KMean(TriMesh mesh)
        {
            Dictionary<int, Cluster> dict = new Dictionary<int, Cluster>();
            Queue<TriMesh.Face> queue = new Queue<HalfEdgeMesh.Face>();
            foreach (var face in mesh.Faces)
            {
                if (face.Traits.SelectedFlag != 0)
                {
                    dict[face.Traits.SelectedFlag] = new Cluster();
                    dict[face.Traits.SelectedFlag].Add(TriMeshUtil.GetMidPoint(face));
                    queue.Enqueue(face);
                }
            }

            while (queue.Count != 0)
            {
                TriMesh.Face center = queue.Dequeue();
                foreach (var round in center.Faces)
                {
                    if (round.Traits.SelectedFlag == 0)
                    {
                        int index = GetNearest(round, dict);
                        dict[index].Add(TriMeshUtil.GetMidPoint(round));
                        round.Traits.SelectedFlag = (byte)index;
                        queue.Enqueue(round);
                    }
                }
            }
        }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:29,代码来源:SegementationGrow.cs


示例4: AddSelectionVertex

         public TriMesh AddSelectionVertex(TriMesh mesh, int index)
         {
             List<TriMesh> sel = new List<TriMesh>();
             for(int i=0;i<mesh.Vertices.Count;i++)
             {

                 if (mesh.Vertices[i].Traits.SelectedFlag == index)
                 {

                     TriMesh selV = TriMeshIO.FromObjFile(ConfigShape.Instance.VertexFile);
                     for (int j = 0; j < selV.Vertices.Count;j++ )
                     {
                         selV.Vertices[j].Traits.SelectedFlag =(byte)index;
                     }
                         TriMeshUtil.ScaleToUnit(selV, ConfigShape.Instance.Scale);
                     TriMeshUtil.TransformationMove(selV, mesh.Vertices[i].Traits.Position);
                     sel.Add(selV);
                 }
                
             }

            TriMesh result= TriMeshUtil.Combine(sel);
            result.FileName = Path.GetFileNameWithoutExtension(mesh.FileName) + "-V-" + index.ToString();

            TriMeshUtil.SetUpVertexNormal(result, EnumNormal.AreaWeight);
             return result;
         }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:27,代码来源:TriMeshShapeSelection.cs


示例5: Move

 public static void Move(TriMesh mesh, Vector3D vec)
 {
     foreach (var v in mesh.Vertices)
     {
         v.Traits.Position += vec;
     }
 }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:7,代码来源:TriMeshInverse.cs


示例6: DrawColor

        public void DrawColor(TriMesh mesh)
        {
            GL.Enable(EnableCap.ColorMaterial);
            GL.ShadeModel(ShadingModel.Smooth);
            GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
            GL.Enable(EnableCap.Normalize);

            GL.Begin(BeginMode.Triangles);
            for (int i = 0; i < mesh.Faces.Count; i++)
            {


                foreach (TriMesh.Vertex vertex in mesh.Faces[i].Vertices)
                {

                    GL.Color3(vertex.Traits.Color.R, vertex.Traits.Color.G, vertex.Traits.Color.B);

                    GL.Normal3(vertex.Traits.Normal.x,
                               vertex.Traits.Normal.y,
                               vertex.Traits.Normal.z);
                    GL.Vertex3(vertex.Traits.Position.x,
                               vertex.Traits.Position.y,
                               vertex.Traits.Position.z);

                }
            }
            GL.End();

        }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:29,代码来源:OpenGLTriMeshDistance.cs


示例7: DrawMultiTextureUV

        private static void DrawMultiTextureUV(TriMesh mesh)
        {
            GL.Begin(BeginMode.Triangles);
            for (int i = 0; i < mesh.Faces.Count; i++)
            {
                foreach (TriMesh.Vertex vertex in mesh.Faces[i].Vertices)
                {
                    GL.Normal3(vertex.Traits.Normal.x, 
                               vertex.Traits.Normal.y, 
                               vertex.Traits.Normal.z); 

                    GL.MultiTexCoord2(TextureUnit.Texture0, 
                                      vertex.Traits.UV[0], 
                                      vertex.Traits.UV[1]);
                    GL.MultiTexCoord2(TextureUnit.Texture1, 
                                      vertex.Traits.UV[0], 
                                      vertex.Traits.UV[1]); 
                    
                    GL.Vertex3(vertex.Traits.Position.x, 
                               vertex.Traits.Position.y, 
                               vertex.Traits.Position.z);
                }
            }
            GL.End();
        }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:25,代码来源:OpenGLTriMeshTexture.cs


示例8: Split

        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;
        }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:28,代码来源:SplitVertex.cs


示例9: ComputePrincipalCurvature

 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;
 }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:27,代码来源:CurvatureWithPG07.cs


示例10: SmoothTaubin

 public static void SmoothTaubin(TriMesh Mesh)
 {
     double weight =  ConfigMeshOP.Instance.SmoothTaubinLamda;
     int iterative = ConfigMeshOP.Instance.SmoothTaubinIterative;
     bool cot=ConfigMeshOP.Instance.SmoothTaubinCot;
     int n = Mesh.Vertices.Count;  
     double[][] lap =null; 
     for (int j = 0; j < iterative; j++)
     {
         if (cot)
         {
             lap = LaplaceManager.Instance.ComputeLaplacianCotNormalize(Mesh);
         }
         else
         {
             lap = LaplaceManager.Instance.ComputeLaplacianUniform(Mesh);
         }
         for (int i = 0; i < n; i++)
         {
            Mesh.Vertices[i].Traits.Position.x += lap[0][i] * weight;
            Mesh.Vertices[i].Traits.Position.y += lap[1][i] * weight;
            Mesh.Vertices[i].Traits.Position.z += lap[2][i] * weight;
         }
     } 
 }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:25,代码来源:TriMeshSmooth.cs


示例11: cBuildExteriorDerivative1Form

        public SparseMatrixComplex cBuildExteriorDerivative1Form(TriMesh mesh)
        {
            SparseMatrixComplex d1 = new SparseMatrixComplex(mesh.Faces.Count, mesh.Edges.Count);

            foreach (TriMesh.Face face in mesh.Faces)
            {
                foreach (TriMesh.HalfEdge hf in face.Halfedges)
                {
                    double s = 0;

                    if (hf.Edge.HalfEdge0 == hf)
                    {
                        s = -1;
                    }
                    else
                    {
                        s = 1;
                    }

                    d1[face.Index, hf.Edge.Index] = new Complex(s, 0);
                }
            }

            return d1;
        }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:25,代码来源:DECMeshComplex.cs


示例12: Init

        public static void Init(TriMesh mesh)
        {
            nv = mesh.Vertices.Count;
            TriMeshIO.WriteToObjFile(FileName, mesh);

            FromObjFile(mesh.FileName);
        }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:7,代码来源:TriMeshCurvature.cs


示例13: Clone

        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;
        }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:26,代码来源:TriMeshIO.cs


示例14: ComputeFunction

 public double[] ComputeFunction(TriMesh mesh)
 {
     SparseMatrix sparse = BuildMatrixA(mesh);
     double[] rightB = BuildRightB(mesh); 
     double[] unknownX = LinearSystem.Instance.SolveSystem(ref sparse, ref rightB, mesh.FileName);
     return unknownX;
 }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:7,代码来源:FunctionSmoothedCurvature.cs


示例15: CreateNBsplineCurve

        public  TriMesh CreateNBsplineCurve(TriMesh mesh)
        {
            TriMesh BezierCurve = new TriMesh();
            double x = 0;
            double y = 0;
            double z = 0;

            for (int i = 0; i < Point - 2; i++)
            {
                for (int t = 0; t <= VerticesNum; t++)
                {
                    double tt = (double)t / (double)VerticesNum;
                    //x = (double)1 / 6 * ((-Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) - 3 * tt + 1)) * mesh.Vertices[0].Traits.Position.x
                    //    + (double)1 / 6 * ((3 * Math.Pow(tt, 3) - 6 * Math.Pow(tt, 2) + 4)) * mesh.Vertices[1].Traits.Position.x
                    //    + (double)1 / 6 * ((-3 * Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) + 3 * tt + 1)) * mesh.Vertices[2].Traits.Position.x
                    //    + (double)1 / 6 * Math.Pow(tt, 3) * mesh.Vertices[3].Traits.Position.x;
                    //y = (double)1 / 6 * ((-Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) - 3 * tt + 1)) * mesh.Vertices[0].Traits.Position.y
                    //    + (double)1 / 6 * ((3 * Math.Pow(tt, 3) - 6 * Math.Pow(tt, 2) + 4)) * mesh.Vertices[1].Traits.Position.y
                    //    + (double)1 / 6 * ((-3 * Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) + 3 * tt + 1)) * mesh.Vertices[2].Traits.Position.y
                    //    + (double)1 / 6 * Math.Pow(tt, 3) * mesh.Vertices[3].Traits.Position.y;
                    x = (double)1 / 6 * ((-Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) - 3 * tt + 1)) * mesh.Vertices[i].Traits.Position.x
                        + (double)1 / 6 * ((3 * Math.Pow(tt, 3) - 6 * Math.Pow(tt, 2) + 4)) * mesh.Vertices[i + 1].Traits.Position.x
                        + (double)1 / 6 * ((-3 * Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) + 3 * tt + 1)) * mesh.Vertices[i + 2].Traits.Position.x
                        + (double)1 / 6 * Math.Pow(tt, 3) * mesh.Vertices[i + 3].Traits.Position.x;
                    y = (double)1 / 6 * ((-Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) - 3 * tt + 1)) * mesh.Vertices[i].Traits.Position.y
                       + (double)1 / 6 * ((3 * Math.Pow(tt, 3) - 6 * Math.Pow(tt, 2) + 4)) * mesh.Vertices[i + 1].Traits.Position.y
                       + (double)1 / 6 * ((-3 * Math.Pow(tt, 3) + 3 * Math.Pow(tt, 2) + 3 * tt + 1)) * mesh.Vertices[i + 2].Traits.Position.y
                       + (double)1 / 6 * Math.Pow(tt, 3) * mesh.Vertices[i + 3].Traits.Position.y;
                    BezierCurve.Vertices.Add(new VertexTraits(x, y, z));
                    x = 0;
                    y = 0;
                }
            }
            return BezierCurve;
        }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:35,代码来源:CurveBSpline.cs


示例16: PlaneCut

        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;
                    }
                }
            }
        }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:32,代码来源:TriMeshCut.cs


示例17: DrawColorVis

        public void DrawColorVis(TriMesh mesh)
        {
            if (GlobalData.Instance.ColorVis == null)
                return;

            if (GlobalData.Instance.ColorVis.Length != mesh.Vertices.Count)
                return;

            GL.ShadeModel(ShadingModel.Smooth);
            GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
            GL.Enable(EnableCap.Normalize);

            GL.Begin(BeginMode.Triangles);
            for (int i = 0; i < mesh.Faces.Count; i++)
            {

                foreach (TriMesh.Vertex vertex in mesh.Faces[i].Vertices)
                {
                    float alpha = (float)GlobalData.Instance.ColorVis[vertex.Index];

                    GL.Color4(alpha, alpha, alpha, alpha);

                    GL.Normal3(vertex.Traits.Normal.x,
                               vertex.Traits.Normal.y,
                               vertex.Traits.Normal.z);
                    GL.Vertex3(vertex.Traits.Position.x,
                               vertex.Traits.Position.y,
                               vertex.Traits.Position.z);

                }
            }
            GL.End();

        }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:34,代码来源:OpenGLTriMeshDistance.cs


示例18: ComputeNormalVertex

        public static Vector3D[] ComputeNormalVertex(TriMesh mesh, EnumNormal type)
        {
            if (type == null)
            {
                type=EnumNormal.UniformWeight ;
            }

            Vector3D[] normal = null;
            switch (type)
            {
                case EnumNormal.AreaWeight:
                    normal= ComputeNormalAreaWeight(mesh);
                    break;
                case EnumNormal.SphereInscribed:
                    normal = ComputeNormalSphereInscribed(mesh);
                    break;
                case EnumNormal.TipAngleWeight:
                    normal = ComputeNormalTipAngleWeight(mesh);
                    break;
                case EnumNormal.UniformWeight:
                    normal = ComputeNormalUniformWeight(mesh);
                    break;

                    
            }
           
            return normal;
        }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:28,代码来源:TriMeshNormal.cs


示例19: LoadObjStream

        /// <summary>
        /// Loads an OBJ file from a stream.
        /// </summary>
        /// <param name="stream">A stream with OBJ file data.</param>
        private static TriMesh LoadObjStream(Stream stream)
        {
            TriMesh mesh = new TriMesh();
            mesh.Traits.HasFaceVertexNormals = true;
            mesh.Traits.HasTextureCoordinates = true;

            StreamReader sr = new StreamReader(stream);
            ObjFileProcessorState state = new ObjFileProcessorState();
            string line;

            while ((line = sr.ReadLine()) != null)
            {

                ProcessObjLine(mesh, line, state);

            }

            if (state.VertexTextureCoords.Count == mesh.Vertices.Count)
            {
                for (int i = 0; i < mesh.Vertices.Count; i++)
                {
                    mesh.Vertices[i].Traits.UV = state.VertexTextureCoords[i];
                }
            }
            mesh.TrimExcess();
            return mesh;
        }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:31,代码来源:TriMeshIOobj.cs


示例20: DrawConnectionVector

        public void DrawConnectionVector(TriMesh m)
        {
            for (int i = 0; i < m.Faces.Count; i++)
            {
                GL.Color3(0.0f, 0.0f, 1.0f);

                Vector3D faceCenter = new Vector3D();

                //Get Face center point
                faceCenter.x = (m.Faces[i].GetVertex(0).Traits.Position.x +
                                  m.Faces[i].GetVertex(1).Traits.Position.x +
                                  m.Faces[i].GetVertex(2).Traits.Position.x) / 3;

                faceCenter.y = (m.Faces[i].GetVertex(0).Traits.Position.y +
                                  m.Faces[i].GetVertex(1).Traits.Position.y +
                                  m.Faces[i].GetVertex(2).Traits.Position.y) / 3;

                faceCenter.z = (m.Faces[i].GetVertex(0).Traits.Position.z +
                                  m.Faces[i].GetVertex(1).Traits.Position.z +
                                  m.Faces[i].GetVertex(2).Traits.Position.z) / 3;

                //Face Normal Vector
               // Vector3D vector = m.Faces[i].faceVector.Normalize();

                GL.Begin(BeginMode.Lines);

                GL.Color3(Color.Black);

                GL.Vertex3(faceCenter.x, faceCenter.y, faceCenter.z);
               // GL.Vertex3(faceCenter.x - 0.2 * vector.x, faceCenter.y - 0.2 * vector.y, faceCenter.z - 0.2 * vector.z);

                GL.End();

            }
        }
开发者ID:meshdgp,项目名称:MeshDGP,代码行数:35,代码来源:OpenGLTriMeshEnhanced.cs



注:本文中的GraphicResearchHuiZhao.TriMesh类示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C# Drawing.Surface类代码示例发布时间:2022-05-26
下一篇:
C# GraphView.WSqlFragmentVisitor类代码示例发布时间:2022-05-26
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap