private void AddMeshZ(Graphics g, DataSeries ds, ChartStyle cs,
            Axes ax, ViewAngle va, ChartLabels cl)
        {
            Pen aPen = new Pen(ds.LineStyle.LineColor, ds.LineStyle.Thickness);
            aPen.DashStyle = ds.LineStyle.Pattern;
            SolidBrush aBrush = new SolidBrush(Color.White);
            Matrix3 m = Matrix3.AzimuthElevation(va.Elevation, va.Azimuth);
            PointF[] pta = new PointF[4];
            Point3[,] pts = ds.PointArray;
            Point3[,] pts1 = new Point3[pts.GetLength(0), pts.GetLength(1)];
            Color color;

            // Find the minumum and maximum z values:
            float zmin = ds.ZDataMin();
            float zmax = ds.ZDataMax();

            for (int i = 0; i < pts.GetLength(0); i++)
            {
                for (int j = 0; j < pts.GetLength(1); j++)
                {
                    // Make a deep copy the points array:
                    pts1[i, j] = new Point3(pts[i, j].X, pts[i, j].Y, pts[i, j].Z, 1);
                    // Perform transformations on points:
                    pts[i, j].Transform(m, chart3d, ax, cs, cl);
                }
            }

            for (int i = 0; i < pts.GetLength(0) - 1; i++)
            {
                for (int j = 0; j < pts.GetLength(1) - 1; j++)
                {
                    int ii = i;
                    if (va.Azimuth >= -180 && va.Azimuth < 0)
                    {
                        ii = pts.GetLength(0) - 2 - i;
                    }
                    pta[0] = new PointF(pts[ii, j].X, pts[ii, j].Y);
                    pta[1] = new PointF(pts[ii, j + 1].X, pts[ii, j + 1].Y);
                    pta[2] = new PointF(pts[ii + 1, j + 1].X, pts[ii + 1, j + 1].Y);
                    pta[3] = new PointF(pts[ii + 1, j].X, pts[ii + 1, j].Y);
                    g.FillPolygon(aBrush, pta);
                    if (IsColorMap)
                    {
                        color = AddColor(cs, pts[ii, j], zmin, zmax, ax, va, cl);
                        aPen = new Pen(color, ds.LineStyle.Thickness);
                        aPen.DashStyle = ds.LineStyle.Pattern;
                    }
                    g.DrawPolygon(aPen, pta);
                }
            }

            Point3[] pt3 = new Point3[4];
            for (int i = 0; i < pts1.GetLength(0); i++)
            {
                int jj = pts1.GetLength(0) - 1;
                if (va.Elevation >= 0)
                {
                    if (va.Azimuth >= -90 && va.Azimuth <= 90)
                        jj = 0;
                }
                else if (va.Elevation < 0)
                {
                    jj = 0;
                    if (va.Azimuth >= -90 && va.Azimuth <= 90)
                        jj = pts1.GetLength(0) - 1;
                }

                if (i < pts1.GetLength(0) - 1)
                {
                    pt3[0] = new Point3(pts1[i, jj].X, pts1[i, jj].Y, pts1[i, jj].Z, 1);
                    pt3[1] = new Point3(pts1[i + 1, jj].X, pts1[i + 1, jj].Y, pts1[i + 1, jj].Z, 1);
                    pt3[2] = new Point3(pts1[i + 1, jj].X, pts1[i + 1, jj].Y, ax.ZMin, 1);
                    pt3[3] = new Point3(pts1[i, jj].X, pts1[i, jj].Y, ax.ZMin, 1);
                    for (int k = 0; k < 4; k++)
                        pt3[k].Transform(m, chart3d, ax, cs, cl);
                    pta[0] = new PointF(pt3[0].X, pt3[0].Y);
                    pta[1] = new PointF(pt3[1].X, pt3[1].Y);
                    pta[2] = new PointF(pt3[2].X, pt3[2].Y);
                    pta[3] = new PointF(pt3[3].X, pt3[3].Y);
                    g.FillPolygon(aBrush, pta);
                    if (IsColorMap)
                    {
                        color = AddColor(cs, pt3[0], zmin, zmax, ax, va, cl);
                        aPen = new Pen(color, ds.LineStyle.Thickness);
                        aPen.DashStyle = ds.LineStyle.Pattern;
                    }
                    g.DrawPolygon(aPen, pta);
                }
            }
            for (int j = 0; j < pts1.GetLength(1); j++)
            {
                int ii = 0;
                if (va.Elevation >= 0)
                {
                    if (va.Azimuth >= 0 && va.Azimuth <= 180)
                        ii = pts1.GetLength(1) - 1;
                }
                else if (va.Elevation < 0)
                {
                    if (va.Azimuth >= -180 && va.Azimuth <= 0)
                        ii = pts1.GetLength(1) - 1;
                }
                if (j < pts1.GetLength(1) - 1)
                {
                    pt3[0] = new Point3(pts1[ii, j].X, pts1[ii, j].Y, pts1[ii, j].Z, 1);
                    pt3[1] = new Point3(pts1[ii, j + 1].X, pts1[ii, j + 1].Y, pts1[ii, j + 1].Z, 1);
                    pt3[2] = new Point3(pts1[ii, j + 1].X, pts1[ii, j + 1].Y, ax.ZMin, 1);
                    pt3[3] = new Point3(pts1[ii, j].X, pts1[ii, j].Y, ax.ZMin, 1);
                    for (int k = 0; k < 4; k++)
                        pt3[k].Transform(m, chart3d, ax, cs, cl);
                    pta[0] = new PointF(pt3[0].X, pt3[0].Y);
                    pta[1] = new PointF(pt3[1].X, pt3[1].Y);
                    pta[2] = new PointF(pt3[2].X, pt3[2].Y);
                    pta[3] = new PointF(pt3[3].X, pt3[3].Y);
                    g.FillPolygon(aBrush, pta);
                    if (IsColorMap)
                    {
                        color = AddColor(cs, pt3[0], zmin, zmax, ax, va, cl);
                        aPen = new Pen(color, ds.LineStyle.Thickness);
                        aPen.DashStyle = ds.LineStyle.Pattern;
                    }
                    g.DrawPolygon(aPen, pta);
                }
            }
            aPen.Dispose();
            aBrush.Dispose();
        }
        private void AddXYColor3D(Graphics g, DataSeries ds, ChartStyle cs,
            ChartStyle2D cs2d, Axes ax, ViewAngle va, ChartLabels cl)
        {
            Pen aPen = new Pen(ds.LineStyle.LineColor, ds.LineStyle.Thickness);
            aPen.DashStyle = ds.LineStyle.Pattern;
            SolidBrush aBrush = new SolidBrush(Color.White);
            PointF[] pta = new PointF[4];
            Point3[,] pts = ds.PointArray;
            Point3[,] pts1 = new Point3[pts.GetLength(0), pts.GetLength(1)];
            Point3[,] pts2 = new Point3[pts.GetLength(0), pts.GetLength(1)];
            Matrix3 m = Matrix3.AzimuthElevation(va.Elevation, va.Azimuth);

            // Find the minumum and maximum z values:
            float zmin = ds.ZDataMin();
            float zmax = ds.ZDataMax();

            // Perform transformation on points:
            for (int i = 0; i < pts.GetLength(0); i++)
            {
                for (int j = 0; j < pts.GetLength(1); j++)
                {
                    // Make a deep copy the points array:
                    pts1[i, j] = new Point3(pts[i, j].X, pts[i, j].Y, ax.ZMin, 1);
                    pts2[i, j] = new Point3(pts[i, j].X, pts[i, j].Y, ax.ZMin, 1);
                    pts1[i, j].Transform(m, chart3d, ax, cs, cl);
                }
            }

            // Draw surface on the XY plane:
            if (!IsInterp)
            {
                for (int i = 0; i < pts.GetLength(0) - 1; i++)
                {
                    for (int j = 0; j < pts.GetLength(1) - 1; j++)
                    {
                        pta[0] = new PointF(pts1[i, j].X, pts1[i, j].Y);
                        pta[1] = new PointF(pts1[i, j + 1].X, pts1[i, j + 1].Y);
                        pta[2] = new PointF(pts1[i + 1, j + 1].X, pts1[i + 1, j + 1].Y);
                        pta[3] = new PointF(pts1[i + 1, j].X, pts1[i + 1, j].Y);
                        Color color = AddColor(cs, pts[i, j], zmin, zmax, ax, va, cl);
                        aBrush = new SolidBrush(color);
                        g.FillPolygon(aBrush, pta);
                        if (ds.LineStyle.IsVisible)
                        {
                            //g.DrawPolygon(aPen, pta);
                        }
                    }
                }
            }

            // Draw refined surface:
            else if (IsInterp)
            {
                for (int i = 0; i < pts1.GetLength(0) - 1; i++)
                {
                    for (int j = 0; j < pts1.GetLength(1) - 1; j++)
                    {
                        Point3[] points = new Point3[4];
                        points[0] = pts[i, j];
                        points[1] = pts[i, j + 1];
                        points[2] = pts[i + 1, j + 1];
                        points[3] = pts[i + 1, j];
                        Interp(g, cs, cs2d, m, points, zmin, zmax, 3, ax, va, cl);
                    }
                }
            }
        }