Logo ROOT   6.12/07
Reference Guide
TGLH2PolyPainter.cxx
Go to the documentation of this file.
1 #include <algorithm>
2 #include <stdexcept>
3 #include <cassert>
4 
5 #include "TMultiGraph.h"
6 #include "TH2Poly.h"
7 #include "TGraph.h"
8 #include "TClass.h"
9 #include "TStyle.h"
10 #include "TError.h"
11 #include "TColor.h"
12 #include "TMath.h"
13 #include "TList.h"
14 #include "TROOT.h"
15 
16 #include "TGLH2PolyPainter.h"
17 #include "TGLPlotCamera.h"
18 #include "TGLIncludes.h"
19 
20 /** \class TGLH2PolyPainter
21 \ingroup opengl
22 Paint TH2Poly.
23 */
24 
26 
27 ////////////////////////////////////////////////////////////////////////////////
28 ///Ctor.
29 
31  : TGLPlotPainter(hist, camera, coord, kFALSE, kFALSE, kFALSE),
32  fZLog(kFALSE),
33  fZMin(0.)
34 {
35  if(!dynamic_cast<TH2Poly *>(hist)) {
36  Error("TGLH2PolyPainter::TGLH2PolyPainter", "bad histogram, must be a valid TH2Poly *");
37  throw std::runtime_error("bad TH2Poly");
38  }
39 }
40 
41 ////////////////////////////////////////////////////////////////////////////////
42 ///Show number of bin and bin contents, if bin is under the cursor.
43 
45 {
46  fBinInfo = "";
47  if (fSelectedPart) {
49  if (fHist->Class())
50  fBinInfo += fHist->Class()->GetName();
51  fBinInfo += "::";
52  fBinInfo += fHist->GetName();
53  } else if (!fHighColor) {
54  const Int_t binIndex = fSelectedPart - fSelectionBase + 1;
55  TH2Poly *h = static_cast<TH2Poly *>(fHist);
56  fBinInfo.Form("%s (bin = %d; binc = %f)", h->GetBinTitle(binIndex), binIndex, h->GetBinContent(binIndex));//+ 1: bins in ROOT start from 1.
57  } else
58  fBinInfo = "Switch to true-color mode to obtain the correct info";
59  }
60 
61  return (Char_t *)fBinInfo.Data();
62 }
63 
64 ////////////////////////////////////////////////////////////////////////////////
65 ///Tesselate polygons, if not done yet.
66 ///All pointers are validated here (and in functions called from here).
67 ///If any pointer is invalid - zero, or has unexpected type (dynamic_cast fails) -
68 ///InitGeometry will return false and nothing will be painted later.
69 ///That's why there are no checks in other functions.
70 
72 {
73  TH2Poly* hp = static_cast<TH2Poly *>(fHist);
74  if (!fCoord->SetRanges(hp))
75  return kFALSE;
76 
79  fCoord->GetZRangeScaled(), 1.);
80 
81  //This code is different from lego.
82  //Currently, negative bin contents are not supported.
83  fZMin = fBackBox.Get3DBox()[0].Z();
84 
85  if (hp->GetNewBinAdded()) {
86  if (!CacheGeometry())
87  return kFALSE;
90  } else if (hp->GetBinContentChanged() || fZLog != fCoord->GetZLog()) {
91  if (!UpdateGeometry())
92  return kFALSE;
94  }
95 
96  fZLog = fCoord->GetZLog();
97 
98  return kTRUE;
99 }
100 
101 ////////////////////////////////////////////////////////////////////////////////
102 ///User clicks on a lego with middle mouse button (middle for pad).
103 
105 {
106  fMousePosition.fX = px;
108  fCamera->StartPan(px, py);
109  fBoxCut.StartMovement(px, py);
110 }
111 
112 ////////////////////////////////////////////////////////////////////////////////
113 ///Mouse events handler.
114 
116 {
117  if (fSelectedPart >= fSelectionBase) {//Pan camera.
120 
121  fCamera->SetCamera();
123  fCamera->Pan(px, py);
124 
127  } else if (fSelectedPart > 0) {
128  //Convert py into bottom-top orientation.
129  py = fCamera->GetHeight() - py;
130 
133 
134  fCamera->SetCamera();
136 
137  if (!fHighColor) {
139  fBoxCut.MoveBox(px, py, fSelectedPart);
140  }
141  }
142 
145  }
146 
147  fMousePosition.fX = px, fMousePosition.fY = py;
149 }
150 
151 ////////////////////////////////////////////////////////////////////////////////
152 ///No additional options.
153 
154 void TGLH2PolyPainter::AddOption(const TString &/*stringOption*/)
155 {
156 }
157 
158 ////////////////////////////////////////////////////////////////////////////////
159 ///No events.
160 
161 void TGLH2PolyPainter::ProcessEvent(Int_t /*event*/, Int_t /*px*/, Int_t /*py*/)
162 {
163 }
164 
165 ////////////////////////////////////////////////////////////////////////////////
166 ///Initialize some gl state variables.
167 
169 {
170  glEnable(GL_DEPTH_TEST);
171  glEnable(GL_LIGHTING);
172  glEnable(GL_LIGHT0);
173 
174  glEnable(GL_CULL_FACE);
175  glCullFace(GL_BACK);
176 
177  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
178 }
179 
180 ////////////////////////////////////////////////////////////////////////////////
181 ///Return some gl states to original values.
182 
184 {
185  glDisable(GL_DEPTH_TEST);
186  glDisable(GL_LIGHTING);
187  glDisable(GL_LIGHT0);
188  glDisable(GL_CULL_FACE);
189  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
190 }
191 
192 namespace {
193 
194 Double_t Distance(const Double_t *p1, const Double_t *p2);
195 Bool_t IsPolygonCW(const Double_t *xs, const Double_t *ys, Int_t n);
196 
197 }
198 
199 ////////////////////////////////////////////////////////////////////////////////
200 ///Draw extruded polygons and plot's frame.
201 
203 {
204  //Shift plot to point of origin.
205  const Rgl::PlotTranslation trGuard(this);
206 
208 
209  DrawExtrusion();
210  DrawCaps();
211 }
212 
213 ////////////////////////////////////////////////////////////////////////////////
214 ///Extruded part of bins.
215 ///GL_QUADS, GL_QUAD_STRIP - have the same time on my laptop, so I use
216 ///GL_QUADS and forgot about vertex arrays (can require more memory BTW).
217 
219 {
220  TList *bins = static_cast<TH2Poly *>(fHist)->GetBins();
221  Int_t binIndex = 0;
222  for(TObjLink * link = bins->FirstLink(); link; link = link->Next(), ++binIndex) {
223  TH2PolyBin *bin = static_cast<TH2PolyBin *>(link->GetObject());
224  //const Double_t zMax = bin->GetContent() * fCoord->GetZScale();
225  Double_t zMax = bin->GetContent();
226  ClampZ(zMax);
227 
228  if (const TGraph * poly = dynamic_cast<TGraph*>(bin->GetPolygon())) {
229  //DrawExtrusion(poly, zMin, zMax, binIndex);
230  DrawExtrusion(poly, fZMin, zMax, binIndex);
231  } else if (const TMultiGraph * mg = dynamic_cast<TMultiGraph*>(bin->GetPolygon())) {
232  //DrawExtrusion(mg, zMin, zMax, binIndex);
233  DrawExtrusion(mg, fZMin, zMax, binIndex);
234  }//else is impossible.
235  }
236 }
237 
238 ////////////////////////////////////////////////////////////////////////////////
239 ///Extrude polygon, described by TGraph.
240 
241 void TGLH2PolyPainter::DrawExtrusion(const TGraph *poly, Double_t zMin, Double_t zMax, Int_t binIndex)const
242 {
243  const Double_t *xs = poly->GetX();
244  const Double_t *ys = poly->GetY();
245 
246  const Int_t nV = poly->GetN();
247 
248  //nV can never be less than 3 - InitGeometry fails on such polygons.
249  //So, no checks here.
250 
251  const Int_t binID = fSelectionBase + binIndex;
252 
253  if (fSelectionPass) {
254  if (!fHighColor)
256  } else {
257  SetBinColor(binIndex);
258  if(!fHighColor && fSelectedPart == binID)
259  glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gOrangeEmission);
260  }
261 
262  //Before, orientation was always done in TH2Poly.
263  //Now we do it every time here.
264  FillTemporaryPolygon(xs, ys, 0., nV); //0. == z is not important here.
265 
266  Double_t normal[3] = {};
267  for (Int_t j = 0; j < nV - 1; ++j) {
268  const Double_t v0[] = {fPolygon[j * 3], fPolygon[j * 3 + 1], zMin};
269  const Double_t v1[] = {fPolygon[(j + 1) * 3], fPolygon[(j + 1) * 3 + 1], zMin};
270 
271  if (Distance(v0, v1) < 1e-10)
272  continue;
273 
274  const Double_t v2[] = {v1[0], v1[1], zMax};
275  const Double_t v3[] = {v0[0], v0[1], zMax};
276 
277  TMath::Normal2Plane(v0, v1, v2, normal);
278  Rgl::DrawQuadFilled(v0, v1, v2, v3, normal);
279  }
280 
281  //Now, close the polygon.
282  const Double_t v0[] = {fPolygon[(nV - 1) * 3], fPolygon[(nV - 1) * 3 + 1], zMin};
283  const Double_t v1[] = {fPolygon[0], fPolygon[1], zMin};
284 
285  if (Distance(v0, v1) > 1e-10) {
286  const Double_t v2[] = {v1[0], v1[1], zMax};
287  const Double_t v3[] = {v0[0], v0[1], zMax};
288 
289  TMath::Normal2Plane(v0, v1, v2, normal);
290  Rgl::DrawQuadFilled(v0, v1, v2, v3, normal);
291  }
292 
293  if (!fHighColor && !fSelectionPass && fSelectedPart == binID)
294  glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gNullEmission);
295 }
296 
297 ////////////////////////////////////////////////////////////////////////////////
298 ///Multigraph contains a list of graphs, draw them.
299 
300 void TGLH2PolyPainter::DrawExtrusion(const TMultiGraph *mg, Double_t zMin, Double_t zMax, Int_t binIndex)const
301 {
302  const TList *graphs = mg->GetListOfGraphs();
303  for (TObjLink *link = graphs->FirstLink(); link; link = link->Next())
304  DrawExtrusion((TGraph *)(link->GetObject()), zMin, zMax, binIndex);
305 }
306 
307 ////////////////////////////////////////////////////////////////////////////////
308 ///Caps on bins.
309 
311 {
312  Int_t binIndex = 0;
313  const TList *bins = static_cast<TH2Poly *>(fHist)->GetBins();
314  CIter_t cap = fCaps.begin();
315 
316  assert(bins->FirstLink());
317 
318  //Very ugly iteration statement. Number of caps is equal to number of links (in a list
319  //of bins including nested links in multigraphs. But this is not obvious from the code here,
320  //so, I've added check cap != fCaps.end() to make it more or less clear.
321 
322  for (TObjLink *link = bins->FirstLink(); link && cap != fCaps.end(); link = link->Next()) {
323  TH2PolyBin *polyBin = static_cast<TH2PolyBin *>(link->GetObject());
324  if (dynamic_cast<TGraph *>(polyBin->GetPolygon())) {
325  DrawCap(cap, binIndex, false/*top cap*/);
326  DrawCap(cap, binIndex, true/*bottom cap*/);
327  ++cap;
328  } else if (TMultiGraph *mg = dynamic_cast<TMultiGraph *>(polyBin->GetPolygon())) {
329  const TList *gs = mg->GetListOfGraphs();
330  TObjLink *graphLink = gs->FirstLink();
331  for (; graphLink && cap != fCaps.end(); graphLink = graphLink->Next(), ++cap) {
332  DrawCap(cap, binIndex, false/*top cap*/);
333  DrawCap(cap, binIndex, true/*bottom cap*/);
334  }
335  }
336 
337  ++binIndex;
338  }
339 }
340 
341 ////////////////////////////////////////////////////////////////////////////////
342 ///Draw a cap on top of a bin.
343 
344 void TGLH2PolyPainter::DrawCap(CIter_t cap, Int_t binIndex, bool bottomCap)const
345 {
346  const Int_t binID = fSelectionBase + binIndex;
347  if (fSelectionPass) {
348  if (!fHighColor)
350  } else {
351  SetBinColor(binIndex);
352  if(!fHighColor && fSelectedPart == binID)
353  glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gOrangeEmission);
354  }
355 
356  glNormal3d(0., 0., bottomCap ? -1. : 1.);
357 
358  if (bottomCap)
359  glFrontFace(GL_CW);
360 
361  const Rgl::Pad::Tesselation_t &t = *cap;
362  typedef std::list<Rgl::Pad::MeshPatch_t>::const_iterator CMIter_t;
363  if (bottomCap) {
364  for (CMIter_t p = t.begin(); p != t.end(); ++p) {
365  const std::vector<Double_t> &vs = p->fPatch;
366  glBegin(GLenum(p->fPatchType));
367  for (UInt_t i = 0; i < vs.size(); i += 3)
368  glVertex3d(vs[i], vs[i + 1], fZMin);
369  glEnd();
370  }
371  } else {
372  for (CMIter_t p = t.begin(); p != t.end(); ++p) {
373  const std::vector<Double_t> &vs = p->fPatch;
374  glBegin(GLenum(p->fPatchType));
375  for (UInt_t i = 0; i < vs.size(); i += 3)
376  glVertex3dv(&vs[i]);
377  glEnd();
378  }
379  }
380 
381 
382  if (!fHighColor && !fSelectionPass && fSelectedPart == binID)
383  glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gNullEmission);
384 
385  if (bottomCap) // Restore the counter-clockwise orientation:
386  glFrontFace(GL_CCW);
387 }
388 
389 ////////////////////////////////////////////////////////////////////////////////
390 ///Cache all data for TH2Poly object.
391 
393 {
394  TH2Poly *hp = static_cast<TH2Poly *>(fHist);
395  TList *bins = hp->GetBins();
396  if (!bins || !bins->GetEntries()) {
397  Error("TGLH2PolyPainter::CacheGeometry", "Empty list of bins in TH2Poly");
398  return kFALSE;
399  }
400 
401  const Double_t zMin = fHist->GetMinimum();
402  const Double_t zMax = fHist->GetMaximum();
403  const Int_t nColors = gStyle->GetNumberOfColors();
404 
405  fBinColors.clear();
406  fBinColors.reserve(bins->GetEntries());
407  fPolygon.clear();
408  fCaps.clear();
409 
410  Rgl::Pad::Tesselator tesselator(kTRUE);
411 
412  for (TObjLink * link = bins->FirstLink(); link; link = link->Next()) {
413  TH2PolyBin * bin = static_cast<TH2PolyBin *>(link->GetObject());
414  if (!bin || !bin->GetPolygon()) {
415  Error("TGH2PolyPainter::InitGeometry", "Null bin or polygon pointer in a list of bins");
416  return kFALSE;
417  }
418 
419  Double_t binZ = bin->GetContent();
420  if (!ClampZ(binZ)) {
421  Error("TGLH2PolyPainter::CacheGeometry", "Negative bin content and log scale");
422  return kFALSE;
423  }
424 
425  if (const TGraph *g = dynamic_cast<TGraph *>(bin->GetPolygon())) {
426  if (!BuildTesselation(tesselator, g, binZ))
427  return kFALSE;
428  } else if (const TMultiGraph *mg = dynamic_cast<TMultiGraph *>(bin->GetPolygon())) {
429  if (!BuildTesselation(tesselator, mg, binZ))
430  return kFALSE;
431  } else {
432  Error("TGLH2PolyPainter::CacheGeometry", "Bin contains object of unknown type");
433  return kFALSE;
434  }
435 
436  const Int_t colorIndex = gStyle->GetColorPalette(Int_t(((bin->GetContent() - zMin) / (zMax - zMin)) * (nColors - 1)));
437  fBinColors.push_back(colorIndex);
438  }
439 
440  return kTRUE;
441 }
442 
443 ////////////////////////////////////////////////////////////////////////////////
444 ///Tesselate a polygon described by TGraph.
445 
447 {
448  const Double_t *xs = g->GetX();
449  const Double_t *ys = g->GetY();
450 
451  if (!xs || !ys) {
452  Error("TGLH2PolyPainter::BuildTesselation", "null array(s) in a polygon");
453  return kFALSE;
454  }
455 
456  const Int_t nV = g->GetN();
457  if (nV < 3) {
458  Error("TGLH2PolyPainter::BuildTesselation", "number of vertices in a polygon must be >= 3");
459  return kFALSE;
460  }
461 
462  fCaps.push_back(Rgl::Pad::Tesselation_t());
463  FillTemporaryPolygon(xs, ys, z, nV);
464 
465  tess.SetDump(&fCaps.back());
466 
467  GLUtesselator *t = (GLUtesselator *)tess.GetTess();
468  gluBeginPolygon(t);
469  gluNextContour(t, (GLenum)GLU_UNKNOWN);
470 
471  glNormal3d(0., 0., 1.);
472 
473  for (Int_t j = 0; j < nV; ++j) {
474  gluTessVertex(t, &fPolygon[j * 3], &fPolygon[j * 3]);
475  }
476  gluEndPolygon(t);
477 
478  return kTRUE;
479 }
480 
481 ////////////////////////////////////////////////////////////////////////////////
482 ///Iterate over multi graph contents and tesselate nested TGraphs.
483 
485 {
486  const TList *graphs = mg->GetListOfGraphs();
487  if (!graphs) {
488  Error("TGLH2PolyPainter::BuildTesselation", "null list of graphs in a multigraph");
489  return kFALSE;
490  }
491 
492  for(TObjLink *link = graphs->FirstLink(); link; link = link->Next()) {
493  const TGraph *graph = dynamic_cast<TGraph *>(link->GetObject());
494  if (!graph) {
495  Error("TGLH2PolyPainter::BuildTesselation", "TGraph expected inside a multigraph, got something else");
496  return kFALSE;
497  }
498 
499  if (!BuildTesselation(tess, graph, z))
500  return kFALSE;
501  }
502 
503  return kTRUE;
504 }
505 
506 ////////////////////////////////////////////////////////////////////////////////
507 ///Update cap's z-coordinates for all caps.
508 ///Here no pointers are checked, this was already done
509 ///by InitGeometry.
510 
512 {
513  TH2Poly *hp = static_cast<TH2Poly *>(fHist);
514  TList *bins = hp->GetBins();
515 
516  std::list<Rgl::Pad::Tesselation_t>::iterator cap = fCaps.begin();
517 
518  //Ugly iteration statements, but still, number of links and caps will be
519  //ok - this is checked in InitGeometry. Check cap != fCaps.end() is added
520  //to make it clear (not required).
521  for (TObjLink *link = bins->FirstLink(); link && cap != fCaps.end(); link = link->Next()) {
522  TH2PolyBin *b = static_cast<TH2PolyBin *>(link->GetObject());
523  Double_t z = b->GetContent();
524  ClampZ(z);
525  //Update z coordinate in all patches.
526  if (dynamic_cast<TGraph *>(b->GetPolygon())) {
527  //Only one cap.
528  Rgl::Pad::Tesselation_t &tess = *cap;
529  Rgl::Pad::Tesselation_t::iterator patch = tess.begin();
530  for (; patch != tess.end(); ++patch) {
531  std::vector<Double_t> &mesh = patch->fPatch;
532  for (UInt_t i = 0, e = mesh.size() / 3; i < e; ++i)
533  mesh[i * 3 + 2] = z;
534  }
535 
536  ++cap;
537  } else if (const TMultiGraph *mg = dynamic_cast<TMultiGraph *>(b->GetPolygon())) {
538  const TList *gs = mg->GetListOfGraphs();
539  for (TObjLink * graphLink = gs->FirstLink(); graphLink && cap != fCaps.end(); graphLink = graphLink->Next(), ++cap) {
540  Rgl::Pad::Tesselation_t &tess = *cap;
541  Rgl::Pad::Tesselation_t::iterator patch = tess.begin();
542  for (; patch != tess.end(); ++patch) {
543  std::vector<Double_t> &mesh = patch->fPatch;
544  for (UInt_t i = 0, e = mesh.size() / 3; i < e; ++i)
545  mesh[i * 3 + 2] = z;
546  }
547  }
548  }//else is impossible and processed by InitGeometry.
549  }
550 
551  return kTRUE;
552 }
553 
554 ////////////////////////////////////////////////////////////////////////////////
555 ///Set bin's color.
556 
558 {
559  if (binIndex >= Int_t(fBinColors.size())) {
560  Error("TGLH2PolyPainter::SetBinColor", "bin index is out of range %d, must be <= %d",
561  binIndex, int(fBinColors.size()));
562  return;
563  }
564 
565  //Convert color index into RGB.
566  Float_t diffColor[] = {0.8f, 0.8f, 0.8f, 0.15f};
567 
568  if (const TColor *c = gROOT->GetColor(fBinColors[binIndex]))
569  c->GetRGB(diffColor[0], diffColor[1], diffColor[2]);
570 
571  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffColor);
572  const Float_t specColor[] = {0.2f, 0.2f, 0.2f, 0.2f};
573  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor);
574  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.f);
575 }
576 
577 ////////////////////////////////////////////////////////////////////////////////
578 ///No sections.
579 
581 {
582 }
583 
584 ////////////////////////////////////////////////////////////////////////////////
585 ///No sections.
586 
588 {
589 }
590 
591 ////////////////////////////////////////////////////////////////////////////////
592 ///No sections.
593 
595 {
596 }
597 
598 ////////////////////////////////////////////////////////////////////////////////
599 ///Not yet.
600 
602 {
603 }
604 
605 ////////////////////////////////////////////////////////////////////////////////
606 ///Not yet.
607 
609 {
610 }
611 
612 ////////////////////////////////////////////////////////////////////////////////
613 ///Since I probably have to re-orient polygon, I need a temporary polygon.
614 
616 {
617  const Double_t xScale = fCoord->GetXScale();
618  const Double_t yScale = fCoord->GetYScale();
619 
620  fPolygon.resize(nV * 3);
621  for (Int_t j = 0; j < nV; ++j) {
622  fPolygon[j * 3] = xs[j] * xScale;
623  fPolygon[j * 3 + 1] = ys[j] * yScale;
624  fPolygon[j * 3 + 2] = z;
625  }
626 
627  if (IsPolygonCW(xs, ys, nV))
628  MakePolygonCCW();
629 }
630 
631 ////////////////////////////////////////////////////////////////////////////////
632 ///Code taken from the original TH2Poly.
633 
635 {
636  const Int_t nV = Int_t(fPolygon.size() / 3);
637  for (Int_t a = 0; a <= (nV / 2) - 1; a++) {
638  const Int_t b = nV - 1 - a;
639  std::swap(fPolygon[a * 3], fPolygon[b * 3]);
640  std::swap(fPolygon[a * 3 + 1], fPolygon[b * 3 + 1]);
641  }
642 }
643 
644 ////////////////////////////////////////////////////////////////////////////////
645 ///Clamp z value.
646 
648 {
649  if (fCoord->GetZLog()) {
650  if (zVal <= 0.)
651  return kFALSE;
652  else
653  zVal = TMath::Log10(zVal) * fCoord->GetZScale();
654  } else
655  zVal *= fCoord->GetZScale();
656 
657  const TGLVertex3 *frame = fBackBox.Get3DBox();
658 
659  if (zVal > frame[4].Z())
660  zVal = frame[4].Z();
661  else if (zVal < frame[0].Z())
662  zVal = frame[0].Z();
663 
664  return kTRUE;
665 }
666 
667 
668 namespace {
669 
670 ////////////////////////////////////////////////////////////////////////////////
671 ///
672 
673 Double_t Distance(const Double_t *p1, const Double_t *p2)
674 {
675  return TMath::Sqrt((p1[0] - p2[0]) * (p1[0] - p2[0]) +
676  (p1[1] - p2[1]) * (p1[1] - p2[1]) +
677  (p1[2] - p2[2]) * (p1[2] - p2[2]));
678 }
679 
680 ////////////////////////////////////////////////////////////////////////////////
681 ///Before, TH2Poly always produced good GL polygons - CCW. Now,
682 ///this code (by Deniz Gunceler) was deleted from TH2Poly.
683 
684 Bool_t IsPolygonCW(const Double_t *xs, const Double_t *ys, Int_t n)
685 {
686  Double_t signedArea = 0.;
687 
688  for (Int_t j = 0; j < n - 1; ++j)
689  signedArea += xs[j] * ys[j + 1] - ys[j] * xs[j + 1];
690 
691  return signedArea < 0.;
692 }
693 
694 }
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
void RestoreModelviewMatrix() const
virtual Double_t GetMaximum(Double_t maxval=FLT_MAX) const
Return maximum value smaller than maxval of bins in the range, unless the value has been overridden b...
Definition: TH1.cxx:7807
Camera for TGLPlotPainter and sub-classes.
Definition: TGLPlotCamera.h:21
void DrawQuadFilled(const TGLVertex3 &v0, const TGLVertex3 &v1, const TGLVertex3 &v2, const TGLVertex3 &v3, const TGLVector3 &normal)
Draw quad face.
Definition: TGLUtil.cxx:2920
void MoveBox(Int_t px, Int_t py, Int_t axisID)
Move box cut along selected direction.
char * GetPlotInfo(Int_t px, Int_t py)
Show number of bin and bin contents, if bin is under the cursor.
const Float_t gNullEmission[]
Definition: TGLUtil.cxx:2814
float Float_t
Definition: RtypesCore.h:53
Bool_t GetZLog() const
Get Z log.
void DrawPaletteAxis() const
Not yet.
void swap(TDirectoryEntry &e1, TDirectoryEntry &e2) noexcept
void DrawPlot() const
Draw extruded polygons and plot&#39;s frame.
R__EXTERN TStyle * gStyle
Definition: TStyle.h:402
TH1 * h
Definition: legend2.C:5
std::vector< Int_t > fBinColors
void StartPan(Int_t px, Int_t py)
User clicks somewhere (px, py).
virtual Int_t GetEntries() const
Definition: TCollection.h:177
A TMultiGraph is a collection of TGraph (or derived) objects.
Definition: TMultiGraph.h:35
const TGLVertex3 * Get3DBox() const
Get 3D box.
Definition: TGLPlotBox.cxx:303
Bool_t ClampZ(Double_t &zVal) const
Clamp z value.
SCoord_t fX
Definition: TPoint.h:35
#define gROOT
Definition: TROOT.h:402
SCoord_t fY
Definition: TPoint.h:36
Basic string class.
Definition: TString.h:125
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
void SetBinContentChanged(Bool_t flag)
Definition: TH2Poly.h:123
void * GetTess() const
Definition: TGLPadUtils.h:180
Helper class to represent a bin in the TH2Poly histogram.
Definition: TH2Poly.h:25
TGLH2PolyPainter(TH1 *hist, TGLPlotCamera *camera, TGLPlotCoordinates *coord)
Ctor.
static constexpr double mg
void MakePolygonCCW() const
Code taken from the original TH2Poly.
T * Normal2Plane(const T v1[3], const T v2[3], const T v3[3], T normal[3])
Definition: TMath.h:1180
Bool_t CacheGeometry()
Cache all data for TH2Poly object.
const Double_t gH2PolyScaleXY
void Apply(Double_t phi, Double_t theta) const
Applies rotations and translations before drawing.
const char * GetBinTitle(Int_t bin) const
Returns the bin title.
Definition: TH2Poly.cxx:801
3 component (x/y/z) vertex class.
Definition: TGLUtil.h:82
Bool_t IsActive() const
void DrawSectionXOZ() const
No sections.
Double_t Log10(Double_t x)
Definition: TMath.h:651
static double p2(double t, double a, double b, double c)
void SetCamera() const
Viewport and projection.
TGLPlotBox fBackBox
std::list< Rgl::Pad::Tesselation_t >::const_iterator CIter_t
void DrawCaps() const
Caps on bins.
Paint TH2Poly.
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition: TStyle.cxx:735
void DrawSectionXOY() const
No sections.
static void SetDump(Tesselation_t *t)
Definition: TGLPadUtils.h:185
void Error(const char *location, const char *msgfmt,...)
void DeInitGL() const
Return some gl states to original values.
virtual Double_t GetBinContent(Int_t bin) const
Returns the content of the input bin For the overflow/underflow/sea bins: -1 | -2 | -3 ---+----+---- ...
Definition: TH2Poly.cxx:762
A doubly linked list.
Definition: TList.h:44
void DrawCap(CIter_t cap, Int_t bin, bool bottomCap) const
Draw a cap on top of a bin.
std::list< MeshPatch_t > Tesselation_t
Definition: TGLPadUtils.h:170
TObject * GetPolygon() const
Definition: TH2Poly.h:38
Double_t fPadTheta
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
Definition: TGLUtil.cxx:2858
const Rgl::Range_t & GetZRangeScaled() const
Scaled range.
TGLPlotCamera * fCamera
void RestoreProjectionMatrix() const
Bool_t UpdateGeometry()
Update cap&#39;s z-coordinates for all caps.
void StartPan(Int_t px, Int_t py)
User clicks on a lego with middle mouse button (middle for pad).
TList * GetBins()
Definition: TH2Poly.h:94
auto * a
Definition: textangle.C:12
Double_t GetContent() const
Definition: TH2Poly.h:35
void AddOption(const TString &stringOption)
No additional options.
Bool_t BuildTesselation(Rgl::Pad::Tesselator &tess, const TGraph *g, Double_t z)
Tesselate a polygon described by TGraph.
Helper class for plot-painters holding information about axis ranges, numbers of bins and flags if ce...
void Pan(Int_t px, Int_t py)
Pan camera.
void FillTemporaryPolygon(const Double_t *xs, const Double_t *ys, Double_t z, Int_t n) const
Since I probably have to re-orient polygon, I need a temporary polygon.
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2343
unsigned int UInt_t
Definition: RtypesCore.h:42
Int_t GetN() const
Definition: TGraph.h:122
static double p1(double t, double a, double b)
void Pan(Int_t px, Int_t py)
Mouse events handler.
Base class for plot-painters that provide GL rendering of various 2D and 3D histograms, functions and parametric surfaces.
Definition: graph.py:1
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition: TStyle.cxx:801
std::vector< Double_t > fZLevels
virtual TObjLink * FirstLink() const
Definition: TList.h:108
virtual Double_t GetMinimum(Double_t minval=-FLT_MAX) const
Return minimum value larger than minval of bins in the range, unless the value has been overridden by...
Definition: TH1.cxx:7892
const Bool_t kFALSE
Definition: RtypesCore.h:88
void DrawBox(Int_t selectedPart, Bool_t selectionPass, const std::vector< Double_t > &zLevels, Bool_t highColor) const
Draw back box for a plot.
Definition: TGLPlotBox.cxx:184
Double_t * GetX() const
Definition: TGraph.h:129
Double_t Z() const
Definition: TGLUtil.h:122
Double_t GetYScale() const
std::vector< Double_t > fPolygon
#define ClassImp(name)
Definition: Rtypes.h:359
Bool_t GetNewBinAdded() const
Definition: TH2Poly.h:109
double Double_t
Definition: RtypesCore.h:55
Bool_t InitGeometry()
Tesselate polygons, if not done yet.
void SaveProjectionMatrix() const
The TH1 histogram class.
Definition: TH1.h:56
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
The color creation and management class.
Definition: TColor.h:19
Bool_t SetRanges(const TH1 *hist, Bool_t errors=kFALSE, Bool_t zBins=kFALSE)
Set bin ranges, ranges.
const Rgl::Range_t & GetYRangeScaled() const
Scaled range.
void DrawSectionYOZ() const
No sections.
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
char Char_t
Definition: RtypesCore.h:29
void SetBinColor(Int_t bin) const
Set bin&#39;s color.
void InitGL() const
Initialize some gl state variables.
TList * GetListOfGraphs() const
Definition: TMultiGraph.h:69
Double_t * GetY() const
Definition: TGraph.h:130
void ProcessEvent(Int_t event, Int_t px, Int_t py)
No events.
Bool_t GetBinContentChanged() const
Definition: TH2Poly.h:98
void StartMovement(Int_t px, Int_t py)
Start cut&#39;s movement.
void SetPlotBox(const Rgl::Range_t &xRange, const Rgl::Range_t &yRange, const Rgl::Range_t &zRange)
Set up a frame box.
Definition: TGLPlotBox.cxx:198
A Graph is a graphics object made of two arrays X and Y with npoints each.
Definition: TGraph.h:41
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
const Rgl::Range_t & GetXRangeScaled() const
Scaled range.
AxisAngle::Scalar Distance(const AxisAngle &r1, const R &r2)
Distance between two rotations.
Definition: AxisAngle.h:326
void DrawExtrusion() const
Extruded part of bins.
def normal(shape, name=None)
std::list< Rgl::Pad::Tesselation_t > fCaps
Double_t Sqrt(Double_t x)
Definition: TMath.h:590
Bool_t fUpdateSelection
Int_t GetHeight() const
viewport[3]
void SaveModelviewMatrix() const
TGLPlotCoordinates * fCoord
const Bool_t kTRUE
Definition: RtypesCore.h:87
const Float_t gOrangeEmission[]
Definition: TGLUtil.cxx:2811
TGLBoxCut fBoxCut
void DrawPalette() const
Not yet.
const Int_t n
Definition: legend1.C:16
Double_t GetZScale() const
Double_t GetXScale() const
2D Histogram with Polygonal Bins
Definition: TH2Poly.h:66
void SetNewBinAdded(Bool_t flag)
Definition: TH2Poly.h:125
const char * Data() const
Definition: TString.h:345
static constexpr double g