diff --git a/graf/inc/LinkDef2.h b/graf/inc/LinkDef2.h
index 034502ea60e61480e7b6f57fd7d94486c1cccbea..e9b348828b3cf094e3d4322836786f55a798bc72 100644
--- a/graf/inc/LinkDef2.h
+++ b/graf/inc/LinkDef2.h
@@ -1,4 +1,4 @@
-/* @(#)root/graf:$Name:  $:$Id: LinkDef2.h,v 1.6 2003/10/28 17:43:07 brun Exp $ */
+/* @(#)root/graf:$Name:  $:$Id: LinkDef2.h,v 1.7 2003/11/20 16:57:46 brun Exp $ */
 
 /*************************************************************************
  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
@@ -15,6 +15,7 @@
 #pragma link off all functions;
 
 #pragma link C++ class TGraph2D-;
+#pragma link C++ class TGraph2DErrors-;
 #pragma link C++ class TGraphSmooth+;
 #pragma link C++ class TLatex+;
 #pragma link C++ class TLegend+;
diff --git a/graf/inc/TGraph2D.h b/graf/inc/TGraph2D.h
index b60e418bdada1bb1eb7a38101f8e9249eaae1fdd..8e3a867470896be8ad863493fbde6fc4dfcb6d29 100644
--- a/graf/inc/TGraph2D.h
+++ b/graf/inc/TGraph2D.h
@@ -34,6 +34,7 @@
 #include "TF2.h"
 #endif
 
+class TView;
 class TDirectory;
 
 class TGraph2D : public TNamed, public TAttLine, public TAttFill, public TAttMarker {
@@ -58,6 +59,7 @@ protected:
    Double_t    fXoffset;     //!
    Double_t    fYoffset;     //!Parameters used to normalize fX and fY
    Double_t    fScaleFactor; //!
+   Double_t   *fGridLevels;  //!Grid levels along Z axis
    Double_t    fMargin;      // Extra space (in %) around interpolated area for 2D histo
    Double_t    fMinimum;     // Minimum value for plotting along z
    Double_t    fMaximum;     // Maximum value for plotting along z
@@ -65,6 +67,7 @@ protected:
    Double_t   *fDist;        //!Array used to order mass points by distance
    Int_t       fMaxIter;     //!Maximum number of iterations to find Delaunay triangles
    Int_t       fTriedSize;   //!Real size of the fxTried arrays
+   Int_t       fNbLevels;    //|Number of Grid levels
    Int_t      *fPTried;      //!
    Int_t      *fNTried;      //!Delaunay triangles storage
    Int_t      *fMTried;      //!
@@ -73,19 +76,26 @@ protected:
    TList      *fFunctions;   // Pointer to list of functions (fits and user)
    TH2D       *fHistogram;   //!2D histogram of z values linearly interpolated
    TDirectory *fDirectory;   //!Pointer to directory holding this 2D graph
+   TView      *fView;        //!TView used to paint the triangles
    
    void     Build(Int_t n);
    Double_t ComputeZ(Double_t x, Double_t y);
+   void     DefineGridLevels();
    Bool_t   Enclose(Int_t T1, Int_t T2, Int_t T3, Int_t Ex) const;
    void     FileIt(Int_t P, Int_t N, Int_t M);
    void     FindAllTriangles();
    void     FindHull();
    Bool_t   InHull(Int_t E, Int_t X) const;
    Double_t InterpolateOnPlane(Int_t TI1, Int_t TI2, Int_t TI3, Int_t E) const;
+   void     PaintOneTriangle(Int_t *T,Double_t *x, Double_t *y);
    void     PaintTriangles(Option_t *option="");
    void     Reset(Int_t level=0);
 
 public:
+    // TGraph2D status bits
+   enum {
+      kFitInit = BIT(19)
+   };
 
    TGraph2D();
    TGraph2D(Int_t n, Option_t *option="");
@@ -113,6 +123,9 @@ public:
    Double_t         GetMarginBinsContent() const {return fZout;}
    TH2D            *GetHistogram(Option_t *option="") const;
    TList           *GetListOfFunctions() const { return fFunctions; }
+   virtual Double_t GetErrorX(Int_t bin) const;
+   virtual Double_t GetErrorY(Int_t bin) const;
+   virtual Double_t GetErrorZ(Int_t bin) const;
    Int_t            GetN() const {return fNpoints;}
    Double_t        *GetX() const {return fX;}
    Double_t        *GetY() const {return fY;}
diff --git a/graf/src/TGraph2D.cxx b/graf/src/TGraph2D.cxx
index 5b1aca43b2b071209d04d415ce35a204030de895..9252c9d7cd4d18da572f64345a50eda9c4b81409 100644
--- a/graf/src/TGraph2D.cxx
+++ b/graf/src/TGraph2D.cxx
@@ -18,6 +18,8 @@
 #include "TVirtualPad.h"
 #include "TVirtualFitter.h"
 #include "TView.h"
+#include "THLimitsFinder.h"
+#include "TStyle.h"
 
 ClassImp(TGraph2D)
 
@@ -68,6 +70,7 @@ ClassImp(TGraph2D)
 //            An hidden surface drawing technique is used
 //   "TRIW" : the Delaunay triangles are drawn as wire frame
 //   "P"    : draw a marker at each vertex
+//   "P0"   : draw a circle at each vertex. Each circle background is white.
 //
 // A TGraph2D can be also drawn with ANY options valid to draw a 2D histogram. 
 //
@@ -674,6 +677,37 @@ L90:
 }
 
 
+//______________________________________________________________________________
+void TGraph2D::DefineGridLevels()
+{
+   // Define the grid levels drawn on the triangles.
+   // The grid levels are aligned on the  Z axis' main tick marks.
+   // The function assumes that fView has been defined.
+
+   Int_t i, nbins;
+   Double_t BinLow, BinHigh, BinWidth;
+
+   // Find the main tick marks positions.
+   Double_t *rmin = fView->GetRmin();
+   Double_t *rmax = fView->GetRmax();
+   Int_t ndivz = fHistogram->GetZaxis()->GetNdivisions()%100;
+
+   if (ndivz > 0) {
+      THLimitsFinder::Optimize(rmin[2], rmax[2], ndivz,
+                               BinLow, BinHigh, nbins, BinWidth, " ");
+   } else {
+      nbins = TMath::Abs(ndivz);
+      BinLow = rmin[2];
+      BinHigh = rmax[2];
+      BinWidth = (BinHigh-BinLow)/nbins;
+   }
+   // Define the grid levels
+   fNbLevels = nbins+1;
+   fGridLevels = new Double_t[fNbLevels];
+   for (i = 0; i < fNbLevels; ++i) fGridLevels[i] = BinLow+i*BinWidth;
+}
+
+
 //______________________________________________________________________________
 Int_t TGraph2D::DistancetoPrimitive(Int_t px, Int_t py)
 {
@@ -1112,6 +1146,9 @@ void TGraph2D::Build(Int_t n)
    fPTried     = 0;
    fNTried     = 0;
    fMTried     = 0;
+   fGridLevels = 0;
+   fNbLevels   = 0;
+   fView       = 0;
 
    SetMaxIter();
 
@@ -1427,7 +1464,7 @@ Int_t TGraph2D::Fit(TF2 *f2, Option_t *option, Option_t *)
    }
 
 //*-*- Is a Fit range specified?
-///Int_t gxfirst, gxlast;
+   Int_t gxfirst, gxlast;
 ///if (fitOption.Range) {
 ///   f2->GetRange(xmin, ymin, xmax, ymax);
 ///   gxfirst = fNpoints +1;
@@ -1438,8 +1475,8 @@ Int_t TGraph2D::Fit(TF2 *f2, Option_t *option, Option_t *)
 ///   }
 ///} else {
 ///   f2->SetRange(xmin, ymin, xmax, ymax);
-///   gxfirst = 0;
-///   gxlast  = fNpoints-1;
+      gxfirst = 0;
+      gxlast  = fNpoints-1;
 ///}
 
    // Some initialisations
@@ -1451,7 +1488,7 @@ Int_t TGraph2D::Fit(TF2 *f2, Option_t *option, Option_t *)
    }
 
    // Set error criterion for chisquare
-   arglist[0] = TVirtualFitter::GetErrorDef();
+   arglist[0] = 1;
    if (!fitOption.User) grFitter->SetFitMethod("Graph2DFitChisquare");
    fitResult = grFitter->ExecuteCommand("SET ERR",arglist,1);
    if (fitResult != 0) {
@@ -1485,16 +1522,16 @@ Int_t TGraph2D::Fit(TF2 *f2, Option_t *option, Option_t *)
 
    // Compute sum of squares of errors in the bin range
    Bool_t hasErrors = kFALSE;
-   Double_t sumw2=0;
-///Double_t ex, ey, sumw2=0;
-///for (i=gxfirst;i<=gxlast;i++) {
-///   ex = GetErrorX(i);
-///   ey = GetErrorY(i);
-///   if (ex > 0 || ey > 0) hasErrors = kTRUE;
-///   sumw2 += ey*ey;
-///}
+   Double_t ex, ey, ez, sumw2=0;
+   for (i=gxfirst;i<=gxlast;i++) {
+      ex = GetErrorX(i);
+      ey = GetErrorY(i);
+      ez = GetErrorZ(i);
+      if (ex > 0 || ey > 0 || ez > 0) hasErrors = kTRUE;
+      sumw2 += ez*ez;
+   }
 //*-*- Perform minimization
-///if (!InheritsFrom("TGraphErrors")) SetBit(kFitInit);
+   if (!InheritsFrom("TGraph2DErrors")) SetBit(kFitInit);
    arglist[0] = TVirtualFitter::GetMaxIterations();
    arglist[1] = sumw2*TVirtualFitter::GetPrecision();
    grFitter->ExecuteCommand("MIGRAD",arglist,2);
@@ -1555,6 +1592,36 @@ Int_t TGraph2D::Fit(TF2 *f2, Option_t *option, Option_t *)
 }
 
 
+//______________________________________________________________________________
+Double_t TGraph2D::GetErrorX(Int_t) const
+{
+   // This function is called by Graph2DFitChisquare.
+   // It always returns a negative value. Real implementation in TGraph2DErrors
+
+   return -1;
+}
+
+
+//______________________________________________________________________________
+Double_t TGraph2D::GetErrorY(Int_t) const
+{
+   // This function is called by Graph2DFitChisquare.
+   // It always returns a negative value. Real implementation in TGraph2DErrors
+
+   return -1;
+}
+
+
+//______________________________________________________________________________
+Double_t TGraph2D::GetErrorZ(Int_t) const
+{
+   // This function is called by Graph2DFitChisquare.
+   // It always returns a negative value. Real implementation in TGraph2DErrors
+
+   return -1;
+}
+
+
 //______________________________________________________________________________
 TH2D *TGraph2D::GetHistogram(Option_t *option) const
 {
@@ -1756,6 +1823,59 @@ void TGraph2D::Paint(Option_t *option)
    }
 }
 
+//______________________________________________________________________________
+void TGraph2D::PaintOneTriangle(Int_t *T,Double_t *x, Double_t *y)
+{
+   // Paints one triangle
+
+   Int_t P0=T[0]-1;
+   Int_t P1=T[1]-1;
+   Int_t P2=T[2]-1;
+   Double_t xl[2],yl[2];
+   Double_t Zl, R21, R20, R10;
+   Double_t X0 = x[0]  , X2 = x[0];
+   Double_t Y0 = y[0]  , Y2 = y[0];
+   Double_t Z0 = fZ[P0], Z2 = fZ[P0];
+   Int_t I0=0;
+   Int_t I1=0;
+   Int_t I2=0;
+
+   if(fZ[P1]<Z0){Z0=fZ[P1];X0=x[1];Y0=y[1];I0=1;}
+   if(fZ[P2]<Z0){Z0=fZ[P2];X0=x[2];Y0=y[2];I0=2;}
+   if(fZ[P1]>Z2){Z2=fZ[P1];X2=x[1];Y2=y[1];I2=1;}
+   if(fZ[P2]>Z2){Z2=fZ[P2];X2=x[2];Y2=y[2];I2=2;}
+
+   I1 = 3-I2-I0;
+   Double_t X1 = x[I1];
+   Double_t Y1 = y[I1];
+   Double_t Z1 = fZ[T[I1]-1];
+
+   SetLineStyle(3);
+   TAttLine::Modify();
+
+   for(Int_t i=0; i<fNbLevels; i++){
+      Zl=fGridLevels[i];
+      if(Zl >= Z0 && Zl <=Z2) {
+         R21=(Zl-Z1)/(Z2-Z1);
+         R20=(Zl-Z0)/(Z2-Z0);
+         R10=(Zl-Z0)/(Z1-Z0);
+         xl[0]=R20*(X2-X0)+X0;
+         yl[0]=R20*(Y2-Y0)+Y0;
+         if(Zl >= Z1 && Zl <=Z2) {
+            xl[1]=R21*(X2-X1)+X1;
+            yl[1]=R21*(Y2-Y1)+Y1;
+         } else {
+            xl[1]=R10*(X1-X0)+X0;
+            yl[1]=R10*(Y1-Y0)+Y0;
+         }
+         gPad->PaintPolyLine(2,xl,yl);
+      }
+   }
+///Int_t ncolors  = gStyle->GetNumberOfColors();
+///color = Int_t(0.01+(z-zmin)*scale);
+   SetLineStyle(1);
+   TAttLine::Modify();
+}
 
 //______________________________________________________________________________
 void TGraph2D::PaintTriangles(Option_t *option)
@@ -1768,6 +1888,7 @@ void TGraph2D::PaintTriangles(Option_t *option)
    TString opt = option;
    Bool_t triangles = opt.Contains("tri"); 
    Bool_t markers   = opt.Contains("p");
+   Bool_t markers0  = opt.Contains("p0");
    Bool_t wire      = opt.Contains("w");
    Bool_t same      = opt.Contains("s");
    Bool_t backbox   = opt.Contains("bb");
@@ -1792,12 +1913,12 @@ void TGraph2D::PaintTriangles(Option_t *option)
       if (!axis) fHistogram->Paint("abb");
    }
 
-   TView *view = gPad->GetView();
-   if (!view) {
+   fView = gPad->GetView();
+   if (!fView) {
       Error("PaintTriangles", "No TView in current pad");
       return;
    }
-
+   DefineGridLevels();
    // Compute minimums and maximums
    TAxis *xaxis = fHistogram->GetXaxis();
    Int_t first = xaxis->GetFirst();
@@ -1817,8 +1938,8 @@ void TGraph2D::PaintTriangles(Option_t *option)
    // the triangles from back to front. 
    if (triangles) {
       FindAllTriangles();
-      Double_t cp = TMath::Cos(view->GetLongitude()*TMath::Pi()/180.);
-      Double_t sp = TMath::Sin(view->GetLongitude()*TMath::Pi()/180.);
+      Double_t cp = TMath::Cos(fView->GetLongitude()*TMath::Pi()/180.);
+      Double_t sp = TMath::Sin(fView->GetLongitude()*TMath::Pi()/180.);
       if (fOrder) {delete [] fOrder; fOrder = 0;}
       if (fDist)  {delete [] fDist; fDist = 0;}
       fOrder = new Int_t[fNdt];
@@ -1862,19 +1983,28 @@ void TGraph2D::PaintTriangles(Option_t *option)
          if (logx) temp1[0] = TMath::Log10(temp1[0]);
          if (logy) temp1[1] = TMath::Log10(temp1[1]);
          if (logz) temp1[2] = TMath::Log10(temp1[2]);
-         view->WCtoNDC(temp1, &temp2[0]);
+         fView->WCtoNDC(temp1, &temp2[0]);
          xm[IT] = temp2[0];
          ym[IT] = temp2[1];
       }
-      SetMarkerStyle(20);
-      SetMarkerSize(0.4);
-      SetMarkerColor(0);
-      TAttMarker::Modify();
-      gPad->PaintPolyMarker(fNpoints,xm,ym);
-      SetMarkerStyle(24);
-      SetMarkerColor(1);
-      TAttMarker::Modify();
-      gPad->PaintPolyMarker(fNpoints,xm,ym);
+      if (markers0) {
+         SetMarkerStyle(20);
+         SetMarkerSize(GetMarkerSize());
+         Int_t MC = GetMarkerColor();
+         SetMarkerColor(0);
+         TAttMarker::Modify();
+         gPad->PaintPolyMarker(fNpoints,xm,ym);
+         SetMarkerStyle(24);
+         SetMarkerColor(MC);
+         TAttMarker::Modify();
+         gPad->PaintPolyMarker(fNpoints,xm,ym);
+      } else {
+         SetMarkerStyle(GetMarkerStyle());
+         SetMarkerSize(GetMarkerSize());
+         SetMarkerColor(GetMarkerColor());
+         TAttMarker::Modify();
+         gPad->PaintPolyMarker(fNpoints,xm,ym);
+      }
       delete [] xm;
       delete [] ym;
 
@@ -1885,6 +2015,7 @@ void TGraph2D::PaintTriangles(Option_t *option)
       TAttFill::Modify();
       SetLineColor(GetLineColor());
       TAttLine::Modify();
+      Int_t LS = GetLineStyle();
       for (IT=0; IT<fNdt; IT++) {
          T[0] = fPTried[fOrder[IT]];
          T[1] = fNTried[fOrder[IT]];
@@ -1900,26 +2031,40 @@ void TGraph2D::PaintTriangles(Option_t *option)
             if (logx) temp1[0] = TMath::Log10(temp1[0]);
             if (logy) temp1[1] = TMath::Log10(temp1[1]);
             if (logz) temp1[2] = TMath::Log10(temp1[2]);
-            view->WCtoNDC(temp1, &temp2[0]);
+            fView->WCtoNDC(temp1, &temp2[0]);
             x[t] = temp2[0];
             y[t] = temp2[1];
          }
          x[3] = x[0];
          y[3] = y[0];
-         if (!wire) gPad->PaintFillArea(3,x,y);
+         if (!wire) {
+            gPad->PaintFillArea(3,x,y);
+            PaintOneTriangle(T,x,y);
+         }
          gPad->PaintPolyLine(4,x,y);
          if (markers) {
-            SetMarkerStyle(20);
-            SetMarkerSize(0.4);
-            SetMarkerColor(0);
-            TAttMarker::Modify();
-            gPad->PaintPolyMarker(3,x,y);
-            SetMarkerStyle(24);
-            SetMarkerColor(1);
-            TAttMarker::Modify();
-            gPad->PaintPolyMarker(3,x,y);
+            if (markers0) {
+               SetMarkerStyle(20);
+               SetMarkerSize(GetMarkerSize());
+               Int_t MC = GetMarkerColor();
+               SetMarkerColor(0);
+               TAttMarker::Modify();
+               gPad->PaintPolyMarker(3,x,y);
+               SetMarkerStyle(24);
+               SetMarkerColor(MC);
+               TAttMarker::Modify();
+               gPad->PaintPolyMarker(3,x,y);
+            } else {
+               SetMarkerStyle(GetMarkerStyle());
+               SetMarkerSize(GetMarkerSize());
+               SetMarkerColor(GetMarkerColor());
+               TAttMarker::Modify();
+               gPad->PaintPolyMarker(3,x,y);
+            }
          }
       }
+      SetLineStyle(LS);
+      TAttLine::Modify();
       delete [] fOrder; fOrder = 0;
       delete [] fDist; fDist = 0;
    }