TGLH2PolyPainter.cxx

Go to the documentation of this file.
00001 #include <algorithm>
00002 #include <stdexcept>
00003 
00004 #include "TMultiGraph.h"
00005 #include "TH2Poly.h"
00006 #include "TGraph.h"
00007 #include "TClass.h"
00008 #include "TStyle.h"
00009 #include "TError.h"
00010 #include "TColor.h"
00011 #include "TMath.h"
00012 #include "TList.h"
00013 #include "TROOT.h"
00014 
00015 #include "TGLH2PolyPainter.h"
00016 #include "TGLPlotCamera.h"
00017 #include "TGLIncludes.h"
00018 
00019 
00020 ClassImp(TGLH2PolyPainter)
00021 
00022 //______________________________________________________________________________
00023 TGLH2PolyPainter::TGLH2PolyPainter(TH1 *hist, TGLPlotCamera *camera, TGLPlotCoordinates *coord)
00024                    : TGLPlotPainter(hist, camera, coord, kFALSE, kFALSE, kFALSE),
00025                      fZLog(kFALSE),
00026                      fZMin(0.)
00027 {
00028    //Ctor.
00029    if(!dynamic_cast<TH2Poly *>(hist)) {
00030       Error("TGLH2PolyPainter::TGLH2PolyPainter", "bad histogram, must be a valid TH2Poly *");
00031       throw std::runtime_error("bad TH2Poly");
00032    }
00033 }
00034 
00035 //______________________________________________________________________________
00036 char *TGLH2PolyPainter::GetPlotInfo(Int_t /*px*/, Int_t /*py*/)
00037 {
00038    //Show number of bin and bin contents, if bin is under the cursor.
00039    fBinInfo = "";
00040    if (fSelectedPart) {
00041       if (fSelectedPart < fSelectionBase) {
00042          if (fHist->Class())
00043             fBinInfo += fHist->Class()->GetName();
00044          fBinInfo += "::";
00045          fBinInfo += fHist->GetName();
00046       } else if (!fHighColor) {
00047          const Int_t binIndex = fSelectedPart - fSelectionBase + 1;
00048          TH2Poly *h = static_cast<TH2Poly *>(fHist);
00049          fBinInfo.Form("%s (bin = %d; binc = %f)", h->GetBinTitle(binIndex), binIndex, h->GetBinContent(binIndex));//+ 1: bins in ROOT start from 1.
00050       } else
00051          fBinInfo = "Switch to true-color mode to obtain the correct info";
00052    }
00053 
00054    return (Char_t *)fBinInfo.Data();
00055 }
00056 
00057 //______________________________________________________________________________
00058 Bool_t TGLH2PolyPainter::InitGeometry()
00059 {
00060    //Tesselate polygons, if not done yet.
00061    //All pointers are validated here (and in functions called from here).
00062    //If any pointer is invalid - zero, or has unexpected type (dynamic_cast fails) -
00063    //InitGeometry will return false and nothing will be painted later.
00064    //That's why there are no checks in other functions.
00065    TH2Poly* hp = static_cast<TH2Poly *>(fHist);
00066    if (!fCoord->SetRanges(hp))
00067       return kFALSE;
00068 
00069    fBackBox.SetPlotBox(fCoord->GetXRangeScaled(), Rgl::gH2PolyScaleXY,
00070                        fCoord->GetYRangeScaled(), Rgl::gH2PolyScaleXY,
00071                        fCoord->GetZRangeScaled(), 1.);
00072 
00073    //This code is different from lego.
00074    //Currently, negative bin contents are not supported.
00075    fZMin = fBackBox.Get3DBox()[0].Z();
00076 
00077    if (hp->GetNewBinAdded()) {
00078       if (!CacheGeometry())
00079          return kFALSE;
00080       hp->SetNewBinAdded(kFALSE);
00081       hp->SetBinContentChanged(kFALSE);
00082    } else if (hp->GetBinContentChanged() || fZLog != fCoord->GetZLog()) {
00083       if (!UpdateGeometry())
00084          return kFALSE;
00085       hp->SetBinContentChanged(kFALSE);
00086    }
00087 
00088    fZLog = fCoord->GetZLog();
00089 
00090    return kTRUE;
00091 }
00092 
00093 //______________________________________________________________________________
00094 void TGLH2PolyPainter::StartPan(Int_t px, Int_t py)
00095 {
00096    //User clicks on a lego with middle mouse button (middle for pad).
00097    fMousePosition.fX = px;
00098    fMousePosition.fY = fCamera->GetHeight() - py;
00099    fCamera->StartPan(px, py);
00100    fBoxCut.StartMovement(px, py);
00101 }
00102 
00103 //______________________________________________________________________________
00104 void TGLH2PolyPainter::Pan(Int_t px, Int_t py)
00105 {
00106       //Mouse events handler.
00107    if (fSelectedPart >= fSelectionBase) {//Pan camera.
00108       SaveModelviewMatrix();
00109       SaveProjectionMatrix();
00110 
00111       fCamera->SetCamera();
00112       fCamera->Apply(fPadPhi, fPadTheta);
00113       fCamera->Pan(px, py);
00114 
00115       RestoreProjectionMatrix();
00116       RestoreModelviewMatrix();
00117    } else if (fSelectedPart > 0) {
00118       //Convert py into bottom-top orientation.
00119       py = fCamera->GetHeight() - py;
00120 
00121       SaveModelviewMatrix();
00122       SaveProjectionMatrix();
00123 
00124       fCamera->SetCamera();
00125       fCamera->Apply(fPadPhi, fPadTheta);
00126 
00127       if (!fHighColor) {
00128          if (fBoxCut.IsActive() && (fSelectedPart >= kXAxis && fSelectedPart <= kZAxis)) {
00129             fBoxCut.MoveBox(px, py, fSelectedPart);
00130          }
00131       }
00132 
00133       RestoreProjectionMatrix();
00134       RestoreModelviewMatrix();
00135    }
00136 
00137    fMousePosition.fX = px, fMousePosition.fY = py;
00138    fUpdateSelection = kTRUE;
00139 }
00140 
00141 //______________________________________________________________________________
00142 void TGLH2PolyPainter::AddOption(const TString &/*stringOption*/)
00143 {
00144    //No additional options.
00145 }
00146 
00147 //______________________________________________________________________________
00148 void TGLH2PolyPainter::ProcessEvent(Int_t /*event*/, Int_t /*px*/, Int_t /*py*/)
00149 {
00150    //No events.
00151 }
00152 
00153 //______________________________________________________________________________
00154 void TGLH2PolyPainter::InitGL()const
00155 {
00156    //Initialize some gl state variables.
00157    glEnable(GL_DEPTH_TEST);
00158    glEnable(GL_LIGHTING);
00159    glEnable(GL_LIGHT0);
00160 
00161    glEnable(GL_CULL_FACE);
00162    glCullFace(GL_BACK);
00163 
00164    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
00165 }
00166 
00167 //______________________________________________________________________________
00168 void TGLH2PolyPainter::DeInitGL()const
00169 {
00170    //Return some gl states to original values.
00171    glDisable(GL_DEPTH_TEST);
00172    glDisable(GL_LIGHTING);
00173    glDisable(GL_LIGHT0);
00174    glDisable(GL_CULL_FACE);
00175    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
00176 }
00177 
00178 namespace {
00179 
00180 Double_t Distance(const Double_t *p1, const Double_t *p2);
00181 Bool_t   IsPolygonCW(const Double_t *xs, const Double_t *ys, Int_t n);
00182 
00183 }
00184 
00185 //______________________________________________________________________________
00186 void TGLH2PolyPainter::DrawPlot()const
00187 {
00188    //Draw extruded polygons and plot's frame.
00189 
00190    //Shift plot to point of origin.
00191    const Rgl::PlotTranslation trGuard(this);
00192 
00193    fBackBox.DrawBox(fSelectedPart, fSelectionPass, fZLevels, fHighColor);
00194 
00195    DrawExtrusion();
00196    DrawCaps();
00197 }
00198 
00199 //______________________________________________________________________________
00200 void TGLH2PolyPainter::DrawExtrusion()const
00201 {
00202    //Extruded part of bins.
00203    //GL_QUADS, GL_QUAD_STRIP - have the same time on my laptop, so I use
00204    //GL_QUADS and forgot about vertex arrays (can require more memory BTW).
00205    TList *bins = static_cast<TH2Poly *>(fHist)->GetBins();
00206    Int_t binIndex = 0;
00207    for(TObjLink * link = bins->FirstLink(); link; link = link->Next(), ++binIndex) {
00208       TH2PolyBin *bin = static_cast<TH2PolyBin *>(link->GetObject());
00209       //const Double_t zMax = bin->GetContent() * fCoord->GetZScale();
00210       Double_t zMax = bin->GetContent();
00211       ClampZ(zMax);
00212 
00213       if (const TGraph * poly = dynamic_cast<TGraph*>(bin->GetPolygon())) {
00214          //DrawExtrusion(poly, zMin, zMax, binIndex);
00215          DrawExtrusion(poly, fZMin, zMax, binIndex);
00216       } else if (const TMultiGraph * mg = dynamic_cast<TMultiGraph*>(bin->GetPolygon())) {
00217          //DrawExtrusion(mg, zMin, zMax, binIndex);
00218          DrawExtrusion(mg, fZMin, zMax, binIndex);
00219       }//else is impossible.
00220    }
00221 }
00222 
00223 //______________________________________________________________________________
00224 void TGLH2PolyPainter::DrawExtrusion(const TGraph *poly, Double_t zMin, Double_t zMax, Int_t binIndex)const
00225 {
00226    //Extrude polygon, described by TGraph.
00227    const Double_t *xs = poly->GetX();
00228    const Double_t *ys = poly->GetY();
00229        
00230    const Int_t nV = poly->GetN();
00231 
00232    //nV can never be less than 3 - InitGeometry fails on such polygons.
00233    //So, no checks here.
00234 
00235    const Int_t binID = fSelectionBase + binIndex;
00236 
00237    if (fSelectionPass) {
00238       if (!fHighColor)
00239          Rgl::ObjectIDToColor(binID, kFALSE);
00240    } else {
00241       SetBinColor(binIndex);
00242       if(!fHighColor && fSelectedPart == binID)
00243          glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gOrangeEmission);
00244    }
00245 
00246    //Before, orientation was always done in TH2Poly.
00247    //Now we do it every time here.
00248    FillTemporaryPolygon(xs, ys, 0., nV); //0. == z is not important here.
00249 
00250    Double_t normal[3] = {};
00251    for (Int_t j = 0; j < nV - 1; ++j) {
00252       const Double_t v0[] = {fPolygon[j * 3], fPolygon[j * 3 + 1], zMin};
00253       const Double_t v1[] = {fPolygon[(j + 1) * 3], fPolygon[(j + 1) * 3 + 1], zMin};
00254 
00255       if (Distance(v0, v1) < 1e-10)
00256          continue;
00257 
00258       const Double_t v2[] = {v1[0], v1[1], zMax};
00259       const Double_t v3[] = {v0[0], v0[1], zMax};
00260 
00261       TMath::Normal2Plane(v0, v1, v2, normal);
00262       Rgl::DrawQuadFilled(v0, v1, v2, v3, normal);
00263    }
00264 
00265    //Now, close the polygon.
00266    const Double_t v0[] = {fPolygon[(nV - 1) * 3], fPolygon[(nV - 1) * 3 + 1], zMin};
00267    const Double_t v1[] = {fPolygon[0], fPolygon[1], zMin};
00268 
00269    if (Distance(v0, v1) > 1e-10) {
00270       const Double_t v2[] = {v1[0], v1[1], zMax};
00271       const Double_t v3[] = {v0[0], v0[1], zMax};
00272 
00273       TMath::Normal2Plane(v0, v1, v2, normal);
00274       Rgl::DrawQuadFilled(v0, v1, v2, v3, normal);
00275    }
00276 
00277    if (!fHighColor && !fSelectionPass && fSelectedPart == binID)
00278       glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gNullEmission);
00279 }
00280 
00281 //______________________________________________________________________________
00282 void TGLH2PolyPainter::DrawExtrusion(const TMultiGraph *mg, Double_t zMin, Double_t zMax, Int_t binIndex)const
00283 {
00284    //Multigraph contains a list of graphs, draw them.
00285    const TList *graphs = mg->GetListOfGraphs();
00286    for (TObjLink *link = graphs->FirstLink(); link; link = link->Next())
00287       DrawExtrusion((TGraph *)(link->GetObject()), zMin, zMax, binIndex);
00288 }
00289 
00290 //______________________________________________________________________________
00291 void TGLH2PolyPainter::DrawCaps()const
00292 {
00293    //Caps on bins.
00294    glNormal3d(0., 0., 1.);
00295 
00296    Int_t binIndex = 0;
00297    const TList *bins = static_cast<TH2Poly *>(fHist)->GetBins();
00298    CIter_t cap = fCaps.begin();
00299 
00300    if(!bins->FirstLink())
00301       throw 1;
00302 
00303    //Very ugly iteration statement. Number of caps is equal to number of links (in a list
00304    //of bins including nested links in multigraphs. But this is not obvious from the code here,
00305    //so, I've added check cap != fCaps.end() to make it more or less clear.
00306    for (TObjLink *link = bins->FirstLink(); link && cap != fCaps.end(); link = link->Next()) {
00307       TH2PolyBin *polyBin = static_cast<TH2PolyBin *>(link->GetObject());
00308       if (dynamic_cast<TGraph *>(polyBin->GetPolygon())) {
00309          DrawCap(cap, binIndex);
00310          ++cap;
00311       } else if (TMultiGraph *mg = dynamic_cast<TMultiGraph *>(polyBin->GetPolygon())) {
00312          const TList *gs = mg->GetListOfGraphs();
00313          TObjLink *graphLink = gs->FirstLink();
00314          for (; graphLink && cap != fCaps.end(); graphLink = graphLink->Next(), ++cap)
00315             DrawCap(cap, binIndex);
00316       }
00317 
00318       ++binIndex;
00319    }
00320 }
00321 
00322 //______________________________________________________________________________
00323 void TGLH2PolyPainter::DrawCap(CIter_t cap, Int_t binIndex)const
00324 {
00325    //Draw a cap on top of a bin.
00326    const Int_t binID = fSelectionBase + binIndex;
00327    if (fSelectionPass) {
00328       if (!fHighColor)
00329          Rgl::ObjectIDToColor(binID, kFALSE);
00330    } else {
00331       SetBinColor(binIndex);
00332       if(!fHighColor && fSelectedPart == binID)
00333          glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gOrangeEmission);
00334    }
00335 
00336    const Rgl::Pad::Tesselation_t &t = *cap;
00337    typedef std::list<Rgl::Pad::MeshPatch_t>::const_iterator CMIter_t;
00338    for (CMIter_t p = t.begin(); p != t.end(); ++p) {
00339       const std::vector<Double_t> &vs = p->fPatch;
00340       glBegin(GLenum(p->fPatchType));
00341       for (UInt_t i = 0; i < vs.size(); i += 3)
00342          glVertex3dv(&vs[i]);
00343       glEnd();
00344    }
00345 
00346    if (!fHighColor && !fSelectionPass && fSelectedPart == binID)
00347       glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gNullEmission);
00348 }
00349 
00350 //______________________________________________________________________________
00351 Bool_t TGLH2PolyPainter::CacheGeometry()
00352 {
00353    //Cache all data for TH2Poly object.
00354    TH2Poly *hp = static_cast<TH2Poly *>(fHist);
00355    TList *bins = hp->GetBins();
00356    if (!bins || !bins->GetEntries()) {
00357       Error("TGLH2PolyPainter::CacheGeometry", "Empty list of bins in TH2Poly");
00358       return kFALSE;
00359    }
00360 
00361    const Double_t zMin = fHist->GetMinimum();
00362    const Double_t zMax = fHist->GetMaximum();
00363    const Int_t nColors = gStyle->GetNumberOfColors();
00364 
00365    fBinColors.clear();
00366    fBinColors.reserve(bins->GetEntries());
00367    fPolygon.clear();
00368    fCaps.clear();
00369 
00370    Rgl::Pad::Tesselator tesselator(kTRUE);
00371 
00372    for (TObjLink * link = bins->FirstLink(); link; link = link->Next()) {
00373       TH2PolyBin * bin = static_cast<TH2PolyBin *>(link->GetObject());
00374       if (!bin || !bin->GetPolygon()) {
00375          Error("TGH2PolyPainter::InitGeometry", "Null bin or polygon pointer in a list of bins");
00376          return kFALSE;
00377       }
00378 
00379       Double_t binZ = bin->GetContent();
00380       if (!ClampZ(binZ)) {
00381          Error("TGLH2PolyPainter::CacheGeometry", "Negative bin content and log scale");
00382          return kFALSE;
00383       }
00384 
00385       if (const TGraph *g = dynamic_cast<TGraph *>(bin->GetPolygon())) {
00386          if (!BuildTesselation(tesselator, g,  binZ))
00387             return kFALSE;
00388       } else if (const TMultiGraph *mg = dynamic_cast<TMultiGraph *>(bin->GetPolygon())) {
00389          if (!BuildTesselation(tesselator, mg, binZ))
00390             return kFALSE;
00391       } else {
00392          //Da vy chto, sgovorilis' chto li???
00393          Error("TGLH2PolyPainter::CacheGeometry", "Bin contains object of unknown type");
00394          return kFALSE;
00395       }
00396 
00397       const Int_t colorIndex = gStyle->GetColorPalette(Int_t(((bin->GetContent() - zMin) / (zMax - zMin)) * (nColors - 1)));
00398       fBinColors.push_back(colorIndex);
00399    }
00400 
00401    return kTRUE;
00402 }
00403 
00404 //______________________________________________________________________________
00405 Bool_t TGLH2PolyPainter::BuildTesselation(Rgl::Pad::Tesselator &tess, const TGraph *g, Double_t z)
00406 {
00407    //Tesselate a polygon described by TGraph.
00408    const Double_t *xs = g->GetX();
00409    const Double_t *ys = g->GetY();
00410 
00411    if (!xs || !ys) {
00412       Error("TGLH2PolyPainter::BuildTesselation", "null array(s) in a polygon");
00413       return kFALSE;
00414    }
00415 
00416    const Int_t nV = g->GetN();
00417    if (nV < 3) {
00418       Error("TGLH2PolyPainter::BuildTesselation", "number of vertices in a polygon must be >= 3");
00419       return kFALSE;
00420    }
00421 
00422    fCaps.push_back(Rgl::Pad::Tesselation_t());
00423    FillTemporaryPolygon(xs, ys, z, nV);
00424 
00425    tess.SetDump(&fCaps.back());
00426 
00427    GLUtesselator *t = (GLUtesselator *)tess.GetTess();
00428    gluBeginPolygon(t);
00429    gluNextContour(t, (GLenum)GLU_UNKNOWN);
00430 
00431    glNormal3d(0., 0., 1.);
00432 
00433    for (Int_t j = 0; j < nV; ++j) {
00434       gluTessVertex(t, &fPolygon[j * 3], &fPolygon[j * 3]);
00435    }
00436    gluEndPolygon(t);
00437 
00438    return kTRUE;
00439 }
00440 
00441 //______________________________________________________________________________
00442 Bool_t TGLH2PolyPainter::BuildTesselation(Rgl::Pad::Tesselator &tess, const TMultiGraph *mg, Double_t z)
00443 {
00444    //Iterate over multi graph contents and tesselate nested TGraphs.
00445    const TList *graphs = mg->GetListOfGraphs();
00446    if (!graphs) {
00447       Error("TGLH2PolyPainter::BuildTesselation", "null list of graphs in a multigraph");
00448       return kFALSE;
00449    }
00450 
00451    for(TObjLink *link = graphs->FirstLink(); link; link = link->Next()) {
00452       const TGraph *graph = dynamic_cast<TGraph *>(link->GetObject());
00453       if (!graph) {
00454          //Da chto za fignia v konce koncov????
00455          Error("TGLH2PolyPainter::BuildTesselation", "TGraph expected inside a multigraph, got something else");
00456          return kFALSE;
00457       }
00458 
00459       if (!BuildTesselation(tess, graph, z))
00460          return kFALSE;
00461    }
00462 
00463    return kTRUE;
00464 }
00465 
00466 //______________________________________________________________________________
00467 Bool_t TGLH2PolyPainter::UpdateGeometry()
00468 {
00469    //Update cap's z-coordinates for all caps.
00470    //Here no pointers are checked, this was already done
00471    //by InitGeometry. So, if histogram was broken somehow
00472    //- hehe, good luck.
00473    TH2Poly *hp = static_cast<TH2Poly *>(fHist);
00474    TList *bins = hp->GetBins();
00475 
00476    std::list<Rgl::Pad::Tesselation_t>::iterator cap = fCaps.begin();
00477 
00478    //Ugly iteration statements, but still, number of links and caps will be
00479    //ok - this is checked in InitGeometry. Check cap != fCaps.end() is added
00480    //to make it clear (not required).
00481    for (TObjLink *link = bins->FirstLink(); link && cap != fCaps.end(); link = link->Next()) {
00482       TH2PolyBin *b = static_cast<TH2PolyBin *>(link->GetObject());
00483       Double_t z = b->GetContent();
00484       ClampZ(z);
00485       //Update z coordinate in all patches.
00486       if (dynamic_cast<TGraph *>(b->GetPolygon())) {
00487          //Only one cap.
00488          Rgl::Pad::Tesselation_t &tess = *cap;
00489          Rgl::Pad::Tesselation_t::iterator patch = tess.begin();
00490          for (; patch != tess.end(); ++patch) {
00491             std::vector<Double_t> &mesh = patch->fPatch;
00492             for (UInt_t i = 0, e = mesh.size() / 3; i < e; ++i)
00493                mesh[i * 3 + 2] = z;
00494          }
00495 
00496          ++cap;
00497       } else if (const TMultiGraph *mg = dynamic_cast<TMultiGraph *>(b->GetPolygon())) {
00498          const TList *gs = mg->GetListOfGraphs();
00499          for (TObjLink * graphLink = gs->FirstLink(); graphLink && cap != fCaps.end(); graphLink = graphLink->Next(), ++cap) {
00500             Rgl::Pad::Tesselation_t &tess = *cap;
00501             Rgl::Pad::Tesselation_t::iterator patch = tess.begin();
00502             for (; patch != tess.end(); ++patch) {
00503                std::vector<Double_t> &mesh = patch->fPatch;
00504                for (UInt_t i = 0, e = mesh.size() / 3; i < e; ++i)
00505                   mesh[i * 3 + 2] = z;
00506             }
00507          }
00508       }//else is impossible and processed by InitGeometry.
00509    }
00510 
00511    return kTRUE;
00512 }
00513 
00514 //______________________________________________________________________________
00515 void TGLH2PolyPainter::SetBinColor(Int_t binIndex)const
00516 {
00517    //Set bin's color.
00518    if (binIndex >= Int_t(fBinColors.size())) {
00519       Error("TGLH2PolyPainter::SetBinColor", "bin index is out of range %d, must be <= %d",
00520             binIndex, int(fBinColors.size()));
00521       return;
00522    }
00523 
00524    //Convert color index into RGB.
00525    Float_t diffColor[] = {0.8f, 0.8f, 0.8f, 0.15f};
00526 
00527    if (const TColor *c = gROOT->GetColor(fBinColors[binIndex]))
00528       c->GetRGB(diffColor[0], diffColor[1], diffColor[2]);
00529 
00530    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffColor);
00531    const Float_t specColor[] = {1.f, 1.f, 1.f, 1.f};
00532    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor);
00533    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.f);
00534 }
00535 
00536 //______________________________________________________________________________
00537 void TGLH2PolyPainter::DrawSectionXOZ()const
00538 {
00539    //No sections.
00540 }
00541 
00542 //______________________________________________________________________________
00543 void TGLH2PolyPainter::DrawSectionYOZ()const
00544 {
00545    //No sections.
00546 }
00547 
00548 //______________________________________________________________________________
00549 void TGLH2PolyPainter::DrawSectionXOY()const
00550 {
00551    //No sections.
00552 }
00553 
00554 //______________________________________________________________________________
00555 void TGLH2PolyPainter::DrawPalette()const
00556 {
00557    //Not yet.
00558 }
00559 
00560 //______________________________________________________________________________
00561 void TGLH2PolyPainter::DrawPaletteAxis()const
00562 {
00563    //Not yet.
00564 }
00565 
00566 //______________________________________________________________________________
00567 void TGLH2PolyPainter::FillTemporaryPolygon(const Double_t *xs, const Double_t *ys, Double_t z, Int_t nV)const
00568 {
00569    //Since I probably have to re-orient polygon, I need a temporary polygon.
00570    const Double_t xScale = fCoord->GetXScale();
00571    const Double_t yScale = fCoord->GetYScale();
00572   
00573    fPolygon.resize(nV * 3);
00574    for (Int_t j = 0; j < nV; ++j) {
00575       fPolygon[j * 3]     = xs[j] * xScale;
00576       fPolygon[j * 3 + 1] = ys[j] * yScale;
00577       fPolygon[j * 3 + 2] = z;
00578    }
00579 
00580    if (IsPolygonCW(xs, ys, nV))
00581       MakePolygonCCW();
00582 }
00583 
00584 //______________________________________________________________________________
00585 void TGLH2PolyPainter::MakePolygonCCW()const
00586 {
00587    //Code taken from the original TH2Poly. 
00588    const Int_t nV = Int_t(fPolygon.size() / 3);
00589    for (Int_t a = 0; a <= (nV / 2) - 1; a++) {
00590       const Int_t b = nV - 1 - a;
00591       std::swap(fPolygon[a * 3], fPolygon[b * 3]);
00592       std::swap(fPolygon[a * 3 + 1], fPolygon[b * 3 + 1]);
00593    }
00594 }
00595 
00596 //______________________________________________________________________________
00597 Bool_t TGLH2PolyPainter::ClampZ(Double_t &zVal)const
00598 {
00599    //Clamp z value.
00600    if (fCoord->GetZLog()) {
00601       if (zVal <= 0.)
00602          return kFALSE;
00603       else
00604          zVal = TMath::Log10(zVal) * fCoord->GetZScale();
00605    } else
00606       zVal *= fCoord->GetZScale();
00607 
00608    const TGLVertex3 *frame = fBackBox.Get3DBox();
00609 
00610    if (zVal > frame[4].Z())
00611       zVal = frame[4].Z();
00612    else if (zVal < frame[0].Z())
00613       zVal = frame[0].Z();
00614 
00615    return kTRUE;
00616 }
00617 
00618 
00619 namespace {
00620 
00621 //______________________________________________________________________________
00622 Double_t Distance(const Double_t *p1, const Double_t *p2)
00623 {
00624    //
00625    return TMath::Sqrt((p1[0] - p2[0]) * (p1[0] - p2[0]) +
00626                       (p1[1] - p2[1]) * (p1[1] - p2[1]) +
00627                       (p1[2] - p2[2]) * (p1[2] - p2[2]));
00628 }
00629 
00630 //______________________________________________________________________________
00631 Bool_t IsPolygonCW(const Double_t *xs, const Double_t *ys, Int_t n)
00632 {
00633    //Before, TH2Poly always produced good GL polygons - CCW. Now,
00634    //this code (by Deniz Gunceler) was deleted from TH2Poly.
00635    Double_t signedArea = 0.;
00636 
00637    for (Int_t j = 0; j < n - 1; ++j)
00638       signedArea += xs[j] * ys[j + 1] - ys[j] * xs[j + 1];
00639 
00640    return signedArea < 0.;         
00641 }
00642 
00643 }

Generated on Tue Jul 5 14:18:07 2011 for ROOT_528-00b_version by  doxygen 1.5.1