Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
TGLTF3Painter.cxx
Go to the documentation of this file.
1// @(#)root/gl:$Id$
2// Author: Timur Pocheptsov 31/08/2006
3
4/*************************************************************************
5 * Copyright (C) 1995-2006, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include <typeinfo>
13
14#include "KeySymbols.h"
15#include "TVirtualX.h"
16#include "Buttons.h"
17#include "TString.h"
18#include "TROOT.h"
19#include "TColor.h"
20#include "TMath.h"
21#include "TH3.h"
22#include "TF3.h"
23
24#include "TGLMarchingCubes.h"
25#include "TGLPlotCamera.h"
26#include "TGLTF3Painter.h"
27#include "TGLIncludes.h"
28
29/** \class TGLTF3Painter
30\ingroup opengl
31Plot-painter for TF3 functions.
32*/
33
34
35////////////////////////////////////////////////////////////////////////////////
36/// Constructor.
37
39 : TGLPlotPainter(hist, camera, coord, kFALSE, kFALSE, kFALSE),
41 fF3(fun),
42 fXOZSlice("XOZ", (TH3 *)hist, fun, coord, &fBackBox, TGLTH3Slice::kXOZ),
43 fYOZSlice("YOZ", (TH3 *)hist, fun, coord, &fBackBox, TGLTH3Slice::kYOZ),
44 fXOYSlice("XOY", (TH3 *)hist, fun, coord, &fBackBox, TGLTH3Slice::kXOY)
45{
46}
47
48////////////////////////////////////////////////////////////////////////////////
49///Coords for point on surface under cursor.
50
52{
53 static char mess[] = { "fun3" };
54 return mess;
55}
56
57////////////////////////////////////////////////////////////////////////////////
58///Create mesh.
59
61{
62 fCoord->SetCoordType(kGLCartesian);
63
64 if (!fCoord->SetRanges(fHist, kFALSE, kTRUE))
65 return kFALSE;
66
67 fBackBox.SetPlotBox(fCoord->GetXRangeScaled(), fCoord->GetYRangeScaled(), fCoord->GetZRangeScaled());
68 if (fCamera) fCamera->SetViewVolume(fBackBox.Get3DBox());
69
70 //Build mesh for TF3 surface
71 fMesh.ClearMesh();
72
73 Rgl::Mc::TMeshBuilder<TF3, Double_t> builder(kFALSE);//no averaged normals.
74 //Set grid parameters.
76 fCoord->GetYScale(), fCoord->GetZScale(),
78
79 builder.BuildMesh(fF3, geom, &fMesh, 0.);
80
81 if (fCoord->Modified()) {
83 const TGLVertex3 &vertex = fBackBox.Get3DBox()[0];
84 fXOZSectionPos = vertex.Y();
85 fYOZSectionPos = vertex.X();
86 fXOYSectionPos = vertex.Z();
87 fCoord->ResetModified();
88 }
89
90 return kTRUE;
91}
92
93////////////////////////////////////////////////////////////////////////////////
94///User clicks right mouse button (in a pad).
95
97{
98 fMousePosition.fX = px;
99 fMousePosition.fY = fCamera->GetHeight() - py;
100 fCamera->StartPan(px, py);
101 fBoxCut.StartMovement(px, fCamera->GetHeight() - py);
102}
103
104////////////////////////////////////////////////////////////////////////////////
105///User's moving mouse cursor, with middle mouse button pressed (for pad).
106///Calculate 3d shift related to 2d mouse movement.
107///Slicing is disabled (since somebody has broken it).
108
110{
111 if (fSelectedPart >= fSelectionBase) {//Pan camera.
114
115 fCamera->SetCamera();
116 fCamera->Apply(fPadPhi, fPadTheta);
117 fCamera->Pan(px, py);
118
121 } else if (fSelectedPart > 0) {
122 //Convert py into bottom-top orientation.
123 //Possibly, move box here
124 py = fCamera->GetHeight() - py;
125
128
129 fCamera->SetCamera();
130 fCamera->Apply(fPadPhi, fPadTheta);
131
132 if (!fHighColor) {
133 if (fBoxCut.IsActive() && (fSelectedPart >= kXAxis && fSelectedPart <= kZAxis)) {
134 fBoxCut.MoveBox(px, py, fSelectedPart);
135 } else {
136 //MoveSection(px, py);
137 }
138 } else {
139 //MoveSection(px, py);
140 }
141
144 }
145
146 fMousePosition.fX = px, fMousePosition.fY = py;
148}
149
150////////////////////////////////////////////////////////////////////////////////
151///No options for tf3
152
153void TGLTF3Painter::AddOption(const TString &/*option*/)
154{
155}
156
157////////////////////////////////////////////////////////////////////////////////
158///Change color scheme.
159
161{
162 if (event == kKeyPress) {
163 if (py == kKey_s || py == kKey_S) {
165 } else if (py == kKey_c || py == kKey_C) {
166 if (fHighColor)
167 Info("ProcessEvent", "Cut box does not work in high color, please, switch to true color");
168 else {
169 fBoxCut.TurnOnOff();
171 }
172 }
173 } else if (event == kButton1Double && (fBoxCut.IsActive() || HasSections())) {
174 if (fBoxCut.IsActive())
175 fBoxCut.TurnOnOff();
176 const TGLVertex3 *frame = fBackBox.Get3DBox();
177 fXOZSectionPos = frame[0].Y();
178 fYOZSectionPos = frame[0].X();
179 fXOYSectionPos = frame[0].Z();
180
181 if (!gVirtualX->IsCmdThread())
182 gROOT->ProcessLineFast(Form("((TGLPlotPainter *)0x%zx)->Paint()", (size_t)this));
183 else
184 Paint();
185 }
186}
187
188////////////////////////////////////////////////////////////////////////////////
189///Initialize OpenGL state variables.
190
192{
193 glEnable(GL_LIGHTING);
194 glEnable(GL_LIGHT0);
195 glEnable(GL_DEPTH_TEST);
196 glDisable(GL_CULL_FACE);
197 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
198}
199
200////////////////////////////////////////////////////////////////////////////////
201///Initialize OpenGL state variables.
202
204{
205 glDisable(GL_LIGHTING);
206 glDisable(GL_LIGHT0);
207 glDisable(GL_DEPTH_TEST);
208 glDisable(GL_CULL_FACE);
209 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
210}
211
212////////////////////////////////////////////////////////////////////////////////
213///Draw triangles, no normals, no lighting.
214
216{
218
219 if (!fBoxCut.IsActive())
220 Rgl::DrawMesh(fMesh.fVerts, fMesh.fTris);
221 else
222 Rgl::DrawMesh(fMesh.fVerts, fMesh.fTris, fBoxCut);
223}
224
225////////////////////////////////////////////////////////////////////////////////
226///Surface with material properties and lighting.
227
229{
230 if (HasSections()) {
231 glEnable(GL_BLEND);
232 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
233 glDepthMask(GL_FALSE);
234 }
235
237
238 if (!fBoxCut.IsActive()) {
239 Rgl::DrawMesh(fMesh.fVerts, fMesh.fNorms, fMesh.fTris);
240 } else {
241 Rgl::DrawMesh(fMesh.fVerts, fMesh.fNorms, fMesh.fTris, fBoxCut);
242 }
243
244 if (HasSections()) {
245 glDisable(GL_BLEND);
246 glDepthMask(GL_TRUE);
247 }
248}
249
250////////////////////////////////////////////////////////////////////////////////
251///Colored surface, without lighting and
252///material properties.
253
255{
256 const TGLDisableGuard lightGuard(GL_LIGHTING);
257
258 if (HasSections() && fStyle < kMaple2) {
259 glEnable(GL_BLEND);
260 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
261 glDepthMask(GL_FALSE);
262 }
263
264 if (fStyle == kMaple1) {//Shaded polygons and outlines.
265 glEnable(GL_POLYGON_OFFSET_FILL);//[1
266 glPolygonOffset(1.f, 1.f);
267 } else if (fStyle == kMaple2)//Colored outlines only.
268 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//[2
269
270 if(!fBoxCut.IsActive())
271 Rgl::DrawMapleMesh(fMesh.fVerts, fMesh.fNorms, fMesh.fTris);
272 else
273 Rgl::DrawMapleMesh(fMesh.fVerts, fMesh.fNorms, fMesh.fTris, fBoxCut);
274
275 if (fStyle == kMaple1) {
276 //Draw outlines.
277 glDisable(GL_POLYGON_OFFSET_FILL);//1]
278 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//[3
279 glColor4d(0., 0., 0., 0.25);
280
281 if(!fBoxCut.IsActive())
282 Rgl::DrawMesh(fMesh.fVerts, fMesh.fTris);
283 else
284 Rgl::DrawMesh(fMesh.fVerts, fMesh.fTris, fBoxCut);
285
286 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);//[3
287 } else if (fStyle == kMaple2)
288 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
289
290 if (HasSections() && fStyle < kMaple2) {
291 glDisable(GL_BLEND);
292 glDepthMask(GL_TRUE);
293 }
294}
295
296////////////////////////////////////////////////////////////////////////////////
297///Draw mesh.
298
300{
301 //Shift plot to point of origin.
302 const Rgl::PlotTranslation trGuard(this);
303
305 DrawSections();
306
307 if (fSelectionPass) {
309 } else if (fStyle == kDefault) {
311 } else {
313 }
314
315 if (fBoxCut.IsActive())
317}
318
319////////////////////////////////////////////////////////////////////////////////
320///Set color for surface.
321
323{
324 Float_t diffColor[] = {0.8f, 0.8f, 0.8f, 0.15f};
325
326 if (fF3->GetFillColor() != kWhite)
327 if (const TColor *c = gROOT->GetColor(fF3->GetFillColor()))
328 c->GetRGB(diffColor[0], diffColor[1], diffColor[2]);
329
330 glMaterialfv(GL_BACK, GL_DIFFUSE, diffColor);
331 diffColor[0] /= 2, diffColor[1] /= 2, diffColor[2] /= 2;
332 glMaterialfv(GL_FRONT, GL_DIFFUSE, diffColor);
333 const Float_t specColor[] = {1.f, 1.f, 1.f, 1.f};
334 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor);
335 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.f);
336}
337
338////////////////////////////////////////////////////////////////////////////////
339///Any section exists.
340
342{
343 return fXOZSectionPos > fBackBox.Get3DBox()[0].Y() ||
344 fYOZSectionPos > fBackBox.Get3DBox()[0].X() ||
345 fXOYSectionPos > fBackBox.Get3DBox()[0].Z();
346}
347
348////////////////////////////////////////////////////////////////////////////////
349/// Draw XOZ parallel section.
350
352{
353 if (fSelectionPass)
354 return;
355 fXOZSlice.DrawSlice(fXOZSectionPos / fCoord->GetYScale());
356}
357
358////////////////////////////////////////////////////////////////////////////////
359/// Draw YOZ parallel section.
360
362{
363 if (fSelectionPass)
364 return;
365 fYOZSlice.DrawSlice(fYOZSectionPos / fCoord->GetXScale());
366}
367
368////////////////////////////////////////////////////////////////////////////////
369/// Draw XOY parallel section.
370
372{
373 if (fSelectionPass)
374 return;
375 fXOYSlice.DrawSlice(fXOYSectionPos / fCoord->GetZScale());
376}
377
378
379/** \class TGLIsoPainter
380\ingroup opengl
381"gliso" option for TH3.
382*/
383
384
385////////////////////////////////////////////////////////////////////////////////
386///Constructor.
387
389 : TGLPlotPainter(hist, camera, coord, kFALSE, kFALSE, kFALSE),
390 fXOZSlice("XOZ", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kXOZ),
391 fYOZSlice("YOZ", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kYOZ),
392 fXOYSlice("XOY", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kXOY),
394{
395 if (hist->GetDimension() < 3)
396 Error("TGLIsoPainter::TGLIsoPainter", "Wrong type of histogramm, must have 3 dimensions");
397}
398
399////////////////////////////////////////////////////////////////////////////////
400///Return info for plot part under cursor.
401
403{
404 static char mess[] = { "iso" };
405 return mess;
406}
407
408////////////////////////////////////////////////////////////////////////////////
409///Initializes meshes for 3d iso contours.
410
412{
413 if (fHist->GetDimension() < 3) {
414 Error("TGLIsoPainter::TGLIsoPainter", "Wrong type of histogramm, must have 3 dimensions");
415 return kFALSE;
416 }
417
418 //Create mesh.
419 if (fInit)
420 return kTRUE;
421
422 //Only in cartesian.
423 fCoord->SetCoordType(kGLCartesian);
424 if (!fCoord->SetRanges(fHist, kFALSE, kTRUE))
425 return kFALSE;
426
427 fBackBox.SetPlotBox(fCoord->GetXRangeScaled(), fCoord->GetYRangeScaled(), fCoord->GetZRangeScaled());
428 if (fCamera) fCamera->SetViewVolume(fBackBox.Get3DBox());
429
430 //Move old meshes into the cache.
431 if (!fIsos.empty())
432 fCache.splice(fCache.begin(), fIsos);
433 //Number of contours == number of iso surfaces.
434 UInt_t nContours = fHist->GetContour();
435
436 if (nContours > 1) {
437 fColorLevels.resize(nContours);
438 FindMinMax();
439
440 if (fHist->TestBit(TH1::kUserContour)) {
441 //There are user defined contours (iso-levels).
442 for (UInt_t i = 0; i < nContours; ++i)
443 fColorLevels[i] = fHist->GetContourLevelPad(i);
444 } else {
445 //Equidistant iso-surfaces.
446 const Double_t isoStep = (fMinMax.second - fMinMax.first) / nContours;
447 for (UInt_t i = 0; i < nContours; ++i)
448 fColorLevels[i] = fMinMax.first + i * isoStep;
449 }
450
451 fPalette.GeneratePalette(nContours, fMinMax, kFALSE);
452 } else {
453 //Only one iso (ROOT's standard).
454 fColorLevels.resize(nContours = 1);
455 fColorLevels[0] = fHist->GetSumOfWeights() / (fHist->GetNbinsX() * fHist->GetNbinsY() * fHist->GetNbinsZ());
456 }
457
458 MeshIter_t firstMesh = fCache.begin();
459 //Initialize meshes, trying to reuse mesh from
460 //mesh cache.
461 for (UInt_t i = 0; i < nContours; ++i) {
462 if (firstMesh != fCache.end()) {
463 //There is a mesh in a cache.
464 SetMesh(*firstMesh, fColorLevels[i]);
465 MeshIter_t next = firstMesh;
466 ++next;
467 fIsos.splice(fIsos.begin(), fCache, firstMesh);
468 firstMesh = next;
469 } else {
470 //No meshes in a cache.
471 //Create new one and _swap_ data (look at Mesh_t::Swap in a header)
472 //between empty mesh in a list and this mesh
473 //to avoid real copying.
474 Mesh_t newMesh;
475 SetMesh(newMesh, fColorLevels[i]);
476 fIsos.push_back(fDummyMesh);
477 fIsos.back().Swap(newMesh);
478 }
479 }
480
481 if (fCoord->Modified()) {
483 fXOZSectionPos = fBackBox.Get3DBox()[0].Y();
484 fYOZSectionPos = fBackBox.Get3DBox()[0].X();
485 fXOYSectionPos = fBackBox.Get3DBox()[0].Z();
486 fCoord->ResetModified();
487 }
488
489 //Avoid rebuilding the mesh.
490 fInit = kTRUE;
491
492 return kTRUE;
493
494}
495
496////////////////////////////////////////////////////////////////////////////////
497///User clicks right mouse button (in a pad).
498
500{
501 fMousePosition.fX = px;
502 fMousePosition.fY = fCamera->GetHeight() - py;
503 fCamera->StartPan(px, py);
504 fBoxCut.StartMovement(px, fCamera->GetHeight() - py);
505}
506
507////////////////////////////////////////////////////////////////////////////////
508///User's moving mouse cursor, with middle mouse button pressed (for pad).
509///Calculate 3d shift related to 2d mouse movement.
510///User's moving mouse cursor, with middle mouse button pressed (for pad).
511///Calculate 3d shift related to 2d mouse movement.
512
514{
515 if (fSelectedPart >= fSelectionBase) {//Pan camera.
518
519 fCamera->SetCamera();
520 fCamera->Apply(fPadPhi, fPadTheta);
521 fCamera->Pan(px, py);
522
525 } else if (fSelectedPart > 0) {
526 //Convert py into bottom-top orientation.
527 //Possibly, move box here
528 py = fCamera->GetHeight() - py;
529
532
533 fCamera->SetCamera();
534 fCamera->Apply(fPadPhi, fPadTheta);
535
536 if (!fHighColor) {
537 if (fBoxCut.IsActive() && (fSelectedPart >= kXAxis && fSelectedPart <= kZAxis)) {
538 fBoxCut.MoveBox(px, py, fSelectedPart);
539 } else {
540 //MoveSection(px, py);
541 }
542 } else {
543 //MoveSection(px, py);
544 }
545
548
549 }
550
551 fMousePosition.fX = px, fMousePosition.fY = py;
553}
554
555////////////////////////////////////////////////////////////////////////////////
556///No additional options for TGLIsoPainter.
557
558void TGLIsoPainter::AddOption(const TString &/*option*/)
559{
560}
561
562////////////////////////////////////////////////////////////////////////////////
563///Change color scheme.
564
566{
567 if (event == kKeyPress) {
568 if (py == kKey_c || py == kKey_C) {
569 if (fHighColor)
570 Info("ProcessEvent", "Cut box does not work in high color, please, switch to true color");
571 else {
572 fBoxCut.TurnOnOff();
574 }
575 }
576 } else if (event == kButton1Double && (fBoxCut.IsActive() || HasSections())) {
577 if (fBoxCut.IsActive())
578 fBoxCut.TurnOnOff();
579 const TGLVertex3 *frame = fBackBox.Get3DBox();
580 fXOZSectionPos = frame[0].Y();
581 fYOZSectionPos = frame[0].X();
582 fXOYSectionPos = frame[0].Z();
583
584 if (!gVirtualX->IsCmdThread())
585 gROOT->ProcessLineFast(Form("((TGLPlotPainter *)0x%zx)->Paint()", (size_t)this));
586 else
587 Paint();
588 }
589}
590
591////////////////////////////////////////////////////////////////////////////////
592///Initialize OpenGL state variables.
593
595{
596 glEnable(GL_LIGHTING);
597 glEnable(GL_LIGHT0);
598 glEnable(GL_DEPTH_TEST);
599 glDisable(GL_CULL_FACE);
600 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
601}
602
603////////////////////////////////////////////////////////////////////////////////
604///Initialize OpenGL state variables.
605
607{
608 glDisable(GL_LIGHTING);
609 glDisable(GL_LIGHT0);
610 glDisable(GL_DEPTH_TEST);
611 glDisable(GL_CULL_FACE);
612 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
613}
614
615////////////////////////////////////////////////////////////////////////////////
616///Draw mesh.
617
619{
620 //Shift plot to point of origin.
621 const Rgl::PlotTranslation trGuard(this);
622
623
625 DrawSections();
626
627 if (fIsos.size() != fColorLevels.size()) {
628 Error("TGLIsoPainter::DrawPlot", "Non-equal number of levels and isos");
629 return;
630 }
631
632 if (!fSelectionPass && HasSections()) {
633 //Surface is semi-transparent during dynamic profiling.
634 //Having several complex nested surfaces, it's not easy
635 //(possible?) to implement correct and _efficient_ transparency
636 //drawing. So, artefacts are possbile.
637 glEnable(GL_BLEND);
638 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
639 glDepthMask(GL_FALSE);
640 }
641
642 UInt_t colorInd = 0;
643 ConstMeshIter_t iso = fIsos.begin();
644
645 for (; iso != fIsos.end(); ++iso, ++colorInd)
646 DrawMesh(*iso, colorInd);
647
648 if (!fSelectionPass && HasSections()) {
649 glDisable(GL_BLEND);
650 glDepthMask(GL_TRUE);
651 }
652
653 if (fBoxCut.IsActive())
655}
656
657////////////////////////////////////////////////////////////////////////////////
658/// Draw XOZ parallel section.
659
661{
662 if (fSelectionPass)
663 return;
664 fXOZSlice.DrawSlice(fXOZSectionPos / fCoord->GetYScale());
665}
666
667////////////////////////////////////////////////////////////////////////////////
668/// Draw YOZ parallel section.
669
671{
672 if (fSelectionPass)
673 return;
674 fYOZSlice.DrawSlice(fYOZSectionPos / fCoord->GetXScale());
675}
676
677////////////////////////////////////////////////////////////////////////////////
678/// Draw XOY parallel section.
679
681{
682 if (fSelectionPass)
683 return;
684 fXOYSlice.DrawSlice(fXOYSectionPos / fCoord->GetZScale());
685}
686
687////////////////////////////////////////////////////////////////////////////////
688///Any section exists.
689
691{
692 return fXOZSectionPos > fBackBox.Get3DBox()[0].Y() || fYOZSectionPos > fBackBox.Get3DBox()[0].X() ||
693 fXOYSectionPos > fBackBox.Get3DBox()[0].Z();
694}
695
696////////////////////////////////////////////////////////////////////////////////
697///Set color for surface.
698
700{
701 Float_t diffColor[] = {0.8f, 0.8f, 0.8f, 0.25f};
702
703 if (fColorLevels.size() == 1) {
704 if (fHist->GetFillColor() != kWhite)
705 if (const TColor *c = gROOT->GetColor(fHist->GetFillColor()))
706 c->GetRGB(diffColor[0], diffColor[1], diffColor[2]);
707 } else {
708 const UChar_t *color = fPalette.GetColour(ind);
709 diffColor[0] = color[0] / 255.;
710 diffColor[1] = color[1] / 255.;
711 diffColor[2] = color[2] / 255.;
712 }
713
714 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffColor);
715 const Float_t specColor[] = {1.f, 1.f, 1.f, 1.f};
716 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor);
717 diffColor[0] /= 3.5, diffColor[1] /= 3.5, diffColor[2] /= 3.5;
718 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, diffColor);
719 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 30.f);
720}
721
722////////////////////////////////////////////////////////////////////////////////
723///Grid geometry.
724
726{
728 fCoord->GetYScale(), fCoord->GetZScale());
729 //Clear mesh if it was from cache.
730 m.ClearMesh();
731 //Select correct TMeshBuilder type.
732 if (typeid(*fHist) == typeid(TH3C)) {
734 builder.BuildMesh(static_cast<TH3C *>(fHist), geom, &m, isoValue);
735 } else if (typeid(*fHist) == typeid(TH3S)) {
737 builder.BuildMesh(static_cast<TH3S *>(fHist), geom, &m, isoValue);
738 } else if (typeid(*fHist) == typeid(TH3I)) {
740 builder.BuildMesh(static_cast<TH3I *>(fHist), geom, &m, isoValue);
741 } else if (typeid(*fHist) == typeid(TH3F)) {
743 builder.BuildMesh(static_cast<TH3F *>(fHist), geom, &m, isoValue);
744 } else if (typeid(*fHist) == typeid(TH3D)) {
746 builder.BuildMesh(static_cast<TH3D *>(fHist), geom, &m, isoValue);
747 }
748}
749
750////////////////////////////////////////////////////////////////////////////////
751///Draw TF3 surface
752
753void TGLIsoPainter::DrawMesh(const Mesh_t &m, Int_t level) const
754{
755 if (!fSelectionPass)
756 SetSurfaceColor(level);
757
758 if (!fBoxCut.IsActive()) {
759 if (!fSelectionPass)
760 Rgl::DrawMesh(m.fVerts, m.fNorms, m.fTris);
761 else {
763 Rgl::DrawMesh(m.fVerts, m.fTris);
764 }
765 } else {
766 if (!fSelectionPass)
767 Rgl::DrawMesh(m.fVerts, m.fNorms, m.fTris, fBoxCut);
768 else {
770 Rgl::DrawMesh(m.fVerts, m.fTris, fBoxCut);
771 }
772 }
773}
774
775////////////////////////////////////////////////////////////////////////////////
776///Find max/min bin contents for TH3.
777
779{
780 fMinMax.first = fHist->GetBinContent(fXAxis->GetFirst(), fYAxis->GetFirst(), fZAxis->GetFirst());
781 fMinMax.second = fMinMax.first;
782
783 for (Int_t i = fXAxis->GetFirst(), ei = fXAxis->GetLast(); i <= ei; ++i) {
784 for (Int_t j = fYAxis->GetFirst(), ej = fYAxis->GetLast(); j <= ej; ++j) {
785 for (Int_t k = fZAxis->GetFirst(), ek = fZAxis->GetLast(); k <= ek; ++k) {
786 const Double_t binContent = fHist->GetBinContent(i, j, k);
787 fMinMax.first = TMath::Min(binContent, fMinMax.first);
788 fMinMax.second = TMath::Max(binContent, fMinMax.second);
789 }
790 }
791 }
792}
@ kKeyPress
Definition Buttons.h:20
@ kButton1Double
Definition Buttons.h:24
@ kKey_C
Definition KeySymbols.h:128
@ kKey_S
Definition KeySymbols.h:144
@ kKey_s
Definition KeySymbols.h:176
@ kKey_c
Definition KeySymbols.h:160
#define c(i)
Definition RSha256.hxx:101
int Int_t
Signed integer 4 bytes (int).
Definition RtypesCore.h:59
unsigned char UChar_t
Unsigned Character 1 byte (unsigned char).
Definition RtypesCore.h:52
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int).
Definition RtypesCore.h:60
bool Bool_t
Boolean (0=false, 1=true) (bool).
Definition RtypesCore.h:77
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
float Float_t
Float 4 bytes (float).
Definition RtypesCore.h:71
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
@ kWhite
Definition Rtypes.h:66
Error("WriteTObject","The current directory (%s) is not associated with a file. The object (%s) has not been written.", GetName(), objname)
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:241
@ kGLCartesian
Definition TGLUtil.h:44
#define gROOT
Definition TROOT.h:417
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2496
#define gVirtualX
Definition TVirtualX.h:375
void BuildMesh(const DataSource *src, const TGridGeometry< ValueType > &geom, MeshType_t *mesh, ValueType iso)
Build iso-mesh using marching cubes.
Definition TF3.h:28
TGLTH3Slice fXOZSlice
Bool_t HasSections() const
Any section exists.
MeshList_t fCache
char * GetPlotInfo(Int_t px, Int_t py) override
Return info for plot part under cursor.
TGLTH3Slice fYOZSlice
TGLIsoPainter(TH1 *hist, TGLPlotCamera *camera, TGLPlotCoordinates *coord)
Constructor.
void DeInitGL() const override
Initialize OpenGL state variables.
Bool_t InitGeometry() override
Initializes meshes for 3d iso contours.
void DrawMesh(const Mesh_t &mesh, Int_t level) const
Draw TF3 surface.
TGLLevelPalette fPalette
Rgl::Mc::TIsoMesh< Float_t > Mesh_t
void DrawSectionXOY() const override
Draw XOY parallel section.
Rgl::Range_t fMinMax
void DrawSectionXOZ() const override
Draw XOZ parallel section.
void AddOption(const TString &option) override
No additional options for TGLIsoPainter.
std::list< Mesh_t >::iterator MeshIter_t
void FindMinMax()
Find max/min bin contents for TH3.
std::vector< Double_t > fColorLevels
void SetMesh(Mesh_t &mesh, Double_t isoValue)
Grid geometry.
MeshList_t fIsos
void ProcessEvent(Int_t event, Int_t px, Int_t py) override
Change color scheme.
void InitGL() const override
Initialize OpenGL state variables.
void DrawSectionYOZ() const override
Draw YOZ parallel section.
TGLTH3Slice fXOYSlice
void SetSurfaceColor(Int_t ind) const
Set color for surface.
void DrawPlot() const override
Draw mesh.
std::list< Mesh_t >::const_iterator ConstMeshIter_t
void StartPan(Int_t px, Int_t py) override
User clicks right mouse button (in a pad).
void Pan(Int_t px, Int_t py) override
User's moving mouse cursor, with middle mouse button pressed (for pad).
Camera for TGLPlotPainter and sub-classes.
Helper class for plot-painters holding information about axis ranges, numbers of bins and flags if ce...
void DrawSections() const
Draw sections (if any).
TGLPlotPainter(TH1 *hist, TGLPlotCamera *camera, TGLPlotCoordinates *coord, Bool_t xoySelectable, Bool_t xozSelectable, Bool_t yozSelectable)
TGLPlotPainter's ctor.
std::vector< Double_t > fZLevels
Double_t fXOYSectionPos
void RestoreModelviewMatrix() const
Double_t fXOZSectionPos
TGLPlotCoordinates * fCoord
void Paint() override
Draw lego/surf/whatever you can.
TGLPlotBox fBackBox
void SaveProjectionMatrix() const
void SaveModelviewMatrix() const
TGLPlotCamera * fCamera
void RestoreProjectionMatrix() const
Double_t fYOZSectionPos
Rgl::Mc::TIsoMesh< Double_t > fMesh
void DeInitGL() const override
Initialize OpenGL state variables.
void DrawSectionXOZ() const override
Draw XOZ parallel section.
Bool_t InitGeometry() override
Create mesh.
void DrawSectionYOZ() const override
Draw YOZ parallel section.
TGLTF3Painter(TF3 *fun, TH1 *hist, TGLPlotCamera *camera, TGLPlotCoordinates *coord)
Constructor.
void DrawDefaultPlot() const
Surface with material properties and lighting.
void AddOption(const TString &stringOption) override
No options for tf3.
void Pan(Int_t px, Int_t py) override
User's moving mouse cursor, with middle mouse button pressed (for pad).
TGLTH3Slice fXOZSlice
void DrawPlot() const override
Draw mesh.
void InitGL() const override
Initialize OpenGL state variables.
char * GetPlotInfo(Int_t px, Int_t py) override
Coords for point on surface under cursor.
void DrawToSelectionBuffer() const
Draw triangles, no normals, no lighting.
TGLTH3Slice fXOYSlice
void SetSurfaceColor() const
Set color for surface.
ETF3Style fStyle
void ProcessEvent(Int_t event, Int_t px, Int_t py) override
Change color scheme.
void DrawSectionXOY() const override
Draw XOY parallel section.
void DrawMaplePlot() const
Colored surface, without lighting and material properties.
TGLTH3Slice fYOZSlice
void StartPan(Int_t px, Int_t py) override
User clicks right mouse button (in a pad).
Bool_t HasSections() const
Any section exists.
A slice of a TH3.
3 component (x/y/z) vertex class.
Definition TGLUtil.h:84
Double_t X() const
Definition TGLUtil.h:119
Double_t Z() const
Definition TGLUtil.h:123
Double_t Y() const
Definition TGLUtil.h:121
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
virtual Int_t GetDimension() const
Definition TH1.h:527
@ kUserContour
User specified contour levels.
Definition TH1.h:404
3-D histogram with a byte per channel (see TH1 documentation)
Definition TH3.h:176
3-D histogram with a double per channel (see TH1 documentation)
Definition TH3.h:424
3-D histogram with a float per channel (see TH1 documentation)
Definition TH3.h:369
3-D histogram with an int per channel (see TH1 documentation)
Definition TH3.h:273
3-D histogram with a short per channel (see TH1 documentation)
Definition TH3.h:224
The 3-D histogram classes derived from the 1-D histogram classes.
Definition TH3.h:45
Basic string class.
Definition TString.h:138
void DrawMapleMesh(const std::vector< Double_t > &vs, const std::vector< Double_t > &ns, const std::vector< UInt_t > &ts)
Colored mesh with lighting disabled.
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
Definition TGLUtil.cxx:2890
void DrawMesh(const std::vector< Float_t > &vs, const std::vector< Float_t > &ns, const std::vector< UInt_t > &ts)
Call function-template.
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:249
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:197
TMarker m
Definition textangle.C:8