TGLParametric.cxx

Go to the documentation of this file.
00001 // @(#)root/gl:$Id: TGLParametric.cxx 34286 2010-07-01 20:38:57Z rdm $
00002 // Author:  Timur Pocheptsov  26/01/2007
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #include "Riostream.h"
00013 #include <cctype>
00014 
00015 #ifdef WIN32
00016 #define NOMINMAX
00017 #endif
00018 
00019 #include "TVirtualX.h"
00020 #include "TString.h"
00021 #include "TROOT.h"
00022 
00023 #include "TGLPlotCamera.h"
00024 #include "TGLParametric.h"
00025 #include "TGLIncludes.h"
00026 #include "TVirtualPad.h"
00027 #include "KeySymbols.h"
00028 #include "Buttons.h"
00029 #include "TString.h"
00030 #include "TColor.h"
00031 #include "TMath.h"
00032 
00033 //______________________________________________________________________________
00034 //
00035 // A parametric surface is a surface defined by a parametric equation, involving
00036 // two parameters (u, v):
00037 //
00038 // S(u, v) = (x(u, v), y(u, v), z(u, v)).
00039 // For example, "limpet torus" surface can be defined as:
00040 //    x = cos(u) / (sqrt(2) + sin(v))
00041 //    y = sin(u) / (sqrt(2) + sin(v))
00042 //    z = 1 / (sqrt(2) + cos(v)),
00043 // where -pi <= u <= pi, -pi <= v <= pi.
00044 //
00045 //
00046 // TGLParametricEquation * eq =
00047 //    new TGLParametricEquation("Limpet_torus", "cos(u) / (sqrt(2.) + sin(v))",
00048 //                              "sin(u) / (sqrt(2.) + sin(v))",
00049 //                              "1 / (sqrt(2) + cos(v))");
00050 //
00051 // $ROOTSYS/tutorials/gl/glparametric.C contains more examples.
00052 //
00053 // Parametric equations can be specified:
00054 //    1. by string expressions, as with TF2, but with 'u' instead of 'x' and
00055 //       'v' instead of 'y'.
00056 //    2. by function - see ParametricEquation_t declaration.
00057 
00058 namespace
00059 {
00060 
00061    //______________________________________________________________________________
00062    void ReplaceUVNames(TString &equation)
00063    {
00064       //User defines equations using names 'u' and 'v' for
00065       //parameters. But TF2 works with 'x' and 'y'. So,
00066       //find 'u' and 'v' (which are not parts of other names)
00067       //and replace them with 'x' and 'y' correspondingly.
00068       using namespace std;
00069       const Ssiz_t len = equation.Length();
00070       //TF2 requires 'y' in formula.
00071       //'v' <=> 'y', so if none 'v' was found, I'll append "+0*y" to the equation.
00072       Int_t vFound = 0;
00073 
00074       for (Ssiz_t i = 0; i < len;) {
00075          const char c = equation[i];
00076          if (!isalpha(c)) {
00077             ++i;
00078             continue;
00079          } else{
00080             ++i;
00081             if (c == 'u' || c == 'v') {
00082                //1. This 'u' or 'v' is the last symbol in a string or
00083                //2. After this 'u' or 'v' symbol, which cannot be part of longer name.
00084                if (i == len || (!isalpha(equation[i]) && !isdigit(equation[i]) && equation[i] != '_')) {
00085                   //Replace 'u' with 'x' or 'v' with 'y'.
00086                   equation[i - 1] = c == 'u' ? 'x' : (++vFound, 'y');
00087                } else {
00088                   //This 'u' or 'v' is the beginning of some longer name.
00089                   //Skip the remaining part of this name.
00090                   while (i < len && (isalpha(equation[i]) || isdigit(equation[i]) || equation[i] == '_'))
00091                      ++i;
00092                }
00093             } else {
00094                while (i < len && (isalpha(equation[i]) || isdigit(equation[i]) || equation[i] == '_'))
00095                   ++i;
00096             }
00097          }
00098       }
00099 
00100       if (!vFound)
00101          equation += "+0*y";
00102    }
00103 
00104 }
00105 
00106 ClassImp(TGLParametricEquation)
00107 
00108 //______________________________________________________________________________
00109 TGLParametricEquation::TGLParametricEquation(const TString &name, const TString &xFun, const TString &yFun,
00110                              const TString &zFun, Double_t uMin, Double_t uMax,
00111                              Double_t vMin, Double_t vMax)
00112                   : TNamed(name, name),
00113                     fEquation(0),
00114                     fURange(uMin, uMax),
00115                     fVRange(vMin, vMax),
00116                     fConstrained(kFALSE),
00117                     fModified(kFALSE)
00118 {
00119    //Surface is defined by three strings.
00120    //ROOT does not use exceptions in ctors,
00121    //so, I have to use MakeZombie to let
00122    //external user know about errors.
00123    if (!xFun.Length() || !yFun.Length() || !zFun.Length()) {
00124       Error("TGLParametricEquation", "One of string expressions iz empty");
00125       MakeZombie();
00126       return;
00127    }
00128 
00129    TString equation(xFun);
00130    equation.ToLower();
00131    ReplaceUVNames(equation);
00132    fXEquation.reset(new TF2(name + "xEquation", equation.Data(), uMin, uMax, vMin, vMax));
00133    //Formula was incorrect.
00134    if (fXEquation->IsZombie()) {
00135       MakeZombie();
00136       return;
00137    }
00138 
00139    equation = yFun;
00140    equation.ToLower();
00141    ReplaceUVNames(equation);
00142    fYEquation.reset(new TF2(name + "yEquation", equation.Data(), uMin, uMax, vMin, vMax));
00143    //Formula was incorrect.
00144    if (fYEquation->IsZombie()) {
00145       MakeZombie();
00146       return;
00147    }
00148 
00149    equation = zFun;
00150    equation.ToLower();
00151    ReplaceUVNames(equation);
00152    fZEquation.reset(new TF2(name + "zEquation", equation.Data(), uMin, uMax, vMin, vMax));
00153    //Formula was incorrect.
00154    if (fZEquation->IsZombie())
00155       MakeZombie();
00156 }
00157 
00158 //______________________________________________________________________________
00159 TGLParametricEquation::TGLParametricEquation(const TString &name, ParametricEquation_t equation,
00160                              Double_t uMin, Double_t uMax, Double_t vMin, Double_t vMax)
00161                   : TNamed(name, name),
00162                     fEquation(equation),
00163                     fURange(uMin, uMax),
00164                     fVRange(vMin, vMax),
00165                     fConstrained(kFALSE),
00166                     fModified(kFALSE)
00167 {
00168    //Surface defined by user's function (see ParametricEquation_t declaration in TGLParametricEquation.h)
00169    if (!fEquation) {
00170       Error("TGLParametricEquation", "Function ptr is null");
00171       MakeZombie();
00172    }
00173 }
00174 
00175 //______________________________________________________________________________
00176 Rgl::Range_t TGLParametricEquation::GetURange()const
00177 {
00178    //[uMin, uMax]
00179    return fURange;
00180 }
00181 
00182 //______________________________________________________________________________
00183 Rgl::Range_t TGLParametricEquation::GetVRange()const
00184 {
00185    //[vMin, vMax]
00186    return fVRange;
00187 }
00188 
00189 //______________________________________________________________________________
00190 Bool_t TGLParametricEquation::IsConstrained()const
00191 {
00192    //Check is constrained.
00193    return fConstrained;
00194 }
00195 
00196 //______________________________________________________________________________
00197 void TGLParametricEquation::SetConstrained(Bool_t c)
00198 {
00199    //Set constrained.
00200    fConstrained = c;
00201 }
00202 
00203 //______________________________________________________________________________
00204 Bool_t TGLParametricEquation::IsModified()const
00205 {
00206    //Something was changed in parametric equation (or constrained option was changed).
00207    return fModified;
00208 }
00209 
00210 //______________________________________________________________________________
00211 void TGLParametricEquation::SetModified(Bool_t m)
00212 {
00213    //Set modified.
00214    fModified = m;
00215 }
00216 
00217 //______________________________________________________________________________
00218 void TGLParametricEquation::EvalVertex(TGLVertex3 &newVertex, Double_t u, Double_t v)const
00219 {
00220    //Calculate vertex.
00221    if (fEquation)
00222       return fEquation(newVertex, u, v);
00223 
00224    if (IsZombie())
00225       return;
00226 
00227    newVertex.X() = fXEquation->Eval(u, v);
00228    newVertex.Y() = fYEquation->Eval(u, v);
00229    newVertex.Z() = fZEquation->Eval(u, v);
00230 }
00231 
00232 //______________________________________________________________________________
00233 Int_t TGLParametricEquation::DistancetoPrimitive(Int_t px, Int_t py)
00234 {
00235    //Check, if parametric surface is under cursor.
00236    if (fPainter.get())
00237       return fPainter->DistancetoPrimitive(px, py);
00238    return 9999;
00239 }
00240 
00241 //______________________________________________________________________________
00242 void TGLParametricEquation::ExecuteEvent(Int_t event, Int_t px, Int_t py)
00243 {
00244    //Pass event to painter.
00245    if (fPainter.get())
00246       return fPainter->ExecuteEvent(event, px, py);
00247 }
00248 
00249 //______________________________________________________________________________
00250 char *TGLParametricEquation::GetObjectInfo(Int_t /*px*/, Int_t /*py*/) const
00251 {
00252    //No object info yet.
00253 
00254    static char mess[] = { "parametric surface" };
00255    return mess;
00256 }
00257 
00258 //______________________________________________________________________________
00259 void TGLParametricEquation::Paint(Option_t * /*option*/)
00260 {
00261    //Delegate paint.
00262    if (!fPainter.get())
00263       fPainter.reset(new TGLHistPainter(this));
00264    fPainter->Paint("dummyoption");
00265 }
00266 
00267 ClassImp(TGLParametricPlot)
00268 
00269 //______________________________________________________________________________
00270 TGLParametricPlot::TGLParametricPlot(TGLParametricEquation *eq,
00271                                      TGLPlotCamera *camera)
00272                       : TGLPlotPainter(camera),
00273                         fMeshSize(90),
00274                         fShowMesh(kFALSE),
00275                         fColorScheme(4),
00276                         fEquation(eq)
00277 {
00278    //Constructor.
00279    InitGeometry();
00280    InitColors();
00281 }
00282 
00283 //______________________________________________________________________________
00284 Bool_t TGLParametricPlot::InitGeometry()
00285 {
00286    //Build mesh. The surface is 'immutable':
00287    //the only reason to rebuild it - the change in size or
00288    //if one of equations contain reference to TF2 function, whose
00289    //parameters were changed.
00290 
00291    // const Bool_t constrained = kTRUE;//fEquation->IsConstrained();
00292 
00293    if (fMeshSize * fMeshSize != (Int_t)fMesh.size() || fEquation->IsModified()) {
00294       if (fEquation->IsZombie())
00295          return kFALSE;
00296 
00297       fEquation->SetModified(kFALSE);
00298 
00299       fMesh.resize(fMeshSize * fMeshSize);
00300       fMesh.SetRowLen(fMeshSize);
00301 
00302       const Rgl::Range_t uRange(fEquation->GetURange());
00303       const Rgl::Range_t vRange(fEquation->GetVRange());
00304 
00305       const Double_t dU = (uRange.second - uRange.first) / (fMeshSize - 1);
00306       const Double_t dV = (vRange.second - vRange.first) / (fMeshSize - 1);
00307       const Double_t dd = 0.001;
00308       Double_t u = uRange.first;
00309 
00310       TGLVertex3 min;
00311       fEquation->EvalVertex(min, uRange.first, vRange.first);
00312       TGLVertex3 max(min), newVert, v1, v2;
00313       using namespace TMath;
00314 
00315       for (Int_t i = 0; i < fMeshSize; ++i) {
00316          Double_t v = vRange.first;
00317          for (Int_t j = 0; j < fMeshSize; ++j) {
00318             fEquation->EvalVertex(newVert, u, v);
00319             min.X() = Min(min.X(), newVert.X());
00320             max.X() = Max(max.X(), newVert.X());
00321             min.Y() = Min(min.Y(), newVert.Y());
00322             max.Y() = Max(max.Y(), newVert.Y());
00323             min.Z() = Min(min.Z(), newVert.Z());
00324             max.Z() = Max(max.Z(), newVert.Z());
00325 
00326             fMesh[i][j].fPos = newVert;
00327 
00328             v += dV;
00329          }
00330          u += dU;
00331       }
00332 
00333       const Double_t xRange = max.X() - min.X(), yRange = max.Y() - min.Y(), zRange = max.Z() - min.Z();
00334       const Double_t xS = 1. / xRange, yS = 1. / yRange, zS = 1. / zRange;
00335 
00336       for (Int_t i = 0; i < fMeshSize; ++i) {
00337          for (Int_t j = 0; j < fMeshSize; ++j) {
00338             TGLVertex3 &ver = fMesh[i][j].fPos;
00339             ver.X() *= xS, ver.Y() *= yS, ver.Z() *= zS;
00340          }
00341       }
00342 
00343       if (!xRange || !yRange || !zRange) {
00344          Error("InitGeometry", "Zero axis range");
00345          return kFALSE;
00346       }
00347 
00348       u = uRange.first;
00349       for (Int_t i = 0; i < fMeshSize; ++i) {
00350          Double_t v = vRange.first;
00351          for (Int_t j = 0; j < fMeshSize; ++j) {
00352             TGLVertex3 &ver = fMesh[i][j].fPos;
00353             fEquation->EvalVertex(v1, u + dd, v);
00354             fEquation->EvalVertex(v2, u, v + dd);
00355             v1.X() *= xS, v1.Y() *= yS, v1.Z() *= zS;
00356             v2.X() *= xS, v2.Y() *= yS, v2.Z() *= zS;
00357             Normal2Plane(ver.CArr(), v1.CArr(), v2.CArr(), fMesh[i][j].fNormal.Arr());
00358             v += dV;
00359          }
00360          u += dU;
00361       }
00362 
00363       using Rgl::Range_t;
00364       fBackBox.SetPlotBox(Range_t(min.X() * xS, max.X() * xS),
00365                           Range_t(min.Y() * yS, max.Y() * yS),
00366                           Range_t(min.Z() * zS, max.Z() * zS));
00367       if (fCamera) fCamera->SetViewVolume(fBackBox.Get3DBox());
00368    }
00369 
00370    return kTRUE;
00371 }
00372 
00373 //______________________________________________________________________________
00374 void TGLParametricPlot::StartPan(Int_t px, Int_t py)
00375 {
00376    //User clicks right mouse button (in a pad).
00377    fMousePosition.fX = px;
00378    fMousePosition.fY = fCamera->GetHeight() - py;
00379    fCamera->StartPan(px, py);
00380    fBoxCut.StartMovement(px, fCamera->GetHeight() - py);
00381 }
00382 
00383 //______________________________________________________________________________
00384 void TGLParametricPlot::Pan(Int_t px, Int_t py)
00385 {
00386    //User's moving mouse cursor, with middle mouse button pressed (for pad).
00387    //Calculate 3d shift related to 2d mouse movement.
00388    if (fSelectedPart) {
00389       SaveModelviewMatrix();
00390       SaveProjectionMatrix();
00391 
00392       fCamera->SetCamera();
00393       fCamera->Apply(fPadPhi, fPadTheta);
00394 
00395       if (fBoxCut.IsActive() && (fSelectedPart >= kXAxis && fSelectedPart <= kZAxis))
00396          fBoxCut.MoveBox(px, fCamera->GetHeight() - py, fSelectedPart);
00397       else
00398          fCamera->Pan(px, py);
00399 
00400       RestoreProjectionMatrix();
00401       RestoreModelviewMatrix();
00402    }
00403 
00404    fUpdateSelection = kTRUE;//
00405 }
00406 
00407 //______________________________________________________________________________
00408 char *TGLParametricPlot::GetPlotInfo(Int_t /*px*/, Int_t /*py*/)
00409 {
00410    //No object info yet.
00411 
00412    static char mess[] = { "parametric surface" };
00413    return mess;
00414 }
00415 
00416 //______________________________________________________________________________
00417 void TGLParametricPlot::AddOption(const TString &/*option*/)
00418 {
00419    //No additional options for parametric surfaces.
00420 }
00421 
00422 //______________________________________________________________________________
00423 void TGLParametricPlot::ProcessEvent(Int_t event, Int_t /*px*/, Int_t py)
00424 {
00425    //Change color/mesh size or switch on/off mesh/box cut.
00426    //Left double click - remove box cut.
00427    if (event == kButton1Double && fBoxCut.IsActive()) {
00428       fBoxCut.TurnOnOff();
00429       if (!gVirtualX->IsCmdThread())
00430          gROOT->ProcessLineFast(Form("((TGLPlotPainter *)0x%lx)->Paint()", (ULong_t)this));
00431       else
00432          Paint();
00433    } else if (event == kKeyPress) {
00434       if (py == kKey_c || py == kKey_C) {
00435          if (fHighColor)
00436             Info("ProcessEvent", "Switch to true color to use box cut");
00437          else {
00438             fBoxCut.TurnOnOff();
00439             fUpdateSelection = kTRUE;
00440          }
00441       } else if (py == kKey_s || py == kKey_S) {
00442          fColorScheme == 20 ? fColorScheme = -1 : ++fColorScheme;
00443          InitColors();//color scheme was changed! recalculate vertices colors.
00444       } else if (py == kKey_w || py == kKey_W) {
00445          fShowMesh = !fShowMesh;
00446       } else if (py == kKey_l || py == kKey_L) {
00447          fMeshSize == kHigh ? fMeshSize = kLow : fMeshSize += 15;
00448          InitGeometry();
00449          InitColors();
00450       }
00451    }
00452 }
00453 
00454 //______________________________________________________________________________
00455 void TGLParametricPlot::InitGL()const
00456 {
00457    //Initialize gl state.
00458    glEnable(GL_DEPTH_TEST);
00459    glEnable(GL_LIGHTING);
00460    glEnable(GL_LIGHT0);
00461    glDisable(GL_CULL_FACE);
00462    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
00463 }
00464 
00465 //______________________________________________________________________________
00466 void TGLParametricPlot::DeInitGL()const
00467 {
00468    //Initialize gl state.
00469    glDisable(GL_DEPTH_TEST);
00470    glDisable(GL_LIGHTING);
00471    glDisable(GL_LIGHT0);
00472    glDisable(GL_CULL_FACE);
00473    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
00474 }
00475 
00476 //______________________________________________________________________________
00477 void TGLParametricPlot::DrawPlot()const
00478 {
00479    //Draw parametric surface.
00480 
00481    //Shift plot to point of origin.
00482    const Rgl::PlotTranslation trGuard(this);
00483 
00484    if (!fSelectionPass) {
00485       SetSurfaceColor();
00486       if (fShowMesh) {
00487          glEnable(GL_POLYGON_OFFSET_FILL);
00488          glPolygonOffset(1.f, 1.f);
00489       }
00490    } else {
00491       Rgl::ObjectIDToColor(fSelectionBase, fHighColor);
00492    }
00493 
00494    glBegin(GL_TRIANGLES);
00495 
00496    for (Int_t i = 0; i < fMeshSize - 1; ++i) {
00497       for (Int_t j = 0; j < fMeshSize - 1; ++j) {
00498          if (fBoxCut.IsActive()) {
00499             using TMath::Min;
00500             using TMath::Max;
00501             const Double_t xMin = Min(Min(fMesh[i][j].fPos.X(), fMesh[i + 1][j].fPos.X()), Min(fMesh[i][j + 1].fPos.X(), fMesh[i + 1][j + 1].fPos.X()));
00502             const Double_t xMax = Max(Max(fMesh[i][j].fPos.X(), fMesh[i + 1][j].fPos.X()), Max(fMesh[i][j + 1].fPos.X(), fMesh[i + 1][j + 1].fPos.X()));
00503             const Double_t yMin = Min(Min(fMesh[i][j].fPos.Y(), fMesh[i + 1][j].fPos.Y()), Min(fMesh[i][j + 1].fPos.Y(), fMesh[i + 1][j + 1].fPos.Y()));
00504             const Double_t yMax = Max(Max(fMesh[i][j].fPos.Y(), fMesh[i + 1][j].fPos.Y()), Max(fMesh[i][j + 1].fPos.Y(), fMesh[i + 1][j + 1].fPos.Y()));
00505             const Double_t zMin = Min(Min(fMesh[i][j].fPos.Z(), fMesh[i + 1][j].fPos.Z()), Min(fMesh[i][j + 1].fPos.Z(), fMesh[i + 1][j + 1].fPos.Z()));
00506             const Double_t zMax = Max(Max(fMesh[i][j].fPos.Z(), fMesh[i + 1][j].fPos.Z()), Max(fMesh[i][j + 1].fPos.Z(), fMesh[i + 1][j + 1].fPos.Z()));
00507 
00508             if (fBoxCut.IsInCut(xMin, xMax, yMin, yMax, zMin, zMax))
00509                continue;
00510          }
00511 
00512          glNormal3dv(fMesh[i + 1][j + 1].fNormal.CArr());
00513          if(fColorScheme != -1)
00514             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, fMesh[i + 1][j + 1].fRGBA);
00515          glVertex3dv(fMesh[i + 1][j + 1].fPos.CArr());
00516 
00517          glNormal3dv(fMesh[i][j + 1].fNormal.CArr());
00518          if(fColorScheme != -1)
00519             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, fMesh[i][j + 1].fRGBA);
00520          glVertex3dv(fMesh[i][j + 1].fPos.CArr());
00521 
00522          glNormal3dv(fMesh[i][j].fNormal.CArr());
00523          if(fColorScheme != -1)
00524             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, fMesh[i][j].fRGBA);
00525          glVertex3dv(fMesh[i][j].fPos.CArr());
00526 
00527          glNormal3dv(fMesh[i + 1][j].fNormal.CArr());
00528          if(fColorScheme != -1)
00529             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, fMesh[i + 1][j].fRGBA);
00530          glVertex3dv(fMesh[i + 1][j].fPos.CArr());
00531 
00532          glNormal3dv(fMesh[i + 1][j + 1].fNormal.CArr());
00533          if(fColorScheme != -1)
00534             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, fMesh[i + 1][j + 1].fRGBA);
00535          glVertex3dv(fMesh[i + 1][j + 1].fPos.CArr());
00536 
00537          glNormal3dv(fMesh[i][j].fNormal.CArr());
00538          if(fColorScheme != -1)
00539             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, fMesh[i][j].fRGBA);
00540          glVertex3dv(fMesh[i][j].fPos.CArr());
00541       }
00542    }
00543 
00544    glEnd();
00545 
00546    if (!fSelectionPass && fShowMesh) {
00547       glDisable(GL_POLYGON_OFFSET_FILL);
00548       const TGLDisableGuard lightGuard(GL_LIGHTING);
00549       const TGLEnableGuard blendGuard(GL_BLEND);
00550       const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);
00551 
00552       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00553       glColor4d(0., 0., 0., 0.5);
00554       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00555 
00556       for (Int_t i = 0; i < fMeshSize - 1; ++i) {
00557          for (Int_t j = 0; j < fMeshSize - 1; ++j) {
00558             if (fBoxCut.IsActive()) {
00559                using TMath::Min;
00560                using TMath::Max;
00561                const Double_t xMin = Min(Min(fMesh[i][j].fPos.X(), fMesh[i + 1][j].fPos.X()), Min(fMesh[i][j + 1].fPos.X(), fMesh[i + 1][j + 1].fPos.X()));
00562                const Double_t xMax = Max(Max(fMesh[i][j].fPos.X(), fMesh[i + 1][j].fPos.X()), Max(fMesh[i][j + 1].fPos.X(), fMesh[i + 1][j + 1].fPos.X()));
00563                const Double_t yMin = Min(Min(fMesh[i][j].fPos.Y(), fMesh[i + 1][j].fPos.Y()), Min(fMesh[i][j + 1].fPos.Y(), fMesh[i + 1][j + 1].fPos.Y()));
00564                const Double_t yMax = Max(Max(fMesh[i][j].fPos.Y(), fMesh[i + 1][j].fPos.Y()), Max(fMesh[i][j + 1].fPos.Y(), fMesh[i + 1][j + 1].fPos.Y()));
00565                const Double_t zMin = Min(Min(fMesh[i][j].fPos.Z(), fMesh[i + 1][j].fPos.Z()), Min(fMesh[i][j + 1].fPos.Z(), fMesh[i + 1][j + 1].fPos.Z()));
00566                const Double_t zMax = Max(Max(fMesh[i][j].fPos.Z(), fMesh[i + 1][j].fPos.Z()), Max(fMesh[i][j + 1].fPos.Z(), fMesh[i + 1][j + 1].fPos.Z()));
00567 
00568                if (fBoxCut.IsInCut(xMin, xMax, yMin, yMax, zMin, zMax))
00569                   continue;
00570             }
00571             glBegin(GL_POLYGON);
00572             glVertex3dv(fMesh[i][j].fPos.CArr());
00573             glVertex3dv(fMesh[i][j + 1].fPos.CArr());
00574             glVertex3dv(fMesh[i + 1][j + 1].fPos.CArr());
00575             glVertex3dv(fMesh[i + 1][j].fPos.CArr());
00576             glEnd();
00577          }
00578       }
00579 
00580       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00581    }
00582 
00583    if (fBoxCut.IsActive())
00584       fBoxCut.DrawBox(fSelectionPass, fSelectedPart);
00585 }
00586 
00587 //______________________________________________________________________________
00588 void TGLParametricPlot::InitColors()
00589 {
00590    //Calculate colors for vertices,
00591    //using one of 20 color themes.
00592    //-1 simple 'metal' surface.
00593    if (fColorScheme == -1)
00594       return;
00595 
00596    const Rgl::Range_t uRange(fEquation->GetURange());
00597 
00598    const Float_t dU = Float_t((uRange.second - uRange.first) / (fMeshSize - 1));
00599    Float_t u = Float_t(uRange.first);
00600 
00601    for (Int_t i = 0; i < fMeshSize; ++i) {
00602       for (Int_t j = 0; j < fMeshSize; ++j)
00603          Rgl::GetColor(u, uRange.first, uRange.second, fColorScheme, fMesh[i][j].fRGBA);
00604       u += dU;
00605    }
00606 }
00607 
00608 //______________________________________________________________________________
00609 void TGLParametricPlot::DrawSectionXOZ()const
00610 {
00611    //No such sections.
00612 }
00613 
00614 //______________________________________________________________________________
00615 void TGLParametricPlot::DrawSectionYOZ()const
00616 {
00617    //No such sections.
00618 }
00619 
00620 //______________________________________________________________________________
00621 void TGLParametricPlot::DrawSectionXOY()const
00622 {
00623    //No such sections.
00624 }
00625 
00626 //______________________________________________________________________________
00627 void TGLParametricPlot::SetSurfaceColor()const
00628 {
00629    //Set material properties.
00630    const Float_t specular[] = {1.f, 1.f, 1.f, 1.f};
00631    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
00632    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.f);
00633 
00634    if (fColorScheme == -1) {
00635       const Float_t outerDiff[] = {0.5f, 0.42f, 0.f, 1.f};
00636       glMaterialfv(GL_FRONT, GL_DIFFUSE, outerDiff);
00637       const Float_t innerDiff[] = {0.5f, 0.2f,  0.f, 1.f};
00638       glMaterialfv(GL_BACK,  GL_DIFFUSE, innerDiff);
00639    }
00640 }

Generated on Tue Jul 5 14:18:08 2011 for ROOT_528-00b_version by  doxygen 1.5.1