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] ==
'_'))
133 Error(
"TGLParametricEquation",
"One of string expressions is empty");
140 ReplaceUVNames(equation);
141 fXEquation = std::make_unique<TF2>(
name +
"xEquation", equation.
Data(), uMin, uMax, vMin, vMax);
150 ReplaceUVNames(equation);
151 fYEquation = std::make_unique<TF2>(
name +
"yEquation", equation.
Data(), uMin, uMax, vMin, vMax);
160 ReplaceUVNames(equation);
161 fZEquation = std::make_unique<TF2>(
name +
"zEquation", equation.
Data(), uMin, uMax, vMin, vMax);
180 Error(
"TGLParametricEquation",
"Function ptr is null");
255 return fPainter->DistancetoPrimitive(px, py);
273 static char mess[] = {
"parametric surface" };
283 fPainter = std::make_unique<TGLHistPainter>(
this);
343 using namespace TMath;
349 min.X() = Min(min.X(), newVert.
X());
350 max.X() = Max(max.X(), newVert.
X());
351 min.Y() = Min(min.Y(), newVert.
Y());
352 max.Y() = Max(max.Y(), newVert.
Y());
353 min.Z() = Min(min.Z(), newVert.
Z());
354 max.Z() = Max(max.Z(), newVert.
Z());
356 fMesh[i][j].fPos = newVert;
363 TH3F hist(
"tmp",
"tmp", 2, -1., 1., 2, -1., 1., 2, -1., 1.);
398 Normal2Plane(ver.
CArr(),
v1.CArr(),
v2.CArr(),
fMesh[i][j].fNormal.Arr());
454 static char mess[] = {
"parametric surface" };
474 gROOT->ProcessLineFast(
Form(
"((TGLPlotPainter *)0x%zx)->Paint()", (
size_t)
this));
480 Info(
"ProcessEvent",
"Switch to true color to use box cut");
503 glEnable(GL_DEPTH_TEST);
504 glEnable(GL_LIGHTING);
506 glDisable(GL_CULL_FACE);
507 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
515 glDisable(GL_DEPTH_TEST);
516 glDisable(GL_LIGHTING);
517 glDisable(GL_LIGHT0);
518 glDisable(GL_CULL_FACE);
519 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
533 glEnable(GL_POLYGON_OFFSET_FILL);
534 glPolygonOffset(1.f, 1.f);
540 glBegin(GL_TRIANGLES);
547 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()));
548 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()));
549 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()));
550 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()));
551 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()));
552 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()));
558 glNormal3dv(
fMesh[i + 1][j + 1].fNormal.CArr());
560 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
fMesh[i + 1][j + 1].fRGBA);
561 glVertex3dv(
fMesh[i + 1][j + 1].fPos.CArr());
563 glNormal3dv(
fMesh[i][j + 1].fNormal.CArr());
565 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
fMesh[i][j + 1].fRGBA);
566 glVertex3dv(
fMesh[i][j + 1].fPos.CArr());
568 glNormal3dv(
fMesh[i][j].fNormal.CArr());
570 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
fMesh[i][j].fRGBA);
571 glVertex3dv(
fMesh[i][j].fPos.CArr());
573 glNormal3dv(
fMesh[i + 1][j].fNormal.CArr());
575 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
fMesh[i + 1][j].fRGBA);
576 glVertex3dv(
fMesh[i + 1][j].fPos.CArr());
578 glNormal3dv(
fMesh[i + 1][j + 1].fNormal.CArr());
580 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
fMesh[i + 1][j + 1].fRGBA);
581 glVertex3dv(
fMesh[i + 1][j + 1].fPos.CArr());
583 glNormal3dv(
fMesh[i][j].fNormal.CArr());
585 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
fMesh[i][j].fRGBA);
586 glVertex3dv(
fMesh[i][j].fPos.CArr());
593 glDisable(GL_POLYGON_OFFSET_FILL);
598 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
599 glColor4d(0., 0., 0., 0.5);
600 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
607 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()));
608 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()));
609 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()));
610 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()));
611 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()));
612 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()));
618 glVertex3dv(
fMesh[i][j].fPos.CArr());
619 glVertex3dv(
fMesh[i][j + 1].fPos.CArr());
620 glVertex3dv(
fMesh[i + 1][j + 1].fPos.CArr());
621 glVertex3dv(
fMesh[i + 1][j].fPos.CArr());
626 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
681 const Float_t specular[] = {1.f, 1.f, 1.f, 1.f};
682 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
683 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.f);
686 const Float_t outerDiff[] = {0.5f, 0.42f, 0.f, 1.f};
687 glMaterialfv(GL_FRONT, GL_DIFFUSE, outerDiff);
688 const Float_t innerDiff[] = {0.5f, 0.2f, 0.f, 1.f};
689 glMaterialfv(GL_BACK, GL_DIFFUSE, innerDiff);
int Int_t
Signed integer 4 bytes (int)
int Ssiz_t
String size (currently int)
float Float_t
Float 4 bytes (float)
const char Option_t
Option string (const char)
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.