23 ClassImp(TGLVoxelPainter);
29 TGLVoxelPainter::TGLVoxelPainter(TH1 *hist, TGLPlotCamera *cam, TGLPlotCoordinates *coord)
30 : TGLPlotPainter(hist, cam, coord, kFALSE, kFALSE, kFALSE),
40 char *TGLVoxelPainter::GetPlotInfo(Int_t, Int_t)
45 if (fSelectedPart < fSelectionBase) {
47 fPlotInfo += fHist->Class()->GetName();
49 fPlotInfo += fHist->GetName();
50 }
else if (!fHighColor){
51 const Int_t arr2Dsize = fCoord->GetNYBins() * fCoord->GetNZBins();
52 const Int_t binI = (fSelectedPart - fSelectionBase) / arr2Dsize + fCoord->GetFirstXBin();
53 const Int_t binJ = (fSelectedPart - fSelectionBase) % arr2Dsize / fCoord->GetNZBins() + fCoord->GetFirstYBin();
54 const Int_t binK = (fSelectedPart - fSelectionBase) % arr2Dsize % fCoord->GetNZBins() + fCoord->GetFirstZBin();
56 fPlotInfo.Form(
"(binx = %d; biny = %d; binz = %d; binc = %f)", binI, binJ, binK,
57 fHist->GetBinContent(binI, binJ, binK));
59 fPlotInfo =
"Switch to true color mode to get correct info";
62 return (Char_t *)fPlotInfo.Data();
69 Bool_t TGLVoxelPainter::InitGeometry()
71 fCoord->SetZLog(kFALSE);
72 fCoord->SetYLog(kFALSE);
73 fCoord->SetXLog(kFALSE);
75 if (!fCoord->SetRanges(fHist, kFALSE, kTRUE))
78 fBackBox.SetPlotBox(fCoord->GetXRangeScaled(), fCoord->GetYRangeScaled(), fCoord->GetZRangeScaled());
79 if(fCamera) fCamera->SetViewVolume(fBackBox.Get3DBox());
81 fMinMaxVal.second = fHist->GetBinContent(fCoord->GetFirstXBin(), fCoord->GetFirstYBin(), fCoord->GetFirstZBin());
82 fMinMaxVal.first = fMinMaxVal.second;
84 for (Int_t ir = fCoord->GetFirstXBin(); ir <= fCoord->GetLastXBin(); ++ir) {
85 for (Int_t jr = fCoord->GetFirstYBin(); jr <= fCoord->GetLastYBin(); ++jr) {
86 for (Int_t kr = fCoord->GetFirstZBin(); kr <= fCoord->GetLastZBin(); ++kr) {
87 fMinMaxVal.second = TMath::Max(fMinMaxVal.second, fHist->GetBinContent(ir, jr, kr));
88 fMinMaxVal.first = TMath::Min(fMinMaxVal.first, fHist->GetBinContent(ir, jr, kr));
93 if (fCoord->Modified()) {
94 fUpdateSelection = kTRUE;
95 fXOZSectionPos = fBackBox.Get3DBox()[0].Y();
96 fYOZSectionPos = fBackBox.Get3DBox()[0].X();
97 fXOYSectionPos = fBackBox.Get3DBox()[0].Z();
98 fCoord->ResetModified();
101 const TList *funcList = fHist->GetListOfFunctions();
102 fTransferFunc =
dynamic_cast<TF1*
>(funcList->FindObject(
"TransferFunction"));
111 void TGLVoxelPainter::StartPan(Int_t px, Int_t py)
113 fMousePosition.fX = px;
114 fMousePosition.fY = fCamera->GetHeight() - py;
115 fCamera->StartPan(px, py);
116 fBoxCut.StartMovement(px, fCamera->GetHeight() - py);
124 void TGLVoxelPainter::Pan(Int_t px, Int_t py)
128 if (fSelectedPart >= fSelectionBase) {
129 SaveModelviewMatrix();
130 SaveProjectionMatrix();
132 fCamera->SetCamera();
133 fCamera->Apply(fPadPhi, fPadTheta);
134 fCamera->Pan(px, py);
136 RestoreProjectionMatrix();
137 RestoreModelviewMatrix();
138 }
else if (fSelectedPart > 0) {
141 py = fCamera->GetHeight() - py;
142 SaveModelviewMatrix();
143 SaveProjectionMatrix();
145 fCamera->SetCamera();
146 fCamera->Apply(fPadPhi, fPadTheta);
150 if (fBoxCut.IsActive() && (fSelectedPart >= kXAxis && fSelectedPart <= kZAxis))
151 fBoxCut.MoveBox(px, py, fSelectedPart);
158 RestoreProjectionMatrix();
159 RestoreModelviewMatrix();
162 fMousePosition.fX = px, fMousePosition.fY = py;
163 fUpdateSelection = kTRUE;
170 void TGLVoxelPainter::AddOption(
const TString &option)
172 option.Index(
"z") == kNPOS ? fDrawPalette = kFALSE : fDrawPalette = kTRUE;
179 void TGLVoxelPainter::ProcessEvent(Int_t event, Int_t , Int_t py)
181 if (event == kButton1Double && fBoxCut.IsActive()) {
182 if (fBoxCut.IsActive())
184 if (!gVirtualX->IsCmdThread())
185 gROOT->ProcessLineFast(Form(
"((TGLPlotPainter *)0x%lx)->Paint()", ULong_t(
this)));
188 }
else if (event == kKeyPress && (py == kKey_c || py == kKey_C)) {
190 Info(
"ProcessEvent",
"Switch to true color mode to use box cut");
193 fUpdateSelection = kTRUE;
201 void TGLVoxelPainter::InitGL()
const
203 glEnable(GL_DEPTH_TEST);
204 glEnable(GL_LIGHTING);
207 glEnable(GL_CULL_FACE);
210 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
216 void TGLVoxelPainter::DeInitGL()
const
218 glDisable(GL_DEPTH_TEST);
219 glDisable(GL_LIGHTING);
220 glDisable(GL_LIGHT0);
221 glDisable(GL_CULL_FACE);
222 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
228 void TGLVoxelPainter::DrawPlot()
const
231 const Rgl::PlotTranslation trGuard(
this);
236 fBackBox.DrawBox(fSelectedPart, fSelectionPass, fZLevels, fHighColor);
238 TGLDisableGuard depthTest(GL_DEPTH_TEST);
240 if (!fSelectionPass) {
242 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
247 const Int_t frontPoint = fBackBox.GetFrontPoint();
248 Int_t irInit = fCoord->GetFirstXBin(), iInit = 0;
249 const Int_t nX = fCoord->GetNXBins();
250 Int_t jrInit = fCoord->GetFirstYBin(), jInit = 0;
251 const Int_t nY = fCoord->GetNYBins();
252 Int_t krInit = fCoord->GetFirstZBin(), kInit = 0;
253 const Int_t nZ = fCoord->GetNZBins();
255 const Int_t addI = frontPoint == 2 || frontPoint == 1 ? 1 : (iInit = nX - 1, irInit = fCoord->GetLastXBin(), -1);
256 const Int_t addJ = frontPoint == 2 || frontPoint == 3 ? 1 : (jInit = nY - 1, jrInit = fCoord->GetLastYBin(), -1);
257 const Int_t addK = fBackBox.Get2DBox()[frontPoint + 4].Y() > fBackBox.Get2DBox()[frontPoint].Y() ? 1
258 : (kInit = nZ - 1, krInit = fCoord->GetLastZBin(),-1);
259 const Double_t xScale = fCoord->GetXScale();
260 const Double_t yScale = fCoord->GetYScale();
261 const Double_t zScale = fCoord->GetZScale();
262 const TAxis *xA = fXAxis;
263 const TAxis *yA = fYAxis;
264 const TAxis *zA = fZAxis;
266 if (fSelectionPass && fHighColor)
267 Rgl::ObjectIDToColor(fSelectionBase, fHighColor);
269 Double_t maxContent = TMath::Max(TMath::Abs(fMinMaxVal.first), TMath::Abs(fMinMaxVal.second));
273 Float_t rgba[4] = {};
275 for(Int_t ir = irInit, i = iInit; addI > 0 ? i < nX : i >= 0; ir += addI, i += addI) {
276 for(Int_t jr = jrInit, j = jInit; addJ > 0 ? j < nY : j >= 0; jr += addJ, j += addJ) {
278 for(Int_t kr = krInit, k = kInit; addK > 0 ? k < nZ : k >= 0; kr += addK, k += addK) {
279 const Double_t xMin = xScale * xA->GetBinLowEdge(ir);
280 const Double_t xMax = xScale * xA->GetBinUpEdge(ir);
281 const Double_t yMin = yScale * yA->GetBinLowEdge(jr);
282 const Double_t yMax = yScale * yA->GetBinUpEdge(jr);
283 const Double_t zMin = zScale * zA->GetBinLowEdge(kr);
284 const Double_t zMax = zScale * zA->GetBinUpEdge(kr);
286 if (fBoxCut.IsActive() && fBoxCut.IsInCut(xMin, xMax, yMin, yMax, zMin, zMax))
289 FindVoxelColor(fHist->GetBinContent(ir, jr, kr), rgba);
297 const Int_t binID = fSelectionBase + i * fCoord->GetNZBins() * fCoord->GetNYBins() + j * fCoord->GetNZBins() + k;
299 if (fSelectionPass && !fHighColor)
300 Rgl::ObjectIDToColor(binID, fHighColor);
301 else if(!fHighColor && fSelectedPart == binID)
302 glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gOrangeEmission);
304 Rgl::DrawBoxFront(xMin, xMax, yMin, yMax, zMin, zMax, frontPoint);
306 if (!fSelectionPass && !fHighColor && fSelectedPart == binID)
307 glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gNullEmission);
312 if (fBoxCut.IsActive())
313 fBoxCut.DrawBox(fSelectionPass, fSelectedPart);
315 if (!fSelectionPass) {
325 void TGLVoxelPainter::DrawSectionXOZ()
const
332 void TGLVoxelPainter::DrawSectionYOZ()
const
340 void TGLVoxelPainter::DrawSectionXOY()
const
347 void TGLVoxelPainter::DrawPalette()
const
349 if (!fPalette.GetPaletteSize() || !fCamera)
352 if (!fHist->TestBit(TH1::kUserContour))
353 Rgl::DrawPalette(fCamera, fPalette);
355 Rgl::DrawPalette(fCamera, fPalette, fLevels);
359 fCamera->SetCamera();
360 fCamera->Apply(fPadPhi, fPadTheta);
366 void TGLVoxelPainter::DrawPaletteAxis()
const
369 gVirtualX->SetDrawMode(TVirtualX::kCopy);
370 Rgl::DrawPaletteAxis(fCamera, fMinMaxVal, kFALSE);
377 void TGLVoxelPainter::PreparePalette()
const
379 if(fMinMaxVal.first == fMinMaxVal.second)
383 UInt_t paletteSize = 0;
385 if (fHist->TestBit(TH1::kUserContour)) {
386 if (
const UInt_t trySize = fHist->GetContour()) {
387 fLevels.reserve(trySize);
389 for (UInt_t i = 0; i < trySize; ++i) {
390 const Double_t level = fHist->GetContourLevel(Int_t(i));
391 if (level <= fMinMaxVal.first || level >= fMinMaxVal.second)
393 fLevels.push_back(level);
396 if (fLevels.size()) {
397 std::sort(fLevels.begin(), fLevels.end());
398 fLevels.push_back(fMinMaxVal.second);
399 fLevels.insert(fLevels.begin(), fMinMaxVal.first);
400 fPalette.SetContours(&fLevels);
401 paletteSize = fLevels.size() - 1;
406 fHist->ResetBit(TH1::kUserContour);
409 if (!paletteSize && !(paletteSize = gStyle->GetNumberContours()))
412 fPalette.GeneratePalette(paletteSize, fMinMaxVal);
418 void TGLVoxelPainter::FindVoxelColor(Double_t binContent, Float_t *rgba)
const
420 const UChar_t * tc = fPalette.GetColour(binContent);
425 rgba[3] = fTransferFunc->Eval(binContent);
428 rgba[0] = tc[0] / 255.f;
429 rgba[1] = tc[1] / 255.f;
430 rgba[2] = tc[2] / 255.f;
437 void TGLVoxelPainter::SetVoxelColor(
const Float_t *diffColor)
const
439 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffColor);
440 const Float_t specColor[] = {1.f, 1.f, 1.f, 1.f};
441 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor);
442 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.f);