Logo ROOT   6.10/09
Reference Guide
TGLParametric.cxx
Go to the documentation of this file.
1 // @(#)root/gl:$Id$
2 // Author: Timur Pocheptsov 26/01/2007
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 #include <cctype>
12 
13 #ifdef WIN32
14 #define NOMINMAX
15 #endif
16 
17 #include "TVirtualX.h"
18 #include "TString.h"
19 #include "TROOT.h"
20 #include "TH3.h"
21 
22 #include "TGLPlotCamera.h"
23 #include "TGLParametric.h"
24 #include "TGLIncludes.h"
25 #include "TVirtualPad.h"
26 #include "KeySymbols.h"
27 #include "Buttons.h"
28 #include "TString.h"
29 #include "TColor.h"
30 #include "TMath.h"
31 
32 namespace
33 {
34 
35  /////////////////////////////////////////////////////////////////////////////
36  ///User defines equations using names 'u' and 'v' for
37  ///parameters. But TF2 works with 'x' and 'y'. So,
38  ///find 'u' and 'v' (which are not parts of other names)
39  ///and replace them with 'x' and 'y' correspondingly.
40 
41  void ReplaceUVNames(TString &equation)
42  {
43  using namespace std;
44  const Ssiz_t len = equation.Length();
45  //TF2 requires 'y' in formula.
46  //'v' <=> 'y', so if none 'v' was found, I'll append "+0*y" to the equation.
47  Int_t vFound = 0;
48 
49  for (Ssiz_t i = 0; i < len;) {
50  const char c = equation[i];
51  if (!isalpha(c)) {
52  ++i;
53  continue;
54  } else{
55  ++i;
56  if (c == 'u' || c == 'v') {
57  //1. This 'u' or 'v' is the last symbol in a string or
58  //2. After this 'u' or 'v' symbol, which cannot be part of longer name.
59  if (i == len || (!isalpha(equation[i]) && !isdigit(equation[i]) && equation[i] != '_')) {
60  //Replace 'u' with 'x' or 'v' with 'y'.
61  equation[i - 1] = c == 'u' ? 'x' : (++vFound, 'y');
62  } else {
63  //This 'u' or 'v' is the beginning of some longer name.
64  //Skip the remaining part of this name.
65  while (i < len && (isalpha(equation[i]) || isdigit(equation[i]) || equation[i] == '_'))
66  ++i;
67  }
68  } else {
69  while (i < len && (isalpha(equation[i]) || isdigit(equation[i]) || equation[i] == '_'))
70  ++i;
71  }
72  }
73  }
74 
75  if (!vFound)
76  equation += "+0*y";
77  }
78 
79 }
80 
81 /** \class TGLParametricEquation
82 \ingroup opengl
83 A parametric surface is a surface defined by a parametric equation, involving
84 two parameters (u, v):
85 
86 ~~~ {.cpp}
87 S(u, v) = (x(u, v), y(u, v), z(u, v)).
88 ~~~
89 
90 For example, "limpet torus" surface can be defined as:
91 
92 ~~~ {.cpp}
93  x = cos(u) / (sqrt(2) + sin(v))
94  y = sin(u) / (sqrt(2) + sin(v))
95  z = 1 / (sqrt(2) + cos(v)),
96 ~~~
97 
98 where -pi <= u <= pi, -pi <= v <= pi.
99 
100 ~~~ {.cpp}
101  TGLParametricEquation * eq =
102  new TGLParametricEquation("Limpet_torus", "cos(u) / (sqrt(2.) + sin(v))",
103  "sin(u) / (sqrt(2.) + sin(v))",
104  "1 / (sqrt(2) + cos(v))");
105 ~~~
106 
107  `$ROOTSYS/tutorials/gl/glparametric.C` contains more examples.
108 
109  Parametric equations can be specified:
110  - 1. by string expressions, as with TF2, but with 'u' instead of 'x' and
111  'v' instead of 'y'.
112  - 2. by function - see ParametricEquation_t declaration.
113 
114 */
115 
117 
118 ////////////////////////////////////////////////////////////////////////////////
119 ///Surface is defined by three strings.
120 ///ROOT does not use exceptions in ctors,
121 ///so, I have to use MakeZombie to let
122 ///external user know about errors.
123 
124 TGLParametricEquation::TGLParametricEquation(const TString &name, const TString &xFun, const TString &yFun,
125  const TString &zFun, Double_t uMin, Double_t uMax,
126  Double_t vMin, Double_t vMax)
127  : TNamed(name, name),
128  fEquation(0),
129  fURange(uMin, uMax),
130  fVRange(vMin, vMax),
131  fConstrained(kFALSE),
132  fModified(kFALSE)
133 {
134  if (!xFun.Length() || !yFun.Length() || !zFun.Length()) {
135  Error("TGLParametricEquation", "One of string expressions is empty");
136  MakeZombie();
137  return;
138  }
139 
140  TString equation(xFun);
141  equation.ToLower();
142  ReplaceUVNames(equation);
143  fXEquation.reset(new TF2(name + "xEquation", equation.Data(), uMin, uMax, vMin, vMax));
144  //Formula was incorrect.
145  if (fXEquation->IsZombie()) {
146  MakeZombie();
147  return;
148  }
149 
150  equation = yFun;
151  equation.ToLower();
152  ReplaceUVNames(equation);
153  fYEquation.reset(new TF2(name + "yEquation", equation.Data(), uMin, uMax, vMin, vMax));
154  //Formula was incorrect.
155  if (fYEquation->IsZombie()) {
156  MakeZombie();
157  return;
158  }
159 
160  equation = zFun;
161  equation.ToLower();
162  ReplaceUVNames(equation);
163  fZEquation.reset(new TF2(name + "zEquation", equation.Data(), uMin, uMax, vMin, vMax));
164  //Formula was incorrect.
165  if (fZEquation->IsZombie())
166  MakeZombie();
167 }
168 
169 ////////////////////////////////////////////////////////////////////////////////
170 ///Surface defined by user's function (see ParametricEquation_t declaration in TGLParametricEquation.h)
171 
173  Double_t uMin, Double_t uMax, Double_t vMin, Double_t vMax)
174  : TNamed(name, name),
175  fEquation(equation),
176  fURange(uMin, uMax),
177  fVRange(vMin, vMax),
178  fConstrained(kFALSE),
179  fModified(kFALSE)
180 {
181  if (!fEquation) {
182  Error("TGLParametricEquation", "Function ptr is null");
183  MakeZombie();
184  }
185 }
186 
187 ////////////////////////////////////////////////////////////////////////////////
188 ///[uMin, uMax]
189 
191 {
192  return fURange;
193 }
194 
195 ////////////////////////////////////////////////////////////////////////////////
196 ///[vMin, vMax]
197 
199 {
200  return fVRange;
201 }
202 
203 ////////////////////////////////////////////////////////////////////////////////
204 ///Check is constrained.
205 
207 {
208  return fConstrained;
209 }
210 
211 ////////////////////////////////////////////////////////////////////////////////
212 ///Set constrained.
213 
215 {
216  fConstrained = c;
217 }
218 
219 ////////////////////////////////////////////////////////////////////////////////
220 ///Something was changed in parametric equation (or constrained option was changed).
221 
223 {
224  return fModified;
225 }
226 
227 ////////////////////////////////////////////////////////////////////////////////
228 ///Set modified.
229 
231 {
232  fModified = m;
233 }
234 
235 ////////////////////////////////////////////////////////////////////////////////
236 ///Calculate vertex.
237 
239 {
240  if (fEquation)
241  return fEquation(newVertex, u, v);
242 
243  if (IsZombie())
244  return;
245 
246  newVertex.X() = fXEquation->Eval(u, v);
247  newVertex.Y() = fYEquation->Eval(u, v);
248  newVertex.Z() = fZEquation->Eval(u, v);
249 }
250 
251 ////////////////////////////////////////////////////////////////////////////////
252 ///Check, if parametric surface is under cursor.
253 
255 {
256  if (fPainter.get())
257  return fPainter->DistancetoPrimitive(px, py);
258  return 9999;
259 }
260 
261 ////////////////////////////////////////////////////////////////////////////////
262 ///Pass event to painter.
263 
265 {
266  if (fPainter.get())
267  return fPainter->ExecuteEvent(event, px, py);
268 }
269 
270 ////////////////////////////////////////////////////////////////////////////////
271 ///No object info yet.
272 
274 {
275  static char mess[] = { "parametric surface" };
276  return mess;
277 }
278 
279 ////////////////////////////////////////////////////////////////////////////////
280 ///Delegate paint.
281 
283 {
284  if (!fPainter.get())
285  fPainter.reset(new TGLHistPainter(this));
286  fPainter->Paint("dummyoption");
287 }
288 
289 /** \class TGLParametricPlot
290 \ingroup opengl
291 */
292 
294 
295 ////////////////////////////////////////////////////////////////////////////////
296 ///Constructor.
297 
299  TGLPlotCamera *camera)
300  : TGLPlotPainter(camera),
301  fMeshSize(90),
302  fShowMesh(kFALSE),
303  fColorScheme(4),
304  fEquation(eq)
305 {
306  fXAxis = &fCartesianXAxis;
307  fYAxis = &fCartesianYAxis;
308  fZAxis = &fCartesianZAxis;
309 
310  fCoord = &fCartesianCoord;
311 
312  InitGeometry();
313  InitColors();
314 }
315 
316 ////////////////////////////////////////////////////////////////////////////////
317 ///Build mesh. The surface is 'immutable':
318 ///the only reason to rebuild it - the change in size or
319 ///if one of equations contain reference to TF2 function, whose
320 ///parameters were changed.
321 
323 {
324  // const Bool_t constrained = kTRUE;//fEquation->IsConstrained();
325 
326  if (fMeshSize * fMeshSize != (Int_t)fMesh.size() || fEquation->IsModified()) {
327  if (fEquation->IsZombie())
328  return kFALSE;
329 
330  fEquation->SetModified(kFALSE);
331 
332  fMesh.resize(fMeshSize * fMeshSize);
333  fMesh.SetRowLen(fMeshSize);
334 
335  const Rgl::Range_t uRange(fEquation->GetURange());
336  const Rgl::Range_t vRange(fEquation->GetVRange());
337 
338  const Double_t dU = (uRange.second - uRange.first) / (fMeshSize - 1);
339  const Double_t dV = (vRange.second - vRange.first) / (fMeshSize - 1);
340  const Double_t dd = 0.001;
341  Double_t u = uRange.first;
342 
343  TGLVertex3 min;
344  fEquation->EvalVertex(min, uRange.first, vRange.first);
345  TGLVertex3 max(min), newVert, v1, v2;
346  using namespace TMath;
347 
348  for (Int_t i = 0; i < fMeshSize; ++i) {
349  Double_t v = vRange.first;
350  for (Int_t j = 0; j < fMeshSize; ++j) {
351  fEquation->EvalVertex(newVert, u, v);
352  min.X() = Min(min.X(), newVert.X());
353  max.X() = Max(max.X(), newVert.X());
354  min.Y() = Min(min.Y(), newVert.Y());
355  max.Y() = Max(max.Y(), newVert.Y());
356  min.Z() = Min(min.Z(), newVert.Z());
357  max.Z() = Max(max.Z(), newVert.Z());
358 
359  fMesh[i][j].fPos = newVert;
360 
361  v += dV;
362  }
363  u += dU;
364  }
365 
366  TH3F hist("tmp", "tmp", 2, -1., 1., 2, -1., 1., 2, -1., 1.);
367  hist.SetDirectory(0);
368  //TAxis has a lot of attributes, defaults, set by ctor,
369  //are not enough to be correctly painted by TGaxis object.
370  //To simplify their initialization - I use temporary histogram.
371  hist.GetXaxis()->Copy(fCartesianXAxis);
372  hist.GetYaxis()->Copy(fCartesianYAxis);
373  hist.GetZaxis()->Copy(fCartesianZAxis);
374 
375  fCartesianXAxis.Set(fMeshSize, min.X(), max.X());
376  fCartesianXAxis.SetTitle("x");//it's lost when copying from temp. hist.
377  fCartesianYAxis.Set(fMeshSize, min.Y(), max.Y());
378  fCartesianYAxis.SetTitle("y");
379  fCartesianZAxis.Set(fMeshSize, min.Z(), max.Z());
380  fCartesianZAxis.SetTitle("z");
381 
382  if (!fCoord->SetRanges(&fCartesianXAxis, &fCartesianYAxis, &fCartesianZAxis))
383  return kFALSE;
384 
385  for (Int_t i = 0; i < fMeshSize; ++i) {
386  for (Int_t j = 0; j < fMeshSize; ++j) {
387  TGLVertex3 &ver = fMesh[i][j].fPos;
388  ver.X() *= fCoord->GetXScale(), ver.Y() *= fCoord->GetYScale(), ver.Z() *= fCoord->GetZScale();
389  }
390  }
391 
392  u = uRange.first;
393  for (Int_t i = 0; i < fMeshSize; ++i) {
394  Double_t v = vRange.first;
395  for (Int_t j = 0; j < fMeshSize; ++j) {
396  TGLVertex3 &ver = fMesh[i][j].fPos;
397  fEquation->EvalVertex(v1, u + dd, v);
398  fEquation->EvalVertex(v2, u, v + dd);
399  v1.X() *= fCoord->GetXScale(), v1.Y() *= fCoord->GetYScale(), v1.Z() *= fCoord->GetZScale();
400  v2.X() *= fCoord->GetXScale(), v2.Y() *= fCoord->GetYScale(), v2.Z() *= fCoord->GetZScale();
401  Normal2Plane(ver.CArr(), v1.CArr(), v2.CArr(), fMesh[i][j].fNormal.Arr());
402  v += dV;
403  }
404  u += dU;
405  }
406 
407  fBackBox.SetPlotBox(fCoord->GetXRangeScaled(),
408  fCoord->GetYRangeScaled(),
409  fCoord->GetZRangeScaled());
410  if (fCamera) fCamera->SetViewVolume(fBackBox.Get3DBox());
411  }
412 
413  return kTRUE;
414 }
415 
416 ////////////////////////////////////////////////////////////////////////////////
417 ///User clicks right mouse button (in a pad).
418 
420 {
421  fMousePosition.fX = px;
422  fMousePosition.fY = fCamera->GetHeight() - py;
423  fCamera->StartPan(px, py);
424  fBoxCut.StartMovement(px, fCamera->GetHeight() - py);
425 }
426 
427 ////////////////////////////////////////////////////////////////////////////////
428 ///User's moving mouse cursor, with middle mouse button pressed (for pad).
429 ///Calculate 3d shift related to 2d mouse movement.
430 
432 {
433  if (fSelectedPart) {
434  SaveModelviewMatrix();
435  SaveProjectionMatrix();
436 
437  fCamera->SetCamera();
438  fCamera->Apply(fPadPhi, fPadTheta);
439 
440  if (fBoxCut.IsActive() && (fSelectedPart >= kXAxis && fSelectedPart <= kZAxis))
441  fBoxCut.MoveBox(px, fCamera->GetHeight() - py, fSelectedPart);
442  else
443  fCamera->Pan(px, py);
444 
445  RestoreProjectionMatrix();
446  RestoreModelviewMatrix();
447  }
448 
449  fUpdateSelection = kTRUE;//
450 }
451 
452 ////////////////////////////////////////////////////////////////////////////////
453 ///No object info yet.
454 
456 {
457  static char mess[] = { "parametric surface" };
458  return mess;
459 }
460 
461 ////////////////////////////////////////////////////////////////////////////////
462 ///No additional options for parametric surfaces.
463 
464 void TGLParametricPlot::AddOption(const TString &/*option*/)
465 {
466 }
467 
468 ////////////////////////////////////////////////////////////////////////////////
469 ///Change color/mesh size or switch on/off mesh/box cut.
470 ///Left double click - remove box cut.
471 
473 {
474  if (event == kButton1Double && fBoxCut.IsActive()) {
475  fBoxCut.TurnOnOff();
476  if (!gVirtualX->IsCmdThread())
477  gROOT->ProcessLineFast(Form("((TGLPlotPainter *)0x%lx)->Paint()", (ULong_t)this));
478  else
479  Paint();
480  } else if (event == kKeyPress) {
481  if (py == kKey_c || py == kKey_C) {
482  if (fHighColor)
483  Info("ProcessEvent", "Switch to true color to use box cut");
484  else {
485  fBoxCut.TurnOnOff();
486  fUpdateSelection = kTRUE;
487  }
488  } else if (py == kKey_s || py == kKey_S) {
489  fColorScheme == 20 ? fColorScheme = -1 : ++fColorScheme;
490  InitColors();//color scheme was changed! recalculate vertices colors.
491  } else if (py == kKey_w || py == kKey_W) {
492  fShowMesh = !fShowMesh;
493  } else if (py == kKey_l || py == kKey_L) {
494  fMeshSize == kHigh ? fMeshSize = kLow : fMeshSize += 15;
495  InitGeometry();
496  InitColors();
497  }
498  }
499 }
500 
501 ////////////////////////////////////////////////////////////////////////////////
502 ///Initialize gl state.
503 
505 {
506  glEnable(GL_DEPTH_TEST);
507  glEnable(GL_LIGHTING);
508  glEnable(GL_LIGHT0);
509  glDisable(GL_CULL_FACE);
510  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
511 }
512 
513 ////////////////////////////////////////////////////////////////////////////////
514 ///Initialize gl state.
515 
517 {
518  glDisable(GL_DEPTH_TEST);
519  glDisable(GL_LIGHTING);
520  glDisable(GL_LIGHT0);
521  glDisable(GL_CULL_FACE);
522  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
523 }
524 
525 ////////////////////////////////////////////////////////////////////////////////
526 ///Draw parametric surface.
527 
529 {
530  //Shift plot to point of origin.
531  const Rgl::PlotTranslation trGuard(this);
532 
533  if (!fSelectionPass) {
534  SetSurfaceColor();
535  if (fShowMesh) {
536  glEnable(GL_POLYGON_OFFSET_FILL);
537  glPolygonOffset(1.f, 1.f);
538  }
539  } else {
540  Rgl::ObjectIDToColor(fSelectionBase, fHighColor);
541  }
542 
543  glBegin(GL_TRIANGLES);
544 
545  for (Int_t i = 0; i < fMeshSize - 1; ++i) {
546  for (Int_t j = 0; j < fMeshSize - 1; ++j) {
547  if (fBoxCut.IsActive()) {
548  using TMath::Min;
549  using TMath::Max;
550  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()));
551  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()));
552  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()));
553  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()));
554  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()));
555  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()));
556 
557  if (fBoxCut.IsInCut(xMin, xMax, yMin, yMax, zMin, zMax))
558  continue;
559  }
560 
561  glNormal3dv(fMesh[i + 1][j + 1].fNormal.CArr());
562  if(fColorScheme != -1)
563  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, fMesh[i + 1][j + 1].fRGBA);
564  glVertex3dv(fMesh[i + 1][j + 1].fPos.CArr());
565 
566  glNormal3dv(fMesh[i][j + 1].fNormal.CArr());
567  if(fColorScheme != -1)
568  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, fMesh[i][j + 1].fRGBA);
569  glVertex3dv(fMesh[i][j + 1].fPos.CArr());
570 
571  glNormal3dv(fMesh[i][j].fNormal.CArr());
572  if(fColorScheme != -1)
573  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, fMesh[i][j].fRGBA);
574  glVertex3dv(fMesh[i][j].fPos.CArr());
575 
576  glNormal3dv(fMesh[i + 1][j].fNormal.CArr());
577  if(fColorScheme != -1)
578  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, fMesh[i + 1][j].fRGBA);
579  glVertex3dv(fMesh[i + 1][j].fPos.CArr());
580 
581  glNormal3dv(fMesh[i + 1][j + 1].fNormal.CArr());
582  if(fColorScheme != -1)
583  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, fMesh[i + 1][j + 1].fRGBA);
584  glVertex3dv(fMesh[i + 1][j + 1].fPos.CArr());
585 
586  glNormal3dv(fMesh[i][j].fNormal.CArr());
587  if(fColorScheme != -1)
588  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, fMesh[i][j].fRGBA);
589  glVertex3dv(fMesh[i][j].fPos.CArr());
590  }
591  }
592 
593  glEnd();
594 
595  if (!fSelectionPass && fShowMesh) {
596  glDisable(GL_POLYGON_OFFSET_FILL);
597  const TGLDisableGuard lightGuard(GL_LIGHTING);
598  const TGLEnableGuard blendGuard(GL_BLEND);
599  const TGLEnableGuard smoothGuard(GL_LINE_SMOOTH);
600 
601  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
602  glColor4d(0., 0., 0., 0.5);
603  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
604 
605  for (Int_t i = 0; i < fMeshSize - 1; ++i) {
606  for (Int_t j = 0; j < fMeshSize - 1; ++j) {
607  if (fBoxCut.IsActive()) {
608  using TMath::Min;
609  using TMath::Max;
610  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()));
611  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()));
612  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()));
613  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()));
614  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()));
615  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()));
616 
617  if (fBoxCut.IsInCut(xMin, xMax, yMin, yMax, zMin, zMax))
618  continue;
619  }
620  glBegin(GL_POLYGON);
621  glVertex3dv(fMesh[i][j].fPos.CArr());
622  glVertex3dv(fMesh[i][j + 1].fPos.CArr());
623  glVertex3dv(fMesh[i + 1][j + 1].fPos.CArr());
624  glVertex3dv(fMesh[i + 1][j].fPos.CArr());
625  glEnd();
626  }
627  }
628 
629  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
630  }
631 
632  if (fBoxCut.IsActive())
633  fBoxCut.DrawBox(fSelectionPass, fSelectedPart);
634 }
635 
636 ////////////////////////////////////////////////////////////////////////////////
637 ///Calculate colors for vertices,
638 ///using one of 20 color themes.
639 ///-1 simple 'metal' surface.
640 
642 {
643  if (fColorScheme == -1)
644  return;
645 
646  const Rgl::Range_t uRange(fEquation->GetURange());
647 
648  const Float_t dU = Float_t((uRange.second - uRange.first) / (fMeshSize - 1));
649  Float_t u = Float_t(uRange.first);
650 
651  for (Int_t i = 0; i < fMeshSize; ++i) {
652  for (Int_t j = 0; j < fMeshSize; ++j)
653  Rgl::GetColor(u, uRange.first, uRange.second, fColorScheme, fMesh[i][j].fRGBA);
654  u += dU;
655  }
656 }
657 
658 ////////////////////////////////////////////////////////////////////////////////
659 ///No such sections.
660 
662 {
663 }
664 
665 ////////////////////////////////////////////////////////////////////////////////
666 ///No such sections.
667 
669 {
670 }
671 
672 ////////////////////////////////////////////////////////////////////////////////
673 ///No such sections.
674 
676 {
677 }
678 
679 ////////////////////////////////////////////////////////////////////////////////
680 ///Set material properties.
681 
683 {
684  const Float_t specular[] = {1.f, 1.f, 1.f, 1.f};
685  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
686  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.f);
687 
688  if (fColorScheme == -1) {
689  const Float_t outerDiff[] = {0.5f, 0.42f, 0.f, 1.f};
690  glMaterialfv(GL_FRONT, GL_DIFFUSE, outerDiff);
691  const Float_t innerDiff[] = {0.5f, 0.2f, 0.f, 1.f};
692  glMaterialfv(GL_BACK, GL_DIFFUSE, innerDiff);
693  }
694 }
ParametricEquation_t fEquation
Definition: TGLParametric.h:43
Camera for TGLPlotPainter and sub-classes.
Definition: TGLPlotCamera.h:21
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:847
void Pan(Int_t px, Int_t py)
User&#39;s moving mouse cursor, with middle mouse button pressed (for pad).
float Float_t
Definition: RtypesCore.h:53
virtual void SetDirectory(TDirectory *dir)
By default when an histogram is created, it is added to the list of histogram objects in the current ...
Definition: TH1.cxx:8053
tomato 3-D histogram with a float per channel (see TH1 documentation)}
Definition: TH3.h:267
const char Option_t
Definition: RtypesCore.h:62
std::pair< Double_t, Double_t > Range_t
Definition: TGLUtil.h:1193
void DrawSectionXOY() const
No such sections.
Bool_t IsConstrained() const
Check is constrained.
Rgl::Range_t GetURange() const
[uMin, uMax]
#define gROOT
Definition: TROOT.h:375
void SetConstrained(Bool_t c)
Set constrained.
Basic string class.
Definition: TString.h:129
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:168
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
void EvalVertex(TGLVertex3 &newVertex, Double_t u, Double_t v) const
Calculate vertex.
Int_t DistancetoPrimitive(Int_t px, Int_t py)
Check, if parametric surface is under cursor.
virtual void Copy(TObject &axis) const
Copy axis structure to another axis.
Definition: TAxis.cxx:208
STL namespace.
Rgl::Range_t fURange
Definition: TGLParametric.h:45
T * Normal2Plane(const T v1[3], const T v2[3], const T v3[3], T normal[3])
Definition: TMath.h:1181
void DrawSectionYOZ() const
No such sections.
3 component (x/y/z) vertex class.
Definition: TGLUtil.h:82
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
TGLParametricEquation(const TString &name, const TString &xEquation, const TString &yEquation, const TString &zEquation, Double_t uMin, Double_t uMax, Double_t vMin, Double_t vMax)
Surface is defined by three strings.
static const Float_t kHigh
Definition: PDEFoam.cxx:96
void Error(const char *location, const char *msgfmt,...)
Rgl::Range_t GetVRange() const
[vMin, vMax]
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
Definition: TGLUtil.cxx:2858
Bool_t IsModified() const
Something was changed in parametric equation (or constrained option was changed). ...
void SetSurfaceColor() const
Set material properties.
SVector< double, 2 > v
Definition: Dict.h:5
void DrawSectionXOZ() const
No such sections.
void(* ParametricEquation_t)(TGLVertex3 &, Double_t u, Double_t v)
Definition: TGLParametric.h:33
TMarker * m
Definition: textangle.C:8
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:873
char * Form(const char *fmt,...)
Ssiz_t Length() const
Definition: TString.h:388
TAxis * GetYaxis()
Definition: TH1.h:301
A parametric surface is a surface defined by a parametric equation, involving two parameters (u...
Definition: TGLParametric.h:35
A 2-Dim function with parameters.
Definition: TF2.h:29
Base class for plot-painters that provide GL rendering of various 2D and 3D histograms, functions and parametric surfaces.
#define gVirtualX
Definition: TVirtualX.h:350
void ExecuteEvent(Int_t event, Int_t px, Int_t py)
Pass event to painter.
const Bool_t kFALSE
Definition: RtypesCore.h:92
Bool_t InitGeometry()
Build mesh.
int Ssiz_t
Definition: RtypesCore.h:63
Double_t Z() const
Definition: TGLUtil.h:122
Rgl::Range_t fVRange
Definition: TGLParametric.h:46
void InitGL() const
Initialize gl state.
#define ClassImp(name)
Definition: Rtypes.h:336
double f(double x)
Bool_t IsZombie() const
Definition: TObject.h:122
double Double_t
Definition: RtypesCore.h:55
unsigned long ULong_t
Definition: RtypesCore.h:51
void AddOption(const TString &option)
No additional options for parametric surfaces.
TAxis * GetZaxis()
Definition: TH1.h:302
The histogram painter class using OpenGL.
void GetColor(Float_t v, Float_t vmin, Float_t vmax, Int_t type, Float_t *rgba)
This function creates color for parametric surface&#39;s vertex, using its &#39;u&#39; value. ...
Definition: TGLUtil.cxx:3844
void StartPan(Int_t px, Int_t py)
User clicks right mouse button (in a pad).
const Double_t * CArr() const
Definition: TGLUtil.h:125
void Paint(Option_t *option)
Delegate paint.
void SetModified(Bool_t m)
Set modified.
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:200
void MakeZombie()
Definition: TObject.h:49
void DrawPlot() const
Draw parametric surface.
void ProcessEvent(Int_t event, Int_t px, Int_t py)
Change color/mesh size or switch on/off mesh/box cut.
void InitColors()
Calculate colors for vertices, using one of 20 color themes.
Double_t Y() const
Definition: TGLUtil.h:120
const Bool_t kTRUE
Definition: RtypesCore.h:91
char * GetObjectInfo(Int_t px, Int_t py) const
No object info yet.
void DeInitGL() const
Initialize gl state.
TAxis * GetXaxis()
Definition: TH1.h:300
char * GetPlotInfo(Int_t px, Int_t py)
No object info yet.
Double_t X() const
Definition: TGLUtil.h:118