private void AddFace(string values)
        {
            // A polygonal face. The numbers are indexes into the arrays of vertex positions, 
            // texture coordinates, and normals respectively. A number may be omitted if, 
            // for example, texture coordinates are not being defined in the model.
            // There is no maximum number of vertices that a single polygon may contain. 
            // The .obj file specification says that each face must be flat and convex. 

            var fields = values.Split(' ');
            var pts = new Point3DCollection();
            var tex = new PointCollection();
            var norm = new Vector3DCollection();
            foreach (var field in fields)
            {
                if (String.IsNullOrEmpty(field))
                    continue;
                var ff = field.Split('/');
                int vi = int.Parse(ff[0]);
                int vti = ff.Length > 1 && ff[1].Length > 0 ? int.Parse(ff[1]) : -1;
                int vni = ff.Length > 2 && ff[2].Length > 0 ? int.Parse(ff[2]) : -1;
                pts.Add(Points[vi - 1]);
                if (vti >= 0)
                    tex.Add(TexCoords[vti - 1]);
                if (vni >= 0)
                    norm.Add(Normals[vni - 1]);
            }
            if (tex.Count == 0) tex = null;
            if (norm.Count == 0) norm = null;

            // QUAD
            if (pts.Count == 4)
            {
                CurrentGroup.MeshBuilder.AddQuads(pts, norm, tex);
                return;
            }

            // TRIANGLE
            if (pts.Count == 3)
            {
                CurrentGroup.MeshBuilder.AddTriangles(pts, norm, tex);
                return;
            }

            // POLYGONS (flat and convex)
            var poly3D = new Polygon3D(pts);
            // Transform the polygon to 2D
            var poly2D = poly3D.Flatten();
            // Triangulate
            var tri = poly2D.Triangulate();
            if (tri != null)
            {
                // Add the triangle indices with the 3D points
                var mesh = new MeshBuilder();
                mesh.Append(pts, tri);
                CurrentGroup.MeshBuilder.Append(mesh);
            }
        }
    public static ModelVisual3D Representation3D(this XYPolygon Poly, IXYPoint refpoint, double height)
    {
      MeshBuilder mb = new MeshBuilder();
      var pts = new Point3DCollection();

      foreach (var p in Poly.Points)
      {
        pts.Add(new Point3D(refpoint.X - p.X, refpoint.Y - p.Y, height));
      }

      // POLYGONS (flat and convex)
      var poly3D = new Polygon3D(pts);
      // Transform the polygon to 2D
      var poly2D = poly3D.Flatten();
      // Triangulate
      var tri = poly2D.Triangulate();
      if (tri != null)
      {
        // Add the triangle indices with the 3D points
        mb.Append(pts, tri);
      }

      var m = MaterialHelper.CreateMaterial(Colors.DimGray, 0.5);

      var mv3D = new ModelVisual3D();
      mv3D.Content = new GeometryModel3D(mb.ToMesh(), m);
      return mv3D;

    }