#include <ctype.h>
#include "KeySymbols.h"
#include "Buttons.h"
#include "TColor.h"
#include "TStyle.h"
#include "TMath.h"
#include "TH1.h"
#include "TH3.h"
#include "TGLOrthoCamera.h"
#include "TGLBoxPainter.h"
#include "TGLIncludes.h"
ClassImp(TGLBoxPainter)
TGLBoxPainter::TGLBoxPainter(TH1 *hist, TGLOrthoCamera *cam, TGLPlotCoordinates *coord, Int_t ctx)
: TGLPlotPainter(hist, cam, coord, ctx, kTRUE, kTRUE, kTRUE),
fXOZSlice("XOZ", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kXOZ),
fYOZSlice("YOZ", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kYOZ),
fXOYSlice("XOY", (TH3 *)hist, coord, &fBackBox, TGLTH3Slice::kXOY),
fType(kBox)
{
}
char *TGLBoxPainter::GetPlotInfo(Int_t, Int_t)
{
fPlotInfo = "";
if (fSelectedPart) {
if (fSelectedPart < fSelectionBase) {
if (fHist->Class())
fPlotInfo += fHist->Class()->GetName();
fPlotInfo += "::";
fPlotInfo += fHist->GetName();
} else if (!fHighColor){
const Int_t arr2Dsize = fCoord->GetNYBins() * fCoord->GetNZBins();
const Int_t binI = (fSelectedPart - fSelectionBase) / arr2Dsize + fCoord->GetFirstXBin();
const Int_t binJ = (fSelectedPart - fSelectionBase) % arr2Dsize / fCoord->GetNZBins() + fCoord->GetFirstYBin();
const Int_t binK = (fSelectedPart - fSelectionBase) % arr2Dsize % fCoord->GetNZBins() + fCoord->GetFirstZBin();
fPlotInfo.Form("(binx = %d; biny = %d; binz = %d; binc = %f)", binI, binJ, binK,
fHist->GetBinContent(binI, binJ, binK));
} else
fPlotInfo = "Switch to true color mode to get correct info";
}
return (Char_t *)fPlotInfo.Data();
}
Bool_t TGLBoxPainter::InitGeometry()
{
fCoord->SetZLog(kFALSE);
fCoord->SetYLog(kFALSE);
fCoord->SetXLog(kFALSE);
if (!fCoord->SetRanges(fHist, kFALSE, kTRUE))
return kFALSE;
fBackBox.SetPlotBox(fCoord->GetXRangeScaled(), fCoord->GetYRangeScaled(), fCoord->GetZRangeScaled());
fCamera->SetViewVolume(fBackBox.Get3DBox());
fMinMaxVal.second = fHist->GetBinContent(fCoord->GetFirstXBin(), fCoord->GetFirstYBin(), fCoord->GetFirstZBin());
fMinMaxVal.first = 0.;
for (Int_t ir = fCoord->GetFirstXBin(); ir <= fCoord->GetLastXBin(); ++ir)
for (Int_t jr = fCoord->GetFirstYBin(); jr <= fCoord->GetLastYBin(); ++jr)
for (Int_t kr = fCoord->GetFirstZBin(); kr <= fCoord->GetLastZBin(); ++kr)
fMinMaxVal.second = TMath::Max(fMinMaxVal.second, fHist->GetBinContent(ir, jr, kr));
if (!fMinMaxVal.second)
fMinMaxVal.second = 1.;
if (fCoord->Modified()) {
fUpdateSelection = kTRUE;
fXOZSectionPos = fBackBox.Get3DBox()[0].Y();
fYOZSectionPos = fBackBox.Get3DBox()[0].X();
fXOYSectionPos = fBackBox.Get3DBox()[0].Z();
fCoord->ResetModified();
}
return kTRUE;
}
void TGLBoxPainter::StartPan(Int_t px, Int_t py)
{
fMousePosition.fX = px;
fMousePosition.fY = fCamera->GetHeight() - py;
fCamera->StartPan(px, py);
fBoxCut.StartMovement(px, fCamera->GetHeight() - py);
}
void TGLBoxPainter::Pan(Int_t px, Int_t py)
{
if (!MakeGLContextCurrent())
return;
if (fSelectedPart >= fSelectionBase)
fCamera->Pan(px, py);
else if (fSelectedPart > 0) {
py = fCamera->GetHeight() - py;
if (!fHighColor) {
if (fBoxCut.IsActive() && (fSelectedPart >= kXAxis && fSelectedPart <= kZAxis))
fBoxCut.MoveBox(px, py, fSelectedPart);
else
MoveSection(px, py);
} else {
MoveSection(px, py);
}
}
fMousePosition.fX = px, fMousePosition.fY = py;
fUpdateSelection = kTRUE;
}
void TGLBoxPainter::AddOption(const TString &option)
{
const Ssiz_t boxPos = option.Index("box");
if (boxPos + 3 < option.Length() && isdigit(option[boxPos + 3]))
option[boxPos + 3] - '0' == 1 ? fType = kBox1 : fType = kBox;
else
fType = kBox;
}
void TGLBoxPainter::ProcessEvent(Int_t event, Int_t , Int_t py)
{
if (event == kButton1Double && (HasSections() || fBoxCut.IsActive())) {
fXOZSectionPos = fBackBox.Get3DBox()[0].Y();
fYOZSectionPos = fBackBox.Get3DBox()[0].X();
fXOYSectionPos = fBackBox.Get3DBox()[0].Z();
if (fBoxCut.IsActive())
fBoxCut.TurnOnOff();
gGLManager->PaintSingleObject(this);
} else if (event == kKeyPress && (py == kKey_c || py == kKey_C)) {
if (fHighColor)
Info("ProcessEvent", "Switch to true color mode to use box cut");
else {
fBoxCut.TurnOnOff();
fUpdateSelection = kTRUE;
}
}
}
void TGLBoxPainter::InitGL()const
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
}
void TGLBoxPainter::DrawPlot()const
{
fBackBox.DrawBox(fSelectedPart, fSelectionPass, fZLevels, fHighColor);
glDisable(GL_CULL_FACE);
DrawSections();
glEnable(GL_CULL_FACE);
if (!fSelectionPass) {
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1.f, 1.f);
SetPlotColor();
if (HasSections()) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
}
const Int_t frontPoint = fBackBox.GetFrontPoint();
Int_t irInit = fCoord->GetFirstXBin(), iInit = 0;
const Int_t nX = fCoord->GetNXBins();
Int_t jrInit = fCoord->GetFirstYBin(), jInit = 0;
const Int_t nY = fCoord->GetNYBins();
Int_t krInit = fCoord->GetFirstZBin(), kInit = 0;
const Int_t nZ = fCoord->GetNZBins();
const Int_t addI = frontPoint == 2 || frontPoint == 1 ? 1 : (iInit = nX - 1, irInit = fCoord->GetLastXBin(), -1);
const Int_t addJ = frontPoint == 2 || frontPoint == 3 ? 1 : (jInit = nY - 1, jrInit = fCoord->GetLastYBin(), -1);
const Int_t addK = fBackBox.Get2DBox()[frontPoint + 4].Y() < fBackBox.Get2DBox()[frontPoint].Y() ? 1
: (kInit = nZ - 1, krInit = fCoord->GetLastZBin(),-1);
const Double_t xScale = fCoord->GetXScale();
const Double_t yScale = fCoord->GetYScale();
const Double_t zScale = fCoord->GetZScale();
const TAxis *xA = fXAxis;
const TAxis *yA = fYAxis;
const TAxis *zA = fZAxis;
if (fSelectionPass && fHighColor)
Rgl::ObjectIDToColor(fSelectionBase, fHighColor);
for(Int_t ir = irInit, i = iInit; addI > 0 ? i < nX : i >= 0; ir += addI, i += addI) {
for(Int_t jr = jrInit, j = jInit; addJ > 0 ? j < nY : j >= 0; jr += addJ, j += addJ) {
for(Int_t kr = krInit, k = kInit; addK > 0 ? k < nZ : k >= 0; kr += addK, k += addK) {
Double_t w = fHist->GetBinContent(ir, jr, kr) / fMinMaxVal.second;
if (!w)
continue;
const Double_t xMin = xScale * (xA->GetBinLowEdge(ir) / 2 + xA->GetBinUpEdge(ir) / 2 - w * xA->GetBinWidth(ir) / 2);
const Double_t xMax = xScale * (xA->GetBinLowEdge(ir) / 2 + xA->GetBinUpEdge(ir) / 2 + w * xA->GetBinWidth(ir) / 2);
const Double_t yMin = yScale * (yA->GetBinLowEdge(jr) / 2 + yA->GetBinUpEdge(jr) / 2 - w * yA->GetBinWidth(jr) / 2);
const Double_t yMax = yScale * (yA->GetBinLowEdge(jr) / 2 + yA->GetBinUpEdge(jr) / 2 + w * yA->GetBinWidth(jr) / 2);
const Double_t zMin = zScale * (zA->GetBinLowEdge(kr) / 2 + zA->GetBinUpEdge(kr) / 2 - w * zA->GetBinWidth(kr) / 2);
const Double_t zMax = zScale * (zA->GetBinLowEdge(kr) / 2 + zA->GetBinUpEdge(kr) / 2 + w * zA->GetBinWidth(kr) / 2);
if (fBoxCut.IsActive() && fBoxCut.IsInCut(xMin, xMax, yMin, yMax, zMin, zMax))
continue;
const Int_t binID = fSelectionBase + i * fCoord->GetNZBins() * fCoord->GetNYBins() + j * fCoord->GetNZBins() + k;
if (fSelectionPass && !fHighColor)
Rgl::ObjectIDToColor(binID, fHighColor);
else if(!fHighColor && fSelectedPart == binID)
glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gOrangeEmission);
if (fType == kBox)
Rgl::DrawBoxFront(xMin, xMax, yMin, yMax, zMin, zMax, frontPoint);
else
Rgl::DrawSphere(&fQuadric, xMin, xMax, yMin, yMax, zMin, zMax);
if (!fSelectionPass && !fHighColor && fSelectedPart == binID)
glMaterialfv(GL_FRONT, GL_EMISSION, Rgl::gNullEmission);
}
}
}
if (fBoxCut.IsActive())
fBoxCut.DrawBox(fSelectionPass, fSelectedPart);
if (!fSelectionPass && fType != kBox1) {
glDisable(GL_POLYGON_OFFSET_FILL);
TGLDisableGuard lightGuard(GL_LIGHTING);
glColor4d(0., 0., 0., 0.4);
glPolygonMode(GL_FRONT, GL_LINE);
const TGLEnableGuard blendGuard(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
for(Int_t ir = irInit, i = iInit; addI > 0 ? i < nX : i >= 0; ir += addI, i += addI) {
for(Int_t jr = jrInit, j = jInit; addJ > 0 ? j < nY : j >= 0; jr += addJ, j += addJ) {
for(Int_t kr = krInit, k = kInit; addK > 0 ? k < nZ : k >= 0; kr += addK, k += addK) {
Double_t w = fHist->GetBinContent(ir, jr, kr) / fMinMaxVal.second;
if (!w)
continue;
const Double_t xMin = xScale * (xA->GetBinLowEdge(ir) / 2 + xA->GetBinUpEdge(ir) / 2 - w * xA->GetBinWidth(ir) / 2);
const Double_t xMax = xScale * (xA->GetBinLowEdge(ir) / 2 + xA->GetBinUpEdge(ir) / 2 + w * xA->GetBinWidth(ir) / 2);
const Double_t yMin = yScale * (yA->GetBinLowEdge(jr) / 2 + yA->GetBinUpEdge(jr) / 2 - w * yA->GetBinWidth(jr) / 2);
const Double_t yMax = yScale * (yA->GetBinLowEdge(jr) / 2 + yA->GetBinUpEdge(jr) / 2 + w * yA->GetBinWidth(jr) / 2);
const Double_t zMin = zScale * (zA->GetBinLowEdge(kr) / 2 + zA->GetBinUpEdge(kr) / 2 - w * zA->GetBinWidth(kr) / 2);
const Double_t zMax = zScale * (zA->GetBinLowEdge(kr) / 2 + zA->GetBinUpEdge(kr) / 2 + w * zA->GetBinWidth(kr) / 2);
if (fBoxCut.IsActive() && fBoxCut.IsInCut(xMin, xMax, yMin, yMax, zMin, zMax))
continue;
Rgl::DrawBoxFront(xMin, xMax, yMin, yMax, zMin, zMax, frontPoint);
}
}
}
glPolygonMode(GL_FRONT, GL_FILL);
}
}
void TGLBoxPainter::ClearBuffers()const
{
Float_t rgb[3] = {1.f, 1.f, 1.f};
if (const TColor *color = GetPadColor())
color->GetRGB(rgb[0], rgb[1], rgb[2]);
glClearColor(rgb[0], rgb[1], rgb[2], 1.);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void TGLBoxPainter::SetPlotColor()const
{
Float_t diffColor[] = {0.8f, 0.8f, 0.8f, 0.25f};
if (fHist->GetFillColor() != kWhite)
if (const TColor *c = gROOT->GetColor(fHist->GetFillColor()))
c->GetRGB(diffColor[0], diffColor[1], diffColor[2]);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffColor);
const Float_t specColor[] = {1.f, 1.f, 1.f, 1.f};
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specColor);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.f);
}
void TGLBoxPainter::DrawSectionXOZ()const
{
if (fSelectionPass)
return;
fXOZSlice.DrawSlice(fXOZSectionPos / fCoord->GetYScale());
}
void TGLBoxPainter::DrawSectionYOZ()const
{
if (fSelectionPass)
return;
fYOZSlice.DrawSlice(fYOZSectionPos / fCoord->GetXScale());
}
void TGLBoxPainter::DrawSectionXOY()const
{
if (fSelectionPass)
return;
fXOYSlice.DrawSlice(fXOYSectionPos / fCoord->GetZScale());
}
Bool_t TGLBoxPainter::HasSections()const
{
return fXOZSectionPos > fBackBox.Get3DBox()[0].Y() || fYOZSectionPos> fBackBox.Get3DBox()[0].X() ||
fXOYSectionPos > fBackBox.Get3DBox()[0].Z();
}
ClassImp(TGLTH3Slice)
TGLTH3Slice::TGLTH3Slice(const TString &name, const TH3 *hist, const TGLPlotCoordinates *coord,
const TGLPlotBox *box, ESliceAxis axis)
: TNamed(name, name),
fAxisType(axis),
fAxis(0),
fCoord(coord),
fBox(box),
fSliceWidth(1),
fHist(hist)
{
fAxis = fAxisType == kXOZ ? fHist->GetYaxis() : fAxisType == kYOZ ? fHist->GetXaxis() : fHist->GetZaxis();
}
void TGLTH3Slice::SetSliceWidth(Int_t width)
{
if (width <= 0)
return;
if (fAxis->GetLast() - fAxis->GetFirst() + 1 <= width)
fSliceWidth = fAxis->GetLast() - fAxis->GetFirst() + 1;
else
fSliceWidth = width;
}
void TGLTH3Slice::DrawSlice(Double_t pos)const
{
const Int_t bin = fAxis->FindBin(pos);
if (bin && bin < fAxis->GetNbins() + 1) {
Int_t low = 1, up = 2;
if (bin - fSliceWidth + 1 >= fAxis->GetFirst()) {
low = bin - fSliceWidth + 1;
up = bin + 1;
} else {
low = fAxis->GetFirst();
up = bin + (fSliceWidth - (bin - fAxis->GetFirst() + 1)) + 1;
}
Double_t min = 0., max =0.;
FindMinMax(min, max, low, up);
if (!PreparePalette(min, max))
return;
PrepareTexCoords();
if (fPalette.EnableTexture(GL_REPLACE)) {
const TGLDisableGuard lightGuard(GL_LIGHTING);
DrawSliceTextured(pos);
fPalette.DisableTexture();
}
}
}
void TGLTH3Slice::FindMinMax(Double_t &min, Double_t &max, Int_t low, Int_t up)const
{
min = 0.;
switch (fAxisType) {
case kXOZ:
fTexCoords.resize(fCoord->GetNXBins() * fCoord->GetNZBins());
fTexCoords.SetRowLen(fCoord->GetNXBins());
for (Int_t level = low; level < up; ++ level)
min += fHist->GetBinContent(fCoord->GetFirstXBin(), level, fCoord->GetFirstZBin());
max = min;
for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++it) {
Double_t val = 0.;
for (Int_t level = low; level < up; ++ level)
val += fHist->GetBinContent(i, level, j);
max = TMath::Max(max, val);
min = TMath::Min(min, val);
fTexCoords[jt][it] = val;
}
}
break;
case kYOZ:
fTexCoords.resize(fCoord->GetNYBins() * fCoord->GetNZBins());
fTexCoords.SetRowLen(fCoord->GetNYBins());
for (Int_t level = low; level < up; ++ level)
min += fHist->GetBinContent(level, fCoord->GetFirstYBin(), fCoord->GetFirstZBin());
max = min;
for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j <= ej; ++j, ++jt) {
for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i <= ei; ++i, ++it) {
Double_t val = 0.;
for (Int_t level = low; level < up; ++ level)
val += fHist->GetBinContent(level, i, j);
max = TMath::Max(max, val);
min = TMath::Min(min, val);
fTexCoords[jt][it] = val;
}
}
break;
case kXOY:
fTexCoords.resize(fCoord->GetNXBins() * fCoord->GetNYBins());
fTexCoords.SetRowLen(fCoord->GetNYBins());
for (Int_t level = low; level < up; ++ level)
min += fHist->GetBinContent(fCoord->GetFirstXBin(), fCoord->GetFirstYBin(), level);
max = min;
for (Int_t i = fCoord->GetFirstXBin(), ir = 0, ei = fCoord->GetLastXBin(); i <= ei; ++i, ++ir) {
for (Int_t j = fCoord->GetFirstYBin(), jr = 0, ej = fCoord->GetLastYBin(); j <= ej; ++j, ++jr) {
Double_t val = 0.;
for (Int_t level = low; level < up; ++ level)
val += fHist->GetBinContent(i, j, level);
max = TMath::Max(max, val);
min = TMath::Min(min, val);
fTexCoords[ir][jr] = val;
}
}
break;
}
}
Bool_t TGLTH3Slice::PreparePalette(Double_t min, Double_t max)const
{
UInt_t paletteSize = ((TH1 *)fHist)->GetContour();
if (!paletteSize && !(paletteSize = gStyle->GetNumberContours()))
paletteSize = 20;
return fPalette.GeneratePalette(paletteSize, Rgl::Range_t(min, max));
}
void TGLTH3Slice::PrepareTexCoords()const
{
switch (fAxisType) {
case kXOZ:
for (Int_t j = 0, ej = fCoord->GetNZBins(); j < ej; ++j)
for (Int_t i = 0, ei = fCoord->GetNXBins(); i < ei; ++i)
fTexCoords[j][i] = fPalette.GetTexCoord(fTexCoords[j][i]);
break;
case kYOZ:
for (Int_t j = 0, ej = fCoord->GetNZBins(); j < ej; ++j)
for (Int_t i = 0, ei = fCoord->GetNYBins(); i < ei; ++i)
fTexCoords[j][i] = fPalette.GetTexCoord(fTexCoords[j][i]);
break;
case kXOY:
for (Int_t i = 0, ei = fCoord->GetNXBins(); i < ei; ++i)
for (Int_t j = 0, ej = fCoord->GetNYBins(); j < ej; ++j)
fTexCoords[i][j] = fPalette.GetTexCoord(fTexCoords[i][j]);
break;
}
}
void TGLTH3Slice::DrawSliceTextured(Double_t pos)const
{
const Double_t xScale = fCoord->GetXScale();
const Double_t yScale = fCoord->GetYScale();
const Double_t zScale = fCoord->GetZScale();
const TAxis *xA = fHist->GetXaxis();
const TAxis *yA = fHist->GetYaxis();
const TAxis *zA = fHist->GetZaxis();
switch (fAxisType) {
case kXOZ:
pos *= yScale;
for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j < ej; ++j, ++jt) {
for (Int_t i = fCoord->GetFirstXBin(), it = 0, ei = fCoord->GetLastXBin(); i < ei; ++i, ++it) {
const Double_t xMin = xA->GetBinCenter(i) * xScale;
const Double_t xMax = xA->GetBinCenter(i + 1) * xScale;
const Double_t zMin = zA->GetBinCenter(j) * zScale;
const Double_t zMax = zA->GetBinCenter(j + 1) * zScale;
glBegin(GL_POLYGON);
glTexCoord1d(fTexCoords[jt][it]);
glVertex3d(xMin, pos, zMin);
glTexCoord1d(fTexCoords[jt + 1][it]);
glVertex3d(xMin, pos, zMax);
glTexCoord1d(fTexCoords[jt + 1][it + 1]);
glVertex3d(xMax, pos, zMax);
glTexCoord1d(fTexCoords[jt][it + 1]);
glVertex3d(xMax, pos, zMin);
glEnd();
}
}
break;
case kYOZ:
pos *= xScale;
for (Int_t j = fCoord->GetFirstZBin(), jt = 0, ej = fCoord->GetLastZBin(); j < ej; ++j, ++jt) {
for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i < ei; ++i, ++it) {
const Double_t yMin = yA->GetBinCenter(i) * yScale;
const Double_t yMax = yA->GetBinCenter(i + 1) * yScale;
const Double_t zMin = zA->GetBinCenter(j) * zScale;
const Double_t zMax = zA->GetBinCenter(j + 1) * zScale;
glBegin(GL_POLYGON);
glTexCoord1d(fTexCoords[jt][it]);
glVertex3d(pos, yMin, zMin);
glTexCoord1d(fTexCoords[jt][it + 1]);
glVertex3d(pos, yMax, zMin);
glTexCoord1d(fTexCoords[jt + 1][it + 1]);
glVertex3d(pos, yMax, zMax);
glTexCoord1d(fTexCoords[jt + 1][it]);
glVertex3d(pos, yMin, zMax);
glEnd();
}
}
break;
case kXOY:
pos *= zScale;
for (Int_t j = fCoord->GetFirstXBin(), jt = 0, ej = fCoord->GetLastXBin(); j < ej; ++j, ++jt) {
for (Int_t i = fCoord->GetFirstYBin(), it = 0, ei = fCoord->GetLastYBin(); i < ei; ++i, ++it) {
const Double_t xMin = xA->GetBinCenter(j) * xScale;
const Double_t xMax = xA->GetBinCenter(j + 1) * xScale;
const Double_t yMin = yA->GetBinCenter(i) * yScale;
const Double_t yMax = yA->GetBinCenter(i + 1) * yScale;
glBegin(GL_POLYGON);
glTexCoord1d(fTexCoords[jt + 1][it]);
glVertex3d(xMax, yMin, pos);
glTexCoord1d(fTexCoords[jt + 1][it + 1]);
glVertex3d(xMax, yMax, pos);
glTexCoord1d(fTexCoords[jt][it + 1]);
glVertex3d(xMin, yMax, pos);
glTexCoord1d(fTexCoords[jt][it]);
glVertex3d(xMin, yMin, pos);
glEnd();
}
}
break;
}
}
namespace {
void DrawBoxOutline(Double_t xMin, Double_t xMax, Double_t yMin,
Double_t yMax, Double_t zMin, Double_t zMax)
{
glBegin(GL_LINE_LOOP);
glVertex3d(xMin, yMin, zMin);
glVertex3d(xMax, yMin, zMin);
glVertex3d(xMax, yMax, zMin);
glVertex3d(xMin, yMax, zMin);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3d(xMin, yMin, zMax);
glVertex3d(xMax, yMin, zMax);
glVertex3d(xMax, yMax, zMax);
glVertex3d(xMin, yMax, zMax);
glEnd();
glBegin(GL_LINES);
glVertex3d(xMin, yMin, zMin);
glVertex3d(xMin, yMin, zMax);
glVertex3d(xMax, yMin, zMin);
glVertex3d(xMax, yMin, zMax);
glVertex3d(xMax, yMax, zMin);
glVertex3d(xMax, yMax, zMax);
glVertex3d(xMin, yMax, zMin);
glVertex3d(xMin, yMax, zMax);
glEnd();
}
}
void TGLTH3Slice::DrawSliceFrame(Int_t low, Int_t up)const
{
glColor3d(1., 0., 0.);
const TGLVertex3 *box = fBox->Get3DBox();
switch (fAxisType) {
case kXOZ:
DrawBoxOutline(box[0].X(), box[1].X(),
fAxis->GetBinLowEdge(low) * fCoord->GetYScale(),
fAxis->GetBinUpEdge(up - 1) * fCoord->GetYScale(),
box[0].Z(), box[4].Z());
break;
case kYOZ:
DrawBoxOutline(fAxis->GetBinLowEdge(low) * fCoord->GetXScale(),
fAxis->GetBinUpEdge(up - 1) * fCoord->GetXScale(),
box[0].Y(), box[2].Y(),
box[0].Z(), box[4].Z());
break;
case kXOY:
DrawBoxOutline(box[0].X(), box[1].X(),
box[0].Y(), box[2].Y(),
fAxis->GetBinLowEdge(low) * fCoord->GetZScale(),
fAxis->GetBinUpEdge(up - 1) * fCoord->GetZScale());
break;
}
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.