27#include "TGLIncludes.h"
41 void ReplaceUVNames(
TString &equation)
49 const char c = equation[i];
55 if (
c ==
'u' ||
c ==
'v') {
58 if (i ==
len || (!isalpha(equation[i]) && !isdigit(equation[i]) && equation[i] !=
'_')) {
60 equation[i - 1] =
c ==
'u' ?
'x' : (++vFound,
'y');
64 while (i <
len && (isalpha(equation[i]) || isdigit(equation[i]) || equation[i] ==
'_'))
68 while (i <
len && (isalpha(equation[i]) || isdigit(equation[i]) || equation[i] ==
'_'))
134 Error(
"TGLParametricEquation",
"One of string expressions is empty");
141 ReplaceUVNames(equation);
142 fXEquation = std::make_unique<TF2>(
name +
"xEquation", equation.
Data(), uMin, uMax, vMin, vMax);
151 ReplaceUVNames(equation);
152 fYEquation = std::make_unique<TF2>(
name +
"yEquation", equation.
Data(), uMin, uMax, vMin, vMax);
161 ReplaceUVNames(equation);
162 fZEquation = std::make_unique<TF2>(
name +
"zEquation", equation.
Data(), uMin, uMax, vMin, vMax);
181 Error(
"TGLParametricEquation",
"Function ptr is null");
256 return fPainter->DistancetoPrimitive(px, py);
266 return fPainter->ExecuteEvent(event, px, py);
274 static char mess[] = {
"parametric surface" };
284 fPainter = std::make_unique<TGLHistPainter>(
this);
345 using namespace TMath;
351 min.
X() = Min(min.
X(), newVert.
X());
352 max.X() = Max(max.X(), newVert.
X());
353 min.
Y() = Min(min.
Y(), newVert.
Y());
354 max.Y() = Max(max.Y(), newVert.
Y());
355 min.
Z() = Min(min.
Z(), newVert.
Z());
356 max.Z() = Max(max.Z(), newVert.
Z());
358 fMesh[i][j].fPos = newVert;
365 TH3F hist(
"tmp",
"tmp", 2, -1., 1., 2, -1., 1., 2, -1., 1.);
400 Normal2Plane(ver.
CArr(),
v1.CArr(),
v2.CArr(),
fMesh[i][j].fNormal.Arr());
456 static char mess[] = {
"parametric surface" };
476 gROOT->ProcessLineFast(
Form(
"((TGLPlotPainter *)0x%zx)->Paint()", (
size_t)
this));
482 Info(
"ProcessEvent",
"Switch to true color to use box cut");
505 glEnable(GL_DEPTH_TEST);
506 glEnable(GL_LIGHTING);
508 glDisable(GL_CULL_FACE);
509 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,
GL_TRUE);
517 glDisable(GL_DEPTH_TEST);
518 glDisable(GL_LIGHTING);
519 glDisable(GL_LIGHT0);
520 glDisable(GL_CULL_FACE);
521 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,
GL_FALSE);
535 glEnable(GL_POLYGON_OFFSET_FILL);
536 glPolygonOffset(1.f, 1.f);
549 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()));
550 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()));
551 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()));
552 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()));
553 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()));
554 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()));
560 glNormal3dv(
fMesh[i + 1][j + 1].fNormal.CArr());
562 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
fMesh[i + 1][j + 1].fRGBA);
563 glVertex3dv(
fMesh[i + 1][j + 1].fPos.CArr());
565 glNormal3dv(
fMesh[i][j + 1].fNormal.CArr());
567 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
fMesh[i][j + 1].fRGBA);
568 glVertex3dv(
fMesh[i][j + 1].fPos.CArr());
570 glNormal3dv(
fMesh[i][j].fNormal.CArr());
572 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
fMesh[i][j].fRGBA);
573 glVertex3dv(
fMesh[i][j].fPos.CArr());
575 glNormal3dv(
fMesh[i + 1][j].fNormal.CArr());
577 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
fMesh[i + 1][j].fRGBA);
578 glVertex3dv(
fMesh[i + 1][j].fPos.CArr());
580 glNormal3dv(
fMesh[i + 1][j + 1].fNormal.CArr());
582 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
fMesh[i + 1][j + 1].fRGBA);
583 glVertex3dv(
fMesh[i + 1][j + 1].fPos.CArr());
585 glNormal3dv(
fMesh[i][j].fNormal.CArr());
587 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
fMesh[i][j].fRGBA);
588 glVertex3dv(
fMesh[i][j].fPos.CArr());
595 glDisable(GL_POLYGON_OFFSET_FILL);
600 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
601 glColor4d(0., 0., 0., 0.5);
602 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
609 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()));
610 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()));
611 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()));
612 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()));
613 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()));
614 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()));
620 glVertex3dv(
fMesh[i][j].fPos.CArr());
621 glVertex3dv(
fMesh[i][j + 1].fPos.CArr());
622 glVertex3dv(
fMesh[i + 1][j + 1].fPos.CArr());
623 glVertex3dv(
fMesh[i + 1][j].fPos.CArr());
628 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
683 const Float_t specular[] = {1.f, 1.f, 1.f, 1.f};
684 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
685 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.f);
688 const Float_t outerDiff[] = {0.5f, 0.42f, 0.f, 1.f};
689 glMaterialfv(GL_FRONT, GL_DIFFUSE, outerDiff);
690 const Float_t innerDiff[] = {0.5f, 0.2f, 0.f, 1.f};
691 glMaterialfv(GL_BACK, GL_DIFFUSE, innerDiff);
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
void(* ParametricEquation_t)(TGLVertex3 &, Double_t u, Double_t v)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
void Copy(TObject &axis) const override
Copy axis structure to another axis.
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
void MoveBox(Int_t px, Int_t py, Int_t axisID)
Move box cut along selected direction.
Bool_t IsInCut(Double_t xMin, Double_t xMax, Double_t yMin, Double_t yMax, Double_t zMin, Double_t zMax) const
Check, if box defined by xmin/xmax etc. is in cut.
void DrawBox(Bool_t selectionPass, Int_t selected) const
Draw cut as a semi-transparent box.
void TurnOnOff()
Turn the box cut on/off.
void StartMovement(Int_t px, Int_t py)
Start cut's movement.
A parametric surface is a surface defined by a parametric equation, involving two parameters (u,...
Rgl::Range_t GetVRange() const
[vMin, vMax]
ParametricEquation_t fEquation
Bool_t IsModified() const
Something was changed in parametric equation (or constrained option was changed).
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.
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Check, if parametric surface is under cursor.
char * GetObjectInfo(Int_t px, Int_t py) const override
No object info yet.
Rgl::Range_t GetURange() const
[uMin, uMax]
Bool_t IsConstrained() const
Check is constrained.
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Pass event to painter.
void Paint(Option_t *option) override
Delegate paint.
void EvalVertex(TGLVertex3 &newVertex, Double_t u, Double_t v) const
Calculate vertex.
void SetConstrained(Bool_t c)
Set constrained.
void SetModified(Bool_t m)
Set modified.
TGLParametricPlot(TGLParametricEquation *equation, TGLPlotCamera *camera)
Constructor.
void ProcessEvent(Int_t event, Int_t px, Int_t py) override
Change color/mesh size or switch on/off mesh/box cut.
void InitColors()
Calculate colors for vertices, using one of 20 color themes.
void InitGL() const override
Initialize gl state.
Bool_t InitGeometry() override
Build mesh.
void DrawSectionXOY() const override
No such sections.
void DrawSectionYOZ() const override
No such sections.
void DeInitGL() const override
Initialize gl state.
void SetSurfaceColor() const
Set material properties.
TGLPlotCoordinates fCartesianCoord
char * GetPlotInfo(Int_t px, Int_t py) override
No object info yet.
TGLParametricEquation * fEquation
void AddOption(const TString &option) override
No additional options for parametric surfaces.
TGL2DArray< Vertex_t > fMesh
void StartPan(Int_t px, Int_t py) override
User clicks right mouse button (in a pad).
void DrawPlot() const override
Draw parametric surface.
void DrawSectionXOZ() const override
No such sections.
void Pan(Int_t px, Int_t py) override
User's moving mouse cursor, with middle mouse button pressed (for pad).
void SetPlotBox(const Rgl::Range_t &xRange, const Rgl::Range_t &yRange, const Rgl::Range_t &zRange)
Set up a frame box.
const TGLVertex3 * Get3DBox() const
Get 3D box.
Camera for TGLPlotPainter and sub-classes.
void StartPan(Int_t px, Int_t py)
User clicks somewhere (px, py).
void Apply(Double_t phi, Double_t theta) const
Applies rotations and translations before drawing.
void SetCamera() const
Viewport and projection.
void Pan(Int_t px, Int_t py)
Pan camera.
Int_t GetHeight() const
viewport[3]
void SetViewVolume(const TGLVertex3 *box)
'box' is the TGLPlotPainter's back box's coordinates.
Bool_t SetRanges(const TH1 *hist, Bool_t errors=kFALSE, Bool_t zBins=kFALSE)
Set bin ranges, ranges.
Double_t GetYScale() const
const Rgl::Range_t & GetXRangeScaled() const
Scaled range.
const Rgl::Range_t & GetYRangeScaled() const
Scaled range.
Double_t GetXScale() const
Double_t GetZScale() const
const Rgl::Range_t & GetZRangeScaled() const
Scaled range.
Base class for plot-painters that provide GL rendering of various 2D and 3D histograms,...
void RestoreModelviewMatrix() const
TGLPlotCoordinates * fCoord
void Paint() override
Draw lego/surf/whatever you can.
void SaveProjectionMatrix() const
void SaveModelviewMatrix() const
void RestoreProjectionMatrix() const
3 component (x/y/z) vertex class.
const Double_t * CArr() const
virtual void SetDirectory(TDirectory *dir)
By default, when a histogram is created, it is added to the list of histogram objects in the current ...
3-D histogram with a float per channel (see TH1 documentation)
The TNamed class is the base class for all named ROOT classes.
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
R__ALWAYS_INLINE Bool_t IsZombie() const
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
void ToLower()
Change string to lower-case.
const char * Data() const
void ObjectIDToColor(Int_t objectID, Bool_t highColor)
Object id encoded as rgb triplet.
void GetColor(Float_t v, Float_t vmin, Float_t vmax, Int_t type, Float_t *rgba)
This function creates color for parametric surface's vertex, using its 'u' value.
std::pair< Double_t, Double_t > Range_t
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.