00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <algorithm>
00013
00014 #include "TColor.h"
00015
00016 #include "TGLIncludes.h"
00017 #include "TGLPlotBox.h"
00018
00019
00020
00021
00022
00023
00024 ClassImp(TGLPlotBox)
00025
00026 const Int_t TGLPlotBox::fgFramePlanes[][4] =
00027 {
00028 {0, 4, 5, 1},
00029 {1, 5, 6, 2},
00030 {2, 6, 7, 3},
00031 {0, 3, 7, 4},
00032 {0, 1, 2, 3}
00033 };
00034 const Double_t TGLPlotBox::fgNormals[][3] =
00035 {
00036 { 0., 1., 0.},
00037 {-1., 0., 0.},
00038 { 0.,-1., 0.},
00039 { 1., 0., 0.},
00040 { 0., 0., 1.}
00041 };
00042 const Int_t TGLPlotBox::fgBackPairs[][2] =
00043 {
00044 {2, 1},
00045 {3, 2},
00046 {0, 3},
00047 {1, 0}
00048 };
00049
00050
00051 TGLPlotBox::TGLPlotBox(Bool_t xoy, Bool_t xoz, Bool_t yoz)
00052 : fFrameColor(0),
00053 fXOYSelectable(xoy),
00054 fXOZSelectable(xoz),
00055 fYOZSelectable(yoz),
00056 fSelectablePairs(),
00057 fFrontPoint(0),
00058 fRangeXU(1.),
00059 fRangeYU(1.),
00060 fRangeZU(1.)
00061 {
00062
00063
00064 fSelectablePairs[0][0] = xoz;
00065 fSelectablePairs[0][1] = yoz;
00066
00067 fSelectablePairs[1][0] = yoz;
00068 fSelectablePairs[1][1] = xoz;
00069
00070 fSelectablePairs[2][0] = xoz;
00071 fSelectablePairs[2][1] = yoz;
00072
00073 fSelectablePairs[3][0] = yoz;
00074 fSelectablePairs[3][1] = xoz;
00075 }
00076
00077
00078
00079 TGLPlotBox::~TGLPlotBox()
00080 {
00081
00082 }
00083
00084
00085
00086 void TGLPlotBox::DrawBox(Int_t selected, Bool_t selectionPass, const std::vector<Double_t> &zLevels,
00087 Bool_t highColor)const
00088 {
00089
00090
00091 using namespace Rgl;
00092 TGLDisableGuard depthTest(GL_DEPTH_TEST);
00093 glDepthMask(GL_FALSE);
00094
00095 if (!selectionPass) {
00096 glEnable(GL_BLEND);
00097 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00098 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
00099 glEnable(GL_LINE_SMOOTH);
00100 }
00101
00102
00103 Float_t backColor[] = {0.9f, 0.9f, 0.9f, 0.85f};
00104 if (fFrameColor)
00105 fFrameColor->GetRGB(backColor[0], backColor[1], backColor[2]);
00106
00107 if (!selectionPass) {
00108 glMaterialfv(GL_FRONT, GL_DIFFUSE, backColor);
00109 if (selected == 1) {
00110 fXOYSelectable ?
00111 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gGreenEmission)
00112 :
00113 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gRedEmission);
00114 }
00115 } else
00116 ObjectIDToColor(1, highColor);
00117
00118 DrawQuadFilled(f3DBox[0], f3DBox[1], f3DBox[2], f3DBox[3], TGLVector3(0., 0., 1.));
00119
00120 if (!selectionPass) {
00121 if (selected == 1)
00122 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
00123 else if (selected == 2)
00124 fSelectablePairs[fFrontPoint][0] ?
00125 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gGreenEmission)
00126 :glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gRedEmission);
00127 } else
00128 ObjectIDToColor(2, highColor);
00129
00130 DrawBackPlane(fgBackPairs[fFrontPoint][0], selectionPass, zLevels);
00131
00132 if (!selectionPass) {
00133 if (selected == 2)
00134 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
00135 else if (selected == 3)
00136 fSelectablePairs[fFrontPoint][1] ?
00137 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gGreenEmission)
00138 :glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gRedEmission);
00139 } else
00140 ObjectIDToColor(3, highColor);
00141
00142 DrawBackPlane(fgBackPairs[fFrontPoint][1], selectionPass, zLevels);
00143
00144 glDepthMask(GL_TRUE);
00145 if (!selectionPass) {
00146 if (selected == 3)
00147 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Rgl::gNullEmission);
00148 glDisable(GL_BLEND);
00149 glDisable(GL_LINE_SMOOTH);
00150 }
00151 }
00152
00153
00154
00155 void TGLPlotBox::SetPlotBox(const Rgl::Range_t &x, const Rgl::Range_t &y, const Rgl::Range_t &z)
00156 {
00157
00158
00159 f3DBox[0].Set(x.first, y.first, z.first);
00160 f3DBox[1].Set(x.second, y.first, z.first);
00161 f3DBox[2].Set(x.second, y.second, z.first);
00162 f3DBox[3].Set(x.first, y.second, z.first);
00163 f3DBox[4].Set(x.first, y.first, z.second);
00164 f3DBox[5].Set(x.second, y.first, z.second);
00165 f3DBox[6].Set(x.second, y.second, z.second);
00166 f3DBox[7].Set(x.first, y.second, z.second);
00167 }
00168
00169
00170 void TGLPlotBox::SetPlotBox(const Rgl::Range_t &x, Double_t xr, const Rgl::Range_t &y, Double_t yr,
00171 const Rgl::Range_t &z, Double_t zr)
00172 {
00173
00174 fRangeXU = xr;
00175 fRangeYU = yr;
00176 fRangeZU = zr;
00177
00178 SetPlotBox(x, y, z);
00179 }
00180
00181
00182 void TGLPlotBox::SetFrameColor(const TColor *color)
00183 {
00184
00185
00186 fFrameColor = color;
00187 }
00188
00189 namespace {
00190
00191 bool Compare(const TGLVertex3 &v1, const TGLVertex3 &v2)
00192 {
00193 return v1.Z() < v2.Z();
00194 }
00195
00196 }
00197
00198
00199
00200 Int_t TGLPlotBox::FindFrontPoint()const
00201 {
00202
00203
00204
00205 Double_t mvMatrix[16] = {0.};
00206 glGetDoublev(GL_MODELVIEW_MATRIX, mvMatrix);
00207 Double_t prMatrix[16] = {0.};
00208 glGetDoublev(GL_PROJECTION_MATRIX, prMatrix);
00209 Int_t viewport[4] = {0};
00210 glGetIntegerv(GL_VIEWPORT, viewport);
00211
00212 const Double_t zMin = f3DBox[0].Z();
00213 const Double_t zMax = f3DBox[4].Z();
00214
00215 const Double_t uBox[][2] = {{-fRangeXU / 2., -fRangeYU / 2.},
00216 { fRangeXU / 2., -fRangeYU / 2.},
00217 { fRangeXU / 2., fRangeYU / 2.},
00218 {-fRangeXU / 2., fRangeYU / 2.}};
00219
00220
00221
00222 for (Int_t i = 0; i < 4; ++i) {
00223 gluProject(f3DBox[i].X(), f3DBox[i].Y(), zMin, mvMatrix, prMatrix, viewport,
00224 &f2DBox[i].X(), &f2DBox[i].Y(), &f2DBox[i].Z());
00225 gluProject(f3DBox[i].X(), f3DBox[i].Y(), zMax, mvMatrix, prMatrix, viewport,
00226 &f2DBox[i + 4].X(), &f2DBox[i + 4].Y(), &f2DBox[i + 4].Z());
00227
00228 gluProject(uBox[i][0], uBox[i][1], -0.5, mvMatrix, prMatrix, viewport,
00229 &f2DBoxU[i].X(), &f2DBoxU[i].Y(), &f2DBoxU[i].Z());
00230 gluProject(uBox[i][0], uBox[i][1], 0.5, mvMatrix, prMatrix, viewport,
00231 &f2DBoxU[i + 4].X(), &f2DBoxU[i + 4].Y(), &f2DBoxU[i + 4].Z());
00232 }
00233
00234
00235 return fFrontPoint = std::min_element(f2DBoxU, f2DBoxU + 4, Compare) - f2DBoxU;
00236 }
00237
00238
00239
00240 Int_t TGLPlotBox::GetFrontPoint()const
00241 {
00242
00243
00244 return fFrontPoint;
00245 }
00246
00247
00248
00249 const TGLVertex3 *TGLPlotBox::Get3DBox()const
00250 {
00251
00252
00253 return f3DBox;
00254 }
00255
00256
00257
00258 const TGLVertex3 *TGLPlotBox::Get2DBox()const
00259 {
00260
00261
00262
00263 return f2DBoxU;
00264 }
00265
00266
00267
00268 void TGLPlotBox::DrawBackPlane(Int_t plane, Bool_t selectionPass,
00269 const std::vector<Double_t> &zLevels)const
00270 {
00271
00272 using namespace Rgl;
00273 const Int_t *vertInd = fgFramePlanes[plane];
00274 DrawQuadFilled(f3DBox[vertInd[0]], f3DBox[vertInd[1]], f3DBox[vertInd[2]],
00275 f3DBox[vertInd[3]], fgNormals[plane]);
00276
00277 if (!selectionPass) {
00278 const TGLDisableGuard lightGuard(GL_LIGHTING);
00279 glColor3d(0., 0., 0.);
00280 DrawQuadOutline(f3DBox[vertInd[0]], f3DBox[vertInd[1]],
00281 f3DBox[vertInd[2]], f3DBox[vertInd[3]]);
00282
00283 const TGLEnableGuard stippleGuard(GL_LINE_STIPPLE);
00284 const UShort_t stipple = 0x5555;
00285 glLineStipple(1, stipple);
00286
00287 Double_t lineCaps[][4] =
00288 {
00289 {f3DBox[1].X(), f3DBox[0].Y(), f3DBox[0].X(), f3DBox[0].Y()},
00290 {f3DBox[1].X(), f3DBox[0].Y(), f3DBox[1].X(), f3DBox[2].Y()},
00291 {f3DBox[1].X(), f3DBox[2].Y(), f3DBox[0].X(), f3DBox[3].Y()},
00292 {f3DBox[0].X(), f3DBox[3].Y(), f3DBox[0].X(), f3DBox[0].Y()}
00293 };
00294
00295 for (UInt_t i = 0; i < zLevels.size(); ++i) {
00296 glBegin(GL_LINES);
00297 glVertex3d(lineCaps[plane][0], lineCaps[plane][1], zLevels[i]);
00298 glVertex3d(lineCaps[plane][2], lineCaps[plane][3], zLevels[i]);
00299 glEnd();
00300 }
00301
00302 }
00303 }