35 ClassImp(TGLTF3Painter);
40 TGLTF3Painter::TGLTF3Painter(TF3 *fun, TH1 *hist, TGLPlotCamera *camera, TGLPlotCoordinates *coord)
41 : TGLPlotPainter(hist, camera, coord, kFALSE, kFALSE, kFALSE),
44 fXOZSlice(
"XOZ", (TH3 *)hist, fun, coord, &fBackBox, TGLTH3Slice::kXOZ),
45 fYOZSlice(
"YOZ", (TH3 *)hist, fun, coord, &fBackBox, TGLTH3Slice::kYOZ),
46 fXOYSlice(
"XOY", (TH3 *)hist, fun, coord, &fBackBox, TGLTH3Slice::kXOY)
53 char *TGLTF3Painter::GetPlotInfo(Int_t , Int_t )
55 static char mess[] = {
"fun3" };
62 Bool_t TGLTF3Painter::InitGeometry()
64 fCoord->SetCoordType(kGLCartesian);
66 if (!fCoord->SetRanges(fHist, kFALSE, kTRUE))
69 fBackBox.SetPlotBox(fCoord->GetXRangeScaled(), fCoord->GetYRangeScaled(), fCoord->GetZRangeScaled());
70 if (fCamera) fCamera->SetViewVolume(fBackBox.Get3DBox());
75 Rgl::Mc::TMeshBuilder<TF3, Double_t> builder(kFALSE);
77 Rgl::Mc::TGridGeometry<Double_t> geom(fXAxis, fYAxis, fZAxis, fCoord->GetXScale(),
78 fCoord->GetYScale(), fCoord->GetZScale(),
79 Rgl::Mc::TGridGeometry<Double_t>::kBinEdge);
81 builder.BuildMesh(fF3, geom, &fMesh, 0.);
83 if (fCoord->Modified()) {
84 fUpdateSelection = kTRUE;
85 const TGLVertex3 &vertex = fBackBox.Get3DBox()[0];
86 fXOZSectionPos = vertex.Y();
87 fYOZSectionPos = vertex.X();
88 fXOYSectionPos = vertex.Z();
89 fCoord->ResetModified();
98 void TGLTF3Painter::StartPan(Int_t px, Int_t py)
100 fMousePosition.fX = px;
101 fMousePosition.fY = fCamera->GetHeight() - py;
102 fCamera->StartPan(px, py);
103 fBoxCut.StartMovement(px, fCamera->GetHeight() - py);
111 void TGLTF3Painter::Pan(Int_t px, Int_t py)
113 if (fSelectedPart >= fSelectionBase) {
114 SaveModelviewMatrix();
115 SaveProjectionMatrix();
117 fCamera->SetCamera();
118 fCamera->Apply(fPadPhi, fPadTheta);
119 fCamera->Pan(px, py);
121 RestoreProjectionMatrix();
122 RestoreModelviewMatrix();
123 }
else if (fSelectedPart > 0) {
126 py = fCamera->GetHeight() - py;
128 SaveModelviewMatrix();
129 SaveProjectionMatrix();
131 fCamera->SetCamera();
132 fCamera->Apply(fPadPhi, fPadTheta);
135 if (fBoxCut.IsActive() && (fSelectedPart >= kXAxis && fSelectedPart <= kZAxis)) {
136 fBoxCut.MoveBox(px, py, fSelectedPart);
144 RestoreProjectionMatrix();
145 RestoreModelviewMatrix();
148 fMousePosition.fX = px, fMousePosition.fY = py;
149 fUpdateSelection = kTRUE;
155 void TGLTF3Painter::AddOption(
const TString &)
162 void TGLTF3Painter::ProcessEvent(Int_t event, Int_t , Int_t py)
164 if (event == kKeyPress) {
165 if (py == kKey_s || py == kKey_S) {
166 fStyle < kMaple2 ? fStyle = ETF3Style(fStyle + 1) : fStyle = kDefault;
167 }
else if (py == kKey_c || py == kKey_C) {
169 Info(
"ProcessEvent",
"Cut box does not work in high color, please, switch to true color");
172 fUpdateSelection = kTRUE;
175 }
else if (event == kButton1Double && (fBoxCut.IsActive() || HasSections())) {
176 if (fBoxCut.IsActive())
178 const TGLVertex3 *frame = fBackBox.Get3DBox();
179 fXOZSectionPos = frame[0].Y();
180 fYOZSectionPos = frame[0].X();
181 fXOYSectionPos = frame[0].Z();
183 if (!gVirtualX->IsCmdThread())
184 gROOT->ProcessLineFast(Form(
"((TGLPlotPainter *)0x%lx)->Paint()", (ULong_t)
this));
193 void TGLTF3Painter::InitGL()
const
195 glEnable(GL_LIGHTING);
197 glEnable(GL_DEPTH_TEST);
198 glDisable(GL_CULL_FACE);
199 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
205 void TGLTF3Painter::DeInitGL()
const
207 glDisable(GL_LIGHTING);
208 glDisable(GL_LIGHT0);
209 glDisable(GL_DEPTH_TEST);
210 glDisable(GL_CULL_FACE);
211 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
217 void TGLTF3Painter::DrawToSelectionBuffer()
const
219 Rgl::ObjectIDToColor(fSelectionBase, fHighColor);
221 if (!fBoxCut.IsActive())
222 Rgl::DrawMesh(fMesh.fVerts, fMesh.fTris);
224 Rgl::DrawMesh(fMesh.fVerts, fMesh.fTris, fBoxCut);
230 void TGLTF3Painter::DrawDefaultPlot()
const
234 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
235 glDepthMask(GL_FALSE);
240 if (!fBoxCut.IsActive()) {
241 Rgl::DrawMesh(fMesh.fVerts, fMesh.fNorms, fMesh.fTris);
243 Rgl::DrawMesh(fMesh.fVerts, fMesh.fNorms, fMesh.fTris, fBoxCut);
248 glDepthMask(GL_TRUE);
256 void TGLTF3Painter::DrawMaplePlot()
const
258 const TGLDisableGuard lightGuard(GL_LIGHTING);
260 if (HasSections() && fStyle < kMaple2) {
262 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
263 glDepthMask(GL_FALSE);
266 if (fStyle == kMaple1) {
267 glEnable(GL_POLYGON_OFFSET_FILL);
268 glPolygonOffset(1.f, 1.f);
269 }
else if (fStyle == kMaple2)
270 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
272 if(!fBoxCut.IsActive())
273 Rgl::DrawMapleMesh(fMesh.fVerts, fMesh.fNorms, fMesh.fTris);
275 Rgl::DrawMapleMesh(fMesh.fVerts, fMesh.fNorms, fMesh.fTris, fBoxCut);
277 if (fStyle == kMaple1) {
279 glDisable(GL_POLYGON_OFFSET_FILL);
280 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
281 glColor4d(0., 0., 0., 0.25);
283 if(!fBoxCut.IsActive())
284 Rgl::DrawMesh(fMesh.fVerts, fMesh.fTris);
286 Rgl::DrawMesh(fMesh.fVerts, fMesh.fTris, fBoxCut);
288 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
289 }
else if (fStyle == kMaple2)
290 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
292 if (HasSections() && fStyle < kMaple2) {
294 glDepthMask(GL_TRUE);
301 void TGLTF3Painter::DrawPlot()
const
304 const Rgl::PlotTranslation trGuard(
this);
306 fBackBox.DrawBox(fSelectedPart, fSelectionPass, fZLevels, fHighColor);
309 if (fSelectionPass) {
310 DrawToSelectionBuffer();
311 }
else if (fStyle == kDefault) {
317 if (fBoxCut.IsActive())
318 fBoxCut.DrawBox(fSelectionPass, fSelectedPart);
324 void TGLTF3Painter::SetSurfaceColor()
const
326 Float_t diffColor[] = {0.8f, 0.8f, 0.8f, 0.15f};
328 if (fF3->GetFillColor() != kWhite)
329 if (
const TColor *c = gROOT->GetColor(fF3->GetFillColor()))
330 c->GetRGB(diffColor[0], diffColor[1], diffColor[2]);
332 glMaterialfv(GL_BACK, GL_DIFFUSE, diffColor);
333 diffColor[0] /= 2, diffColor[1] /= 2, diffColor[2] /= 2;
334 glMaterialfv(GL_FRONT, GL_DIFFUSE, diffColor);
335 const Float_t specColor[] = {1.f, 1.f, 1.f, 1.f};
336 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor);
337 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.f);
343 Bool_t TGLTF3Painter::HasSections()
const
345 return fXOZSectionPos > fBackBox.Get3DBox()[0].Y() ||
346 fYOZSectionPos > fBackBox.Get3DBox()[0].X() ||
347 fXOYSectionPos > fBackBox.Get3DBox()[0].Z();
353 void TGLTF3Painter::DrawSectionXOZ()
const
357 fXOZSlice.DrawSlice(fXOZSectionPos / fCoord->GetYScale());
363 void TGLTF3Painter::DrawSectionYOZ()
const
367 fYOZSlice.DrawSlice(fYOZSectionPos / fCoord->GetXScale());
373 void TGLTF3Painter::DrawSectionXOY()
const
377 fXOYSlice.DrawSlice(fXOYSectionPos / fCoord->GetZScale());
386 ClassImp(TGLIsoPainter);
391 TGLIsoPainter::TGLIsoPainter(TH1 *hist, TGLPlotCamera *camera, TGLPlotCoordinates *coord)
392 : TGLPlotPainter(hist, camera, coord, kFALSE, kFALSE, kFALSE),
393 fXOZSlice(
"XOZ", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kXOZ),
394 fYOZSlice(
"YOZ", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kYOZ),
395 fXOYSlice(
"XOY", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kXOY),
398 if (hist->GetDimension() < 3)
399 Error(
"TGLIsoPainter::TGLIsoPainter",
"Wrong type of histogramm, must have 3 dimensions");
405 char *TGLIsoPainter::GetPlotInfo(Int_t , Int_t )
407 static char mess[] = {
"iso" };
414 Bool_t TGLIsoPainter::InitGeometry()
416 if (fHist->GetDimension() < 3) {
417 Error(
"TGLIsoPainter::TGLIsoPainter",
"Wrong type of histogramm, must have 3 dimensions");
426 fCoord->SetCoordType(kGLCartesian);
427 if (!fCoord->SetRanges(fHist, kFALSE, kTRUE))
430 fBackBox.SetPlotBox(fCoord->GetXRangeScaled(), fCoord->GetYRangeScaled(), fCoord->GetZRangeScaled());
431 if (fCamera) fCamera->SetViewVolume(fBackBox.Get3DBox());
435 fCache.splice(fCache.begin(), fIsos);
437 UInt_t nContours = fHist->GetContour();
440 fColorLevels.resize(nContours);
443 if (fHist->TestBit(TH1::kUserContour)) {
445 for (UInt_t i = 0; i < nContours; ++i)
446 fColorLevels[i] = fHist->GetContourLevelPad(i);
449 const Double_t isoStep = (fMinMax.second - fMinMax.first) / nContours;
450 for (UInt_t i = 0; i < nContours; ++i)
451 fColorLevels[i] = fMinMax.first + i * isoStep;
454 fPalette.GeneratePalette(nContours, fMinMax, kFALSE);
457 fColorLevels.resize(nContours = 1);
458 fColorLevels[0] = fHist->GetSumOfWeights() / (fHist->GetNbinsX() * fHist->GetNbinsY() * fHist->GetNbinsZ());
461 MeshIter_t firstMesh = fCache.begin();
464 for (UInt_t i = 0; i < nContours; ++i) {
465 if (firstMesh != fCache.end()) {
467 SetMesh(*firstMesh, fColorLevels[i]);
468 MeshIter_t next = firstMesh;
470 fIsos.splice(fIsos.begin(), fCache, firstMesh);
478 SetMesh(newMesh, fColorLevels[i]);
479 fIsos.push_back(fDummyMesh);
480 fIsos.back().Swap(newMesh);
484 if (fCoord->Modified()) {
485 fUpdateSelection = kTRUE;
486 fXOZSectionPos = fBackBox.Get3DBox()[0].Y();
487 fYOZSectionPos = fBackBox.Get3DBox()[0].X();
488 fXOYSectionPos = fBackBox.Get3DBox()[0].Z();
489 fCoord->ResetModified();
502 void TGLIsoPainter::StartPan(Int_t px, Int_t py)
504 fMousePosition.fX = px;
505 fMousePosition.fY = fCamera->GetHeight() - py;
506 fCamera->StartPan(px, py);
507 fBoxCut.StartMovement(px, fCamera->GetHeight() - py);
516 void TGLIsoPainter::Pan(Int_t px, Int_t py)
518 if (fSelectedPart >= fSelectionBase) {
519 SaveModelviewMatrix();
520 SaveProjectionMatrix();
522 fCamera->SetCamera();
523 fCamera->Apply(fPadPhi, fPadTheta);
524 fCamera->Pan(px, py);
526 RestoreProjectionMatrix();
527 RestoreModelviewMatrix();
528 }
else if (fSelectedPart > 0) {
531 py = fCamera->GetHeight() - py;
533 SaveModelviewMatrix();
534 SaveProjectionMatrix();
536 fCamera->SetCamera();
537 fCamera->Apply(fPadPhi, fPadTheta);
540 if (fBoxCut.IsActive() && (fSelectedPart >= kXAxis && fSelectedPart <= kZAxis)) {
541 fBoxCut.MoveBox(px, py, fSelectedPart);
549 RestoreProjectionMatrix();
550 RestoreModelviewMatrix();
554 fMousePosition.fX = px, fMousePosition.fY = py;
555 fUpdateSelection = kTRUE;
561 void TGLIsoPainter::AddOption(
const TString &)
568 void TGLIsoPainter::ProcessEvent(Int_t event, Int_t , Int_t py)
570 if (event == kKeyPress) {
571 if (py == kKey_c || py == kKey_C) {
573 Info(
"ProcessEvent",
"Cut box does not work in high color, please, switch to true color");
576 fUpdateSelection = kTRUE;
579 }
else if (event == kButton1Double && (fBoxCut.IsActive() || HasSections())) {
580 if (fBoxCut.IsActive())
582 const TGLVertex3 *frame = fBackBox.Get3DBox();
583 fXOZSectionPos = frame[0].Y();
584 fYOZSectionPos = frame[0].X();
585 fXOYSectionPos = frame[0].Z();
587 if (!gVirtualX->IsCmdThread())
588 gROOT->ProcessLineFast(Form(
"((TGLPlotPainter *)0x%lx)->Paint()", (ULong_t)
this));
597 void TGLIsoPainter::InitGL()
const
599 glEnable(GL_LIGHTING);
601 glEnable(GL_DEPTH_TEST);
602 glDisable(GL_CULL_FACE);
603 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
609 void TGLIsoPainter::DeInitGL()
const
611 glDisable(GL_LIGHTING);
612 glDisable(GL_LIGHT0);
613 glDisable(GL_DEPTH_TEST);
614 glDisable(GL_CULL_FACE);
615 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
621 void TGLIsoPainter::DrawPlot()
const
624 const Rgl::PlotTranslation trGuard(
this);
627 fBackBox.DrawBox(fSelectedPart, fSelectionPass, fZLevels, fHighColor);
630 if (fIsos.size() != fColorLevels.size()) {
631 Error(
"TGLIsoPainter::DrawPlot",
"Non-equal number of levels and isos");
635 if (!fSelectionPass && HasSections()) {
641 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
642 glDepthMask(GL_FALSE);
646 ConstMeshIter_t iso = fIsos.begin();
648 for (; iso != fIsos.end(); ++iso, ++colorInd)
649 DrawMesh(*iso, colorInd);
651 if (!fSelectionPass && HasSections()) {
653 glDepthMask(GL_TRUE);
656 if (fBoxCut.IsActive())
657 fBoxCut.DrawBox(fSelectionPass, fSelectedPart);
663 void TGLIsoPainter::DrawSectionXOZ()
const
667 fXOZSlice.DrawSlice(fXOZSectionPos / fCoord->GetYScale());
673 void TGLIsoPainter::DrawSectionYOZ()
const
677 fYOZSlice.DrawSlice(fYOZSectionPos / fCoord->GetXScale());
683 void TGLIsoPainter::DrawSectionXOY()
const
687 fXOYSlice.DrawSlice(fXOYSectionPos / fCoord->GetZScale());
693 Bool_t TGLIsoPainter::HasSections()
const
695 return fXOZSectionPos > fBackBox.Get3DBox()[0].Y() || fYOZSectionPos > fBackBox.Get3DBox()[0].X() ||
696 fXOYSectionPos > fBackBox.Get3DBox()[0].Z();
702 void TGLIsoPainter::SetSurfaceColor(Int_t ind)
const
704 Float_t diffColor[] = {0.8f, 0.8f, 0.8f, 0.25f};
706 if (fColorLevels.size() == 1) {
707 if (fHist->GetFillColor() != kWhite)
708 if (
const TColor *c = gROOT->GetColor(fHist->GetFillColor()))
709 c->GetRGB(diffColor[0], diffColor[1], diffColor[2]);
711 const UChar_t *color = fPalette.GetColour(ind);
712 diffColor[0] = color[0] / 255.;
713 diffColor[1] = color[1] / 255.;
714 diffColor[2] = color[2] / 255.;
717 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffColor);
718 const Float_t specColor[] = {1.f, 1.f, 1.f, 1.f};
719 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor);
720 diffColor[0] /= 3.5, diffColor[1] /= 3.5, diffColor[2] /= 3.5;
721 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, diffColor);
722 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 30.f);
728 void TGLIsoPainter::SetMesh(Mesh_t &m, Double_t isoValue)
730 Rgl::Mc::TGridGeometry<Float_t> geom(fXAxis, fYAxis, fZAxis, fCoord->GetXScale(),
731 fCoord->GetYScale(), fCoord->GetZScale());
735 if (
typeid(*fHist) ==
typeid(TH3C)) {
736 Rgl::Mc::TMeshBuilder<TH3C, Float_t> builder(kTRUE);
737 builder.BuildMesh(static_cast<TH3C *>(fHist), geom, &m, isoValue);
738 }
else if (
typeid(*fHist) ==
typeid(TH3S)) {
739 Rgl::Mc::TMeshBuilder<TH3S, Float_t> builder(kTRUE);
740 builder.BuildMesh(static_cast<TH3S *>(fHist), geom, &m, isoValue);
741 }
else if (
typeid(*fHist) ==
typeid(TH3I)) {
742 Rgl::Mc::TMeshBuilder<TH3I, Float_t> builder(kTRUE);
743 builder.BuildMesh(static_cast<TH3I *>(fHist), geom, &m, isoValue);
744 }
else if (
typeid(*fHist) ==
typeid(TH3F)) {
745 Rgl::Mc::TMeshBuilder<TH3F, Float_t> builder(kTRUE);
746 builder.BuildMesh(static_cast<TH3F *>(fHist), geom, &m, isoValue);
747 }
else if (
typeid(*fHist) ==
typeid(TH3D)) {
748 Rgl::Mc::TMeshBuilder<TH3D, Float_t> builder(kTRUE);
749 builder.BuildMesh(static_cast<TH3D *>(fHist), geom, &m, isoValue);
756 void TGLIsoPainter::DrawMesh(
const Mesh_t &m, Int_t level)
const
759 SetSurfaceColor(level);
761 if (!fBoxCut.IsActive()) {
763 Rgl::DrawMesh(m.fVerts, m.fNorms, m.fTris);
765 Rgl::ObjectIDToColor(fSelectionBase, fHighColor);
766 Rgl::DrawMesh(m.fVerts, m.fTris);
770 Rgl::DrawMesh(m.fVerts, m.fNorms, m.fTris, fBoxCut);
772 Rgl::ObjectIDToColor(fSelectionBase, fHighColor);
773 Rgl::DrawMesh(m.fVerts, m.fTris, fBoxCut);
781 void TGLIsoPainter::FindMinMax()
783 fMinMax.first = fHist->GetBinContent(fXAxis->GetFirst(), fYAxis->GetFirst(), fZAxis->GetFirst());
784 fMinMax.second = fMinMax.first;
786 for (Int_t i = fXAxis->GetFirst(), ei = fXAxis->GetLast(); i <= ei; ++i) {
787 for (Int_t j = fYAxis->GetFirst(), ej = fYAxis->GetLast(); j <= ej; ++j) {
788 for (Int_t k = fZAxis->GetFirst(), ek = fZAxis->GetLast(); k <= ek; ++k) {
789 const Double_t binContent = fHist->GetBinContent(i, j, k);
790 fMinMax.first = TMath::Min(binContent, fMinMax.first);
791 fMinMax.second = TMath::Max(binContent, fMinMax.second);