Skip to content
Snippets Groups Projects
Commit b27a7abf authored by Rene Brun's avatar Rene Brun
Browse files

From Richard:

New files


git-svn-id: http://root.cern.ch/svn/root/trunk@14065 27541ba8-7e3a-0410-8455-c3a389f83636
parent c9ebb21d
No related branches found
No related tags found
No related merge requests found
// @(#)root/gl:$Name: $:$Id: TGLCylinder.h $
// Author: Timur Pocheptsov 03/08/2004
// NOTE: This code moved from obsoleted TGLSceneObject.h / .cxx - see these
// attic files for previous CVS history
/*************************************************************************
* Copyright (C) 1995-2006, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#ifndef ROOT_TGLCylinder
#define ROOT_TGLCylinder
#ifndef ROOT_TGLLogicalShape
#include "TGLLogicalShape.h"
#endif
class TBuffer3DTube;
class TGLCylinder : public TGLLogicalShape
{
private:
Double_t fR1, fR2, fR3, fR4;
Double_t fDz;
Double_t fPhi1, fPhi2;
TGLVector3 fLowPlaneNorm, fHighPlaneNorm;
Bool_t fSegMesh;
protected:
void DirectDraw(const TGLDrawFlags & flags) const;
public:
TGLCylinder(const TBuffer3DTube & buffer);
~TGLCylinder();
// Cylinders support LOD (tesselation quality) adjustment along
// X/Y axes (round the cylinder radius), but not along length (Z)
virtual ELODAxes SupportedLODAxes() const { return ELODAxes(kLODAxesX | kLODAxesY); }
private:
ClassDef(TGLCylinder,0) // a cylinderical logical shape
};
#endif
// @(#)root/gl:$Name: $:$Id: TGLFaceSet.h $
// Author: Timur Pocheptsov 03/08/2004
// NOTE: This code moved from obsoleted TGLSceneObject.h / .cxx - see these
// attic files for previous CVS history
/*************************************************************************
* Copyright (C) 1995-2006, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#ifndef ROOT_TGLFaceSet
#define ROOT_TGLFaceSet
#ifndef ROOT_TGLLogicalShape
#include "TGLLogicalShape.h"
#endif
#ifndef ROOT_CsgOps
#include "CsgOps.h"
#endif
///////////////////////////////////////////////////////////////////////
class TGLFaceSet : public TGLLogicalShape
{
private:
std::vector<Double_t> fVertices;
std::vector<Double_t> fNormals;
std::vector<Int_t> fPolyDesc;
UInt_t fNbPols;
protected:
void DirectDraw(const TGLDrawFlags & flags) const;
public:
TGLFaceSet(const TBuffer3D & buffer);
void SetFromMesh(const RootCsg::TBaseMesh *m);
virtual ELODAxes SupportedLODAxes() const { return kLODAxesNone; }
private:
void GLDrawPolys()const;
Int_t CheckPoints(const Int_t *source, Int_t *dest)const;
static Bool_t Eq(const Double_t *p1, const Double_t *p2);
void CalculateNormals();
ClassDef(TGLFaceSet,0) // a faceset logical shape
};
#endif
// @(#)root/gl:$Name: $:$Id: TGLPolyLine.h $
// Author: Timur Pocheptsov 03/08/2004
// NOTE: This code moved from obsoleted TGLSceneObject.h / .cxx - see these
// attic files for previous CVS history
/*************************************************************************
* Copyright (C) 1995-2006, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#ifndef ROOT_TGLPolyLine
#define ROOT_TGLPolyLine
#ifndef ROOT_TGLLogicalShape
#include "TGLLogicalShape.h"
#endif
#include <vector>
class TBuffer3D;
class TGLPolyLine : public TGLLogicalShape
{
private:
std::vector<Double_t> fVertices;
protected:
void DirectDraw(const TGLDrawFlags & flags) const;
public:
TGLPolyLine(const TBuffer3D & buffer);
virtual ELODAxes SupportedLODAxes() const { return kLODAxesNone; }
ClassDef(TGLPolyLine,0) // a polyline logical shape
};
#endif
// @(#)root/gl:$Name: $:$Id: TGLPolyMarker.h $
// Author: Timur Pocheptsov 03/08/2004
// NOTE: This code moved from obsoleted TGLSceneObject.h / .cxx - see these
// attic files for previous CVS history
/*************************************************************************
* Copyright (C) 1995-2006, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#ifndef ROOT_TGLPolyMarker
#define ROOT_TGLPolyMarker
#ifndef ROOT_TGLLogicalShape
#include "TGLLogicalShape.h"
#endif
#include <vector>
class TBuffer3D;
////////////////////////////////////////////////////////////////////////
class TGLPolyMarker : public TGLLogicalShape
{
private:
std::vector<Double_t> fVertices;
UInt_t fStyle;
protected:
void DirectDraw(const TGLDrawFlags & flags) const;
public:
TGLPolyMarker(const TBuffer3D & buffer);
virtual ELODAxes SupportedLODAxes() const { return kLODAxesNone; }
private:
void DrawStars()const;
ClassDef(TGLPolyMarker,0) // a polymarker logical shape
};
#endif
// @(#)root/gl:$Name: $:$Id: TGLSphere.h $
// Author: Timur Pocheptsov 03/08/2004
// NOTE: This code moved from obsoleted TGLSceneObject.h / .cxx - see these
// attic files for previous CVS history
/*************************************************************************
* Copyright (C) 1995-2006, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#ifndef ROOT_TGLSphere
#define ROOT_TGLSphere
#ifndef ROOT_TGLLogicalShape
#include "TGLLogicalShape.h"
#endif
class TBuffer3DSphere;
/*
#include <utility>
#ifndef ROOT_TObject
#include "TObject.h"
#endif
#ifndef ROOT_Gtypes
#include "Gtypes.h"
#endif
#ifndef ROOT_CsgOps
#include "CsgOps.h"
#endif
#ifndef ROOT_TGLUtil
#include "TGLUtil.h"
#endif
class TBuffer3D;
class TBuffer3DTube;
*/
class TGLSphere : public TGLLogicalShape
{
private:
Double_t fRadius; // Sphere radius
protected:
void DirectDraw(const TGLDrawFlags & flags) const;
public:
TGLSphere(const TBuffer3DSphere &buffer);
virtual ELODAxes SupportedLODAxes() const { return kLODAxesAll; }
ClassDef(TGLSphere,0) // a spherical logical shape
};
#endif
// @(#)root/gl:$Name: $:$Id: TGLCylinder.cxx $
// Author: Timur Pocheptsov 03/08/2004
// NOTE: This code moved from obsoleted TGLSceneObject.h / .cxx - see these
// attic files for previous CVS history
/*************************************************************************
* Copyright (C) 1995-2006, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#include "TGLCylinder.h"
#include "TGLDrawFlags.h"
#include "TGLIncludes.h"
#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"
// For debug tracing
#include "TClass.h"
#include "TError.h"
TGLVector3 gLowNormalDefault(0., 0., -1.);
TGLVector3 gHighNormalDefault(0., 0., 1.);
class TGLMesh {
protected:
// active LOD (level of detail) - quality
UInt_t fLOD;
Double_t fRmin1, fRmax1, fRmin2, fRmax2;
Double_t fDz;
//normals for top and bottom (for cuts)
TGLVector3 fNlow;
TGLVector3 fNhigh;
void GetNormal(const TGLVertex3 &vertex, TGLVector3 &normal)const;
Double_t GetZcoord(Double_t x, Double_t y, Double_t z)const;
const TGLVertex3 &MakeVertex(Double_t x, Double_t y, Double_t z)const;
public:
TGLMesh(UInt_t LOD, Double_t r1, Double_t r2, Double_t r3, Double_t r4, Double_t dz,
const TGLVector3 &l = gLowNormalDefault, const TGLVector3 &h = gHighNormalDefault);
virtual ~TGLMesh() { }
virtual void Draw() const = 0;
};
//segment contains 3 quad strips:
//one for inner and outer sides, two for top and bottom
class TubeSegMesh : public TGLMesh {
private:
// Allocate space for highest quality (LOD) meshes
TGLVertex3 fMesh[(TGLDrawFlags::kLODHigh + 1) * 8 + 8];
TGLVector3 fNorm[(TGLDrawFlags::kLODHigh + 1) * 8 + 8];
public:
TubeSegMesh(UInt_t LOD, Double_t r1, Double_t r2, Double_t r3, Double_t r4, Double_t dz,
Double_t phi1, Double_t phi2, const TGLVector3 &l = gLowNormalDefault,
const TGLVector3 &h = gHighNormalDefault);
void Draw() const;
};
//four quad strips:
//outer, inner, top, bottom
class TubeMesh : public TGLMesh {
private:
// Allocate space for highest quality (LOD) meshes
TGLVertex3 fMesh[(TGLDrawFlags::kLODHigh + 1) * 8];
TGLVector3 fNorm[(TGLDrawFlags::kLODHigh + 1) * 8];
public:
TubeMesh(UInt_t LOD, Double_t r1, Double_t r2, Double_t r3, Double_t r4, Double_t dz,
const TGLVector3 &l = gLowNormalDefault, const TGLVector3 &h = gHighNormalDefault);
void Draw() const;
};
//One quad mesh and 2 triangle funs
class TCylinderMesh : public TGLMesh {
private:
// Allocate space for highest quality (LOD) meshes
TGLVertex3 fMesh[(TGLDrawFlags::kLODHigh + 1) * 4 + 2];
TGLVector3 fNorm[(TGLDrawFlags::kLODHigh + 1) * 4 + 2];
public:
TCylinderMesh(UInt_t LOD, Double_t r1, Double_t r2, Double_t dz,
const TGLVector3 &l = gLowNormalDefault, const TGLVector3 &h = gHighNormalDefault);
void Draw() const;
};
//One quad mesh and 2 triangle fans
class TCylinderSegMesh : public TGLMesh {
private:
// Allocate space for highest quality (LOD) meshes
TGLVertex3 fMesh[(TGLDrawFlags::kLODHigh + 1) * 4 + 10];
TGLVector3 fNorm[(TGLDrawFlags::kLODHigh + 1) * 4 + 10];
public:
TCylinderSegMesh(UInt_t LOD, Double_t r1, Double_t r2, Double_t dz, Double_t phi1, Double_t phi2,
const TGLVector3 &l = gLowNormalDefault, const TGLVector3 &h = gHighNormalDefault);
void Draw() const;
};
//______________________________________________________________________________
TGLMesh::TGLMesh(UInt_t LOD, Double_t r1, Double_t r2, Double_t r3, Double_t r4, Double_t dz,
const TGLVector3 &l, const TGLVector3 &h) :
fLOD(LOD),
fRmin1(r1), fRmax1(r2), fRmin2(r3), fRmax2(r4),
fDz(dz), fNlow(l), fNhigh(h)
{
//
}
//______________________________________________________________________________
void TGLMesh::GetNormal(const TGLVertex3 &v, TGLVector3 &n)const
{
//
Double_t z = (fRmax1 - fRmax2) / (2 * fDz);
Double_t mag = TMath::Sqrt(v[0] * v[0] + v[1] * v[1] + z * z);
n[0] = v[0] / mag;
n[1] = v[1] / mag;
n[2] = z / mag;
}
//______________________________________________________________________________
Double_t TGLMesh::GetZcoord(Double_t x, Double_t y, Double_t z)const
{
//
Double_t newz = 0;
if (z < 0) newz = -fDz - (x * fNlow[0] + y * fNlow[1]) / fNlow[2];
else newz = fDz - (x * fNhigh[0] + y * fNhigh[1]) / fNhigh[2];
return newz;
}
//______________________________________________________________________________
const TGLVertex3 &TGLMesh::MakeVertex(Double_t x, Double_t y, Double_t z)const
{
//
static TGLVertex3 vert(0., 0., 0.);
vert[0] = x;
vert[1] = y;
vert[2] = GetZcoord(x, y, z);
return vert;
}
//______________________________________________________________________________
TubeSegMesh::TubeSegMesh(UInt_t LOD, Double_t r1, Double_t r2, Double_t r3, Double_t r4, Double_t dz,
Double_t phi1, Double_t phi2,
const TGLVector3 &l, const TGLVector3 &h)
:TGLMesh(LOD, r1, r2, r3, r4, dz, l, h), fMesh(), fNorm()
{
//
const Double_t delta = (phi2 - phi1) / LOD;
Double_t currAngle = phi1;
Bool_t even = kTRUE;
Double_t c = TMath::Cos(currAngle);
Double_t s = TMath::Sin(currAngle);
const Int_t topShift = (fLOD + 1) * 4 + 8;
const Int_t botShift = (fLOD + 1) * 6 + 8;
Int_t j = 4 * (fLOD + 1) + 2;
//defining all three strips here, first strip is non-closed here
for (Int_t i = 0, e = (fLOD + 1) * 2; i < e; ++i) {
if (even) {
fMesh[i] = MakeVertex(fRmax2 * c, fRmax2 * s, fDz);
fMesh[j] = MakeVertex(fRmin2 * c, fRmin2 * s, fDz);
fMesh[i + topShift] = MakeVertex(fRmin2 * c, fRmin2 * s, fDz);
fMesh[i + botShift] = MakeVertex(fRmax1 * c, fRmax1 * s, - fDz);
GetNormal(fMesh[j], fNorm[j]);
fNorm[j].Negate();
even = kFALSE;
} else {
fMesh[i] = MakeVertex(fRmax1 * c, fRmax1 * s, - fDz);
fMesh[j + 1] = MakeVertex(fRmin1 * c, fRmin1 * s, -fDz);
fMesh[i + topShift] = MakeVertex(fRmax2 * c, fRmax2 * s, fDz);
fMesh[i + botShift] = MakeVertex(fRmin1 * c, fRmin1 * s, - fDz);
GetNormal(fMesh[j + 1], fNorm[j + 1]);
fNorm[j + 1].Negate();
even = kTRUE;
currAngle += delta;
c = TMath::Cos(currAngle);
s = TMath::Sin(currAngle);
j -= 2;
}
GetNormal(fMesh[i], fNorm[i]);
fNorm[i + topShift] = fNhigh;
fNorm[i + botShift] = fNlow;
}
//closing first strip
Int_t ind = 2 * (fLOD + 1);
TGLVector3 norm(0., 0., 0.);
fMesh[ind] = fMesh[ind - 2];
fMesh[ind + 1] = fMesh[ind - 1];
fMesh[ind + 2] = fMesh[ind + 4];
fMesh[ind + 3] = fMesh[ind + 5];
TMath::Normal2Plane(fMesh[ind].CArr(), fMesh[ind + 1].CArr(), fMesh[ind + 2].CArr(),
norm.Arr());
fNorm[ind] = norm;
fNorm[ind + 1] = norm;
fNorm[ind + 2] = norm;
fNorm[ind + 3] = norm;
ind = topShift - 4;
fMesh[ind] = fMesh[ind - 2];
fMesh[ind + 1] = fMesh[ind - 1];
fMesh[ind + 2] = fMesh[0];
fMesh[ind + 3] = fMesh[1];
TMath::Normal2Plane(fMesh[ind].CArr(), fMesh[ind + 1].CArr(), fMesh[ind + 2].CArr(),
norm.Arr());
fNorm[ind] = norm;
fNorm[ind + 1] = norm;
fNorm[ind + 2] = norm;
fNorm[ind + 3] = norm;
}
//______________________________________________________________________________
void TubeSegMesh::Draw() const
{
//Tube segment is drawn as three quad strips
//1. enabling vertex arrays
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
//2. setting arrays
glVertexPointer(3, GL_DOUBLE, sizeof(TGLVertex3), fMesh[0].CArr());
glNormalPointer(GL_DOUBLE, sizeof(TGLVector3), fNorm[0].CArr());
//3. draw first strip
glDrawArrays(GL_QUAD_STRIP, 0, 4 * (fLOD + 1) + 8);
//4. draw top and bottom strips
glDrawArrays(GL_QUAD_STRIP, 4 * (fLOD + 1) + 8, 2 * (fLOD + 1));
glDrawArrays(GL_QUAD_STRIP, 6 * (fLOD + 1) + 8, 2 * (fLOD + 1));
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
//______________________________________________________________________________
TubeMesh::TubeMesh(UInt_t LOD, Double_t r1, Double_t r2, Double_t r3, Double_t r4, Double_t z,
const TGLVector3 &l, const TGLVector3 &h)
:TGLMesh(LOD, r1, r2, r3, r4, z, l, h), fMesh(), fNorm()
{
//
const Double_t delta = TMath::TwoPi() / fLOD;
Double_t currAngle = 0.;
Bool_t even = kTRUE;
Double_t c = TMath::Cos(currAngle);
Double_t s = TMath::Sin(currAngle);
const Int_t topShift = (fLOD + 1) * 4;
const Int_t botShift = (fLOD + 1) * 6;
Int_t j = 4 * (fLOD + 1) - 2;
//defining all four strips here
for (Int_t i = 0, e = (fLOD + 1) * 2; i < e; ++i) {
if (even) {
fMesh[i] = MakeVertex(fRmax2 * c, fRmax2 * s, fDz);
fMesh[j] = MakeVertex(fRmin2 * c, fRmin2 * s, fDz);
fMesh[i + topShift] = MakeVertex(fRmin2 * c, fRmin2 * s, fDz);
fMesh[i + botShift] = MakeVertex(fRmax1 * c, fRmax1 * s, - fDz);
GetNormal(fMesh[j], fNorm[j]);
fNorm[j].Negate();
even = kFALSE;
} else {
fMesh[i] = MakeVertex(fRmax1 * c, fRmax1 * s, - fDz);
fMesh[j + 1] = MakeVertex(fRmin1 * c, fRmin1 * s, -fDz);
fMesh[i + topShift] = MakeVertex(fRmax2 * c, fRmax2 * s, fDz);
fMesh[i + botShift] = MakeVertex(fRmin1 * c, fRmin1 * s, - fDz);
GetNormal(fMesh[j + 1], fNorm[j + 1]);
fNorm[j + 1].Negate();
even = kTRUE;
currAngle += delta;
c = TMath::Cos(currAngle);
s = TMath::Sin(currAngle);
j -= 2;
}
GetNormal(fMesh[i], fNorm[i]);
fNorm[i + topShift] = fNhigh;
fNorm[i + botShift] = fNlow;
}
}
//______________________________________________________________________________
void TubeMesh::Draw() const
{
//Tube is drawn as four quad strips
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_DOUBLE, sizeof(TGLVertex3), fMesh[0].CArr());
glNormalPointer(GL_DOUBLE, sizeof(TGLVector3), fNorm[0].CArr());
//draw outer and inner strips
glDrawArrays(GL_QUAD_STRIP, 0, 2 * (fLOD + 1));
glDrawArrays(GL_QUAD_STRIP, 2 * (fLOD + 1), 2 * (fLOD + 1));
//draw top and bottom strips
glDrawArrays(GL_QUAD_STRIP, 4 * (fLOD + 1), 2 * (fLOD + 1));
glDrawArrays(GL_QUAD_STRIP, 6 * (fLOD + 1), 2 * (fLOD + 1));
//5. disabling vertex arrays
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
//______________________________________________________________________________
TCylinderMesh::TCylinderMesh(UInt_t LOD, Double_t r1, Double_t r2, Double_t dz,
const TGLVector3 &l, const TGLVector3 &h)
:TGLMesh(LOD, 0., r1, 0., r2, dz, l, h), fMesh(), fNorm()
{
//
const Double_t delta = TMath::TwoPi() / fLOD;
Double_t currAngle = 0.;
Bool_t even = kTRUE;
Double_t c = TMath::Cos(currAngle);
Double_t s = TMath::Sin(currAngle);
//central point of top fan
Int_t topShift = (fLOD + 1) * 2;
fMesh[topShift][0] = fMesh[topShift][1] = 0., fMesh[topShift][2] = fDz;
fNorm[topShift] = fNhigh;
++topShift;
//central point of bottom fun
Int_t botShift = topShift + 2 * (fLOD + 1);
fMesh[botShift][0] = fMesh[botShift][1] = 0., fMesh[botShift][2] = -fDz;
fNorm[botShift] = fNlow;
++botShift;
//defining 1 strip and 2 fans
for (Int_t i = 0, e = (fLOD + 1) * 2, j = 0; i < e; ++i) {
if (even) {
fMesh[i] = MakeVertex(fRmax2 * c, fRmax2 * s, fDz);
fMesh[j + topShift] = MakeVertex(fRmin2 * c, fRmin2 * s, fDz);
fMesh[j + botShift] = MakeVertex(fRmax1 * c, fRmax1 * s, - fDz);
even = kFALSE;
} else {
fMesh[i] = MakeVertex(fRmax1 * c, fRmax1 * s, - fDz);
even = kTRUE;
currAngle += delta;
c = TMath::Cos(currAngle);
s = TMath::Sin(currAngle);
++j;
}
GetNormal(fMesh[i], fNorm[i]);
fNorm[i + topShift] = fNhigh;
fNorm[i + botShift] = fNlow;
}
}
//______________________________________________________________________________
void TCylinderMesh::Draw() const
{
//
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_DOUBLE, sizeof(TGLVertex3), fMesh[0].CArr());
glNormalPointer(GL_DOUBLE, sizeof(TGLVector3), fNorm[0].CArr());
//draw quad strip
glDrawArrays(GL_QUAD_STRIP, 0, 2 * (fLOD + 1));
//draw top and bottom funs
glDrawArrays(GL_TRIANGLE_FAN, 2 * (fLOD + 1), fLOD + 2);
glDrawArrays(GL_TRIANGLE_FAN, 3 * (fLOD + 1) + 1, fLOD + 2);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
//______________________________________________________________________________
TCylinderSegMesh::TCylinderSegMesh(UInt_t LOD, Double_t r1, Double_t r2, Double_t dz, Double_t phi1,
Double_t phi2, const TGLVector3 &l,
const TGLVector3 &h)
:TGLMesh(LOD, 0., r1, 0., r2, dz, l, h), fMesh(), fNorm()
{
//One quad mesh and two fans
Double_t delta = (phi2 - phi1) / fLOD;
Double_t currAngle = phi1;
Bool_t even = kTRUE;
Double_t c = TMath::Cos(currAngle);
Double_t s = TMath::Sin(currAngle);
const TGLVertex3 vTop(0., 0., fDz);
const TGLVertex3 vBot(0., 0., - fDz);
//center of top fan
Int_t topShift = (fLOD + 1) * 2 + 8;
fMesh[topShift] = vTop;
fNorm[topShift] = fNhigh;
++topShift;
//center of bottom fan
Int_t botShift = topShift + fLOD + 1;
fMesh[botShift] = vBot;
fNorm[botShift] = fNlow;
++botShift;
//defining strip and two fans
//strip is not closed here
Int_t i = 0;
for (Int_t e = (fLOD + 1) * 2, j = 0; i < e; ++i) {
if (even) {
fMesh[i] = MakeVertex(fRmax2 * c, fRmax2 * s, fDz);
fMesh[j + topShift] = MakeVertex(fRmax2 * c, fRmax2 * s, fDz);
fMesh[j + botShift] = MakeVertex(fRmax1 * c, fRmax1 * s, - fDz);
even = kFALSE;
fNorm[j + topShift] = fNhigh;
fNorm[j + botShift] = fNlow;
} else {
fMesh[i] = MakeVertex(fRmax1 * c, fRmax1 * s, - fDz);
even = kTRUE;
currAngle += delta;
c = TMath::Cos(currAngle);
s = TMath::Sin(currAngle);
++j;
}
GetNormal(fMesh[i], fNorm[i]);
}
//closing first strip
Int_t ind = 2 * (fLOD + 1);
TGLVector3 norm(0., 0., 0.);
fMesh[ind] = fMesh[ind - 2];
fMesh[ind + 1] = fMesh[ind - 1];
fMesh[ind + 2] = vTop;
fMesh[ind + 3] = vBot;
TMath::Normal2Plane(fMesh[ind].CArr(), fMesh[ind + 1].CArr(), fMesh[ind + 2].CArr(),
norm.Arr());
fNorm[ind] = norm;
fNorm[ind + 1] = norm;
fNorm[ind + 2] = norm;
fNorm[ind + 3] = norm;
ind += 4;
fMesh[ind] = vTop;
fMesh[ind + 1] = vBot;
fMesh[ind + 2] = fMesh[0];
fMesh[ind + 3] = fMesh[1];
TMath::Normal2Plane(fMesh[ind].CArr(), fMesh[ind + 1].CArr(), fMesh[ind + 2].CArr(),
norm.Arr());
fNorm[ind] = norm;
fNorm[ind + 1] = norm;
fNorm[ind + 2] = norm;
fNorm[ind + 3] = norm;
}
//______________________________________________________________________________
void TCylinderSegMesh::Draw() const
{
//Cylinder segment is drawn as one quad strip and
//two triangle fans
//1. enabling vertex arrays
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
//2. setting arrays
glVertexPointer(3, GL_DOUBLE, sizeof(TGLVertex3), fMesh[0].CArr());
glNormalPointer(GL_DOUBLE, sizeof(TGLVector3), fNorm[0].CArr());
//3. draw quad strip
glDrawArrays(GL_QUAD_STRIP, 0, 2 * (fLOD + 1) + 8);
//4. draw top and bottom funs
glDrawArrays(GL_TRIANGLE_FAN, 2 * (fLOD + 1) + 8, fLOD + 2);
// glDrawArrays(GL_TRIANGLE_FAN, 3 * (fLOD + 1) + 9, fLOD + 2);
//5. disabling vertex arrays
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
ClassImp(TGLCylinder)
//______________________________________________________________________________
TGLCylinder::TGLCylinder(const TBuffer3DTube &buffer) :
TGLLogicalShape(buffer)
{
// Copy out relevant parts of buffer - we create and delete mesh
// parts on demand in DirectDraw() and they are DL cached
fR1 = buffer.fRadiusInner;
fR2 = buffer.fRadiusOuter;
fR3 = buffer.fRadiusInner;
fR4 = buffer.fRadiusOuter;
fDz = buffer.fHalfLength;
fLowPlaneNorm = gLowNormalDefault;
fHighPlaneNorm = gHighNormalDefault;
switch (buffer.Type()) {
case TBuffer3DTypes::kTube:
fSegMesh = kFALSE;
break;
case TBuffer3DTypes::kTubeSeg:
case TBuffer3DTypes::kCutTube:
fSegMesh = kTRUE;
const TBuffer3DTubeSeg * segBuffer = dynamic_cast<const TBuffer3DTubeSeg *>(&buffer);
if (!segBuffer) {
Error("TGLCylinder::TGLCylinder", "cannot cast TBuffer3D");
return;
}
fPhi1 = segBuffer->fPhiMin;
fPhi2 = segBuffer->fPhiMax;
if (fPhi2 < fPhi1) fPhi2 += 360.;
fPhi1 *= TMath::DegToRad();
fPhi2 *= TMath::DegToRad();
if (buffer.Type() == TBuffer3DTypes::kCutTube) {
const TBuffer3DCutTube * cutBuffer = dynamic_cast<const TBuffer3DCutTube *>(&buffer);
if (!cutBuffer) {
Error("TGLCylinder::TGLCylinder", "cannot cast TBuffer3D");
return;
}
for (UInt_t i =0; i < 3; i++) {
fLowPlaneNorm[i] = cutBuffer->fLowPlaneNorm[i];
fHighPlaneNorm[i] = cutBuffer->fHighPlaneNorm[i];
}
}
}
}
//______________________________________________________________________________
TGLCylinder::~TGLCylinder()
{
}
//______________________________________________________________________________
void TGLCylinder::DirectDraw(const TGLDrawFlags & flags) const
{
// Debug tracing
if (gDebug > 4) {
Info("TGLCylinder::DirectDraw", "this %d (class %s) LOD %d", this, IsA()->GetName(), flags.LOD());
}
// As we are now support display list caching we can create, draw and
// delete mesh parts of suitible LOD (quality) here - it will be cached
// into a display list by TGLDisplayListCache/TGLDrawable base,
// against our id and the LOD value. So this will only occur once
// for a certain cylinder/LOD combination
std::vector<TGLMesh *> meshParts;
// Create mesh parts
if (!fSegMesh) {
meshParts.push_back(new TubeMesh(flags.LOD(), fR1, fR2, fR3, fR4, fDz, fLowPlaneNorm, fHighPlaneNorm));
} else {
meshParts.push_back(new TubeSegMesh(flags.LOD(), fR1, fR2, fR3, fR4, fDz, fPhi1,
fPhi2, fLowPlaneNorm, fHighPlaneNorm));
}
// Draw mesh parts
for (UInt_t i = 0; i < meshParts.size(); ++i) meshParts[i]->Draw();
// Delete mesh parts
for (UInt_t i = 0; i < meshParts.size(); ++i) {
delete meshParts[i];
meshParts[i] = 0;//not to have invalid pointer for pseudo-destructor call :)
}
}
// @(#)root/gl:$Name: $:$Id: TGLFaceSet.cxx $
// Author: Timur Pocheptsov 03/08/2004
// NOTE: This code moved from obsoleted TGLSceneObject.h / .cxx - see these
// attic files for previous CVS history
/*************************************************************************
* Copyright (C) 1995-2006, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#include "TGLFaceSet.h"
#include "TGLDrawFlags.h"
#include "TGLIncludes.h"
#include "TBuffer3D.h"
// For debug tracing
#include "TClass.h"
#include "TError.h"
static GLUtriangulatorObj *GetTesselator()
{
static struct Init {
Init()
{
#if defined(R__WIN32)
typedef void (CALLBACK *tessfuncptr_t)();
#elif defined(R__AIXGCC)
typedef void (*tessfuncptr_t)(...);
#else
typedef void (*tessfuncptr_t)();
#endif
fTess = gluNewTess();
if (!fTess) {
Error("GetTesselator::Init", "could not create tesselation object");
} else {
gluTessCallback(fTess, (GLenum)GLU_BEGIN, (tessfuncptr_t)glBegin);
gluTessCallback(fTess, (GLenum)GLU_END, (tessfuncptr_t)glEnd);
gluTessCallback(fTess, (GLenum)GLU_VERTEX, (tessfuncptr_t)glVertex3dv);
}
}
~Init()
{
if(fTess)
gluDeleteTess(fTess);
}
GLUtriangulatorObj *fTess;
}singleton;
return singleton.fTess;
}
ClassImp(TGLFaceSet)
//______________________________________________________________________________
TGLFaceSet::TGLFaceSet(const TBuffer3D & buffer) :
TGLLogicalShape(buffer),
fVertices(buffer.fPnts, buffer.fPnts + 3 * buffer.NbPnts()),
fNormals(3 * buffer.NbPols())
{
//
fNbPols = buffer.NbPols();
Int_t *segs = buffer.fSegs;
Int_t *pols = buffer.fPols;
Int_t descSize = 0;
for (UInt_t i = 0, j = 1; i < fNbPols; ++i, ++j)
{
descSize += pols[j] + 1;
j += pols[j] + 1;
}
fPolyDesc.resize(descSize);
{//fix for scope
for (UInt_t numPol = 0, currInd = 0, j = 1; numPol < fNbPols; ++numPol) {
Int_t segmentInd = pols[j] + j;
Int_t segmentCol = pols[j];
Int_t s1 = pols[segmentInd];
segmentInd--;
Int_t s2 = pols[segmentInd];
segmentInd--;
Int_t segEnds[] = {segs[s1 * 3 + 1], segs[s1 * 3 + 2],
segs[s2 * 3 + 1], segs[s2 * 3 + 2]};
Int_t numPnts[3] = {0};
if (segEnds[0] == segEnds[2]) {
numPnts[0] = segEnds[1], numPnts[1] = segEnds[0], numPnts[2] = segEnds[3];
} else if (segEnds[0] == segEnds[3]) {
numPnts[0] = segEnds[1], numPnts[1] = segEnds[0], numPnts[2] = segEnds[2];
} else if (segEnds[1] == segEnds[2]) {
numPnts[0] = segEnds[0], numPnts[1] = segEnds[1], numPnts[2] = segEnds[3];
} else {
numPnts[0] = segEnds[0], numPnts[1] = segEnds[1], numPnts[2] = segEnds[2];
}
fPolyDesc[currInd] = 3;
Int_t sizeInd = currInd++;
fPolyDesc[currInd++] = numPnts[0];
fPolyDesc[currInd++] = numPnts[1];
fPolyDesc[currInd++] = numPnts[2];
Int_t lastAdded = numPnts[2];
Int_t end = j + 1;
for (; segmentInd != end; segmentInd--) {
segEnds[0] = segs[pols[segmentInd] * 3 + 1];
segEnds[1] = segs[pols[segmentInd] * 3 + 2];
if (segEnds[0] == lastAdded) {
fPolyDesc[currInd++] = segEnds[1];
lastAdded = segEnds[1];
} else {
fPolyDesc[currInd++] = segEnds[0];
lastAdded = segEnds[0];
}
++fPolyDesc[sizeInd];
}
j += segmentCol + 2;
}
}
CalculateNormals();
}
//______________________________________________________________________________
void TGLFaceSet::SetFromMesh(const RootCsg::TBaseMesh *mesh)
{
// Should only be done on an empty faceset object
assert(fNbPols == 0);
UInt_t nv = mesh->NumberOfVertices();
fVertices.reserve(3 * nv);
fNormals.resize(mesh->NumberOfPolys() * 3);
UInt_t i;
for (i = 0; i < nv; ++i) {
const Double_t *v = mesh->GetVertex(i);
fVertices.insert(fVertices.end(), v, v + 3);
}
fNbPols = mesh->NumberOfPolys();
UInt_t descSize = 0;
for (i = 0; i < fNbPols; ++i) descSize += mesh->SizeOfPoly(i) + 1;
fPolyDesc.reserve(descSize);
for (UInt_t polyIndex = 0; polyIndex < fNbPols; ++polyIndex) {
UInt_t polySize = mesh->SizeOfPoly(polyIndex);
fPolyDesc.push_back(polySize);
for(UInt_t i = 0; i < polySize; ++i) fPolyDesc.push_back(mesh->GetVertexIndex(polyIndex, i));
}
CalculateNormals();
}
//______________________________________________________________________________
void TGLFaceSet::DirectDraw(const TGLDrawFlags & flags) const
{
// Debug tracing
if (gDebug > 4) {
Info("TGLFaceSet::DirectDraw", "this %d (class %s) LOD %d", this, IsA()->GetName(), flags.LOD());
}
GLUtriangulatorObj *tessObj = GetTesselator();
const Double_t *pnts = &fVertices[0];
const Double_t *normals = &fNormals[0];
const Int_t *pols = &fPolyDesc[0];
for (UInt_t i = 0, j = 0; i < fNbPols; ++i) {
Int_t npoints = pols[j++];
if (tessObj && npoints > 4) {
gluBeginPolygon(tessObj);
gluNextContour(tessObj, (GLenum)GLU_UNKNOWN);
glNormal3dv(normals + i * 3);
for (Int_t k = 0; k < npoints; ++k, ++j) {
gluTessVertex(tessObj, (Double_t *)pnts + pols[j] * 3, (Double_t *)pnts + pols[j] * 3);
}
gluEndPolygon(tessObj);
} else {
glBegin(GL_POLYGON);
glNormal3dv(normals + i * 3);
for (Int_t k = 0; k < npoints; ++k, ++j) {
glVertex3dv(pnts + pols[j] * 3);
}
glEnd();
}
}
}
//______________________________________________________________________________
Int_t TGLFaceSet::CheckPoints(const Int_t *source, Int_t *dest) const
{
//
const Double_t * p1 = &fVertices[source[0] * 3];
const Double_t * p2 = &fVertices[source[1] * 3];
const Double_t * p3 = &fVertices[source[2] * 3];
Int_t retVal = 1;
if (Eq(p1, p2)) {
dest[0] = source[0];
if (!Eq(p1, p3) ) {
dest[1] = source[2];
retVal = 2;
}
} else if (Eq(p1, p3)) {
dest[0] = source[0];
dest[1] = source[1];
retVal = 2;
} else {
dest[0] = source[0];
dest[1] = source[1];
retVal = 2;
if (!Eq(p2, p3)) {
dest[2] = source[2];
retVal = 3;
}
}
return retVal;
}
//______________________________________________________________________________
Bool_t TGLFaceSet::Eq(const Double_t *p1, const Double_t *p2)
{
//
Double_t dx = TMath::Abs(p1[0] - p2[0]);
Double_t dy = TMath::Abs(p1[1] - p2[1]);
Double_t dz = TMath::Abs(p1[2] - p2[2]);
return dx < 1e-10 && dy < 1e-10 && dz < 1e-10;
}
//______________________________________________________________________________
void TGLFaceSet::CalculateNormals()
{
//
Double_t *pnts = &fVertices[0];
for (UInt_t i = 0, j = 0; i < fNbPols; ++i) {
Int_t polEnd = fPolyDesc[j] + j + 1;
Int_t norm[] = {fPolyDesc[j + 1], fPolyDesc[j + 2], fPolyDesc[j + 3]};
j += 4;
Int_t check = CheckPoints(norm, norm), ngood = check;
if (check == 3) {
TMath::Normal2Plane(pnts + norm[0] * 3, pnts + norm[1] * 3,
pnts + norm[2] * 3, &fNormals[i * 3]);
j = polEnd;
continue;
}
while (j < (UInt_t)polEnd) {
norm[ngood++] = fPolyDesc[j++];
if (ngood == 3) {
ngood = CheckPoints(norm, norm);
if (ngood == 3) {
TMath::Normal2Plane(pnts + norm[0] * 3, pnts + norm[1] * 3,
pnts + norm[2] * 3, &fNormals[i * 3]);
j = polEnd;
break;
}
}
}
}
}
// @(#)root/gl:$Name: $:$Id: TGLPloyLine.cxx $
// Author: Timur Pocheptsov 03/08/2004
// NOTE: This code moved from obsoleted TGLSceneObject.h / .cxx - see these
// attic files for previous CVS history
/*************************************************************************
* Copyright (C) 1995-2006, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#include "TGLPolyLine.h"
#include "TGLDrawFlags.h"
#include "TGLIncludes.h"
#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"
// For debug tracing
#include "TClass.h"
#include "TError.h"
ClassImp(TGLPolyLine)
//______________________________________________________________________________
TGLPolyLine::TGLPolyLine(const TBuffer3D & buffer) :
TGLLogicalShape(buffer),
fVertices(buffer.fPnts, buffer.fPnts + 3 * buffer.NbPnts())
{
//
}
//______________________________________________________________________________
void TGLPolyLine::DirectDraw(const TGLDrawFlags & flags) const
{
// Debug tracing
if (gDebug > 4) {
Info("TGLPolyLine::DirectDraw", "this %d (class %s) LOD %d", this, IsA()->GetName(), flags.LOD());
}
glBegin(GL_LINE_STRIP);
for (UInt_t i = 0; i < fVertices.size(); i += 3)
glVertex3d(fVertices[i], fVertices[i + 1], fVertices[i + 2]);
glEnd();
}
// @(#)root/gl:$Name: $:$Id: TGLPolyMarker.cxx $
// Author: Timur Pocheptsov 03/08/2004
// NOTE: This code moved from obsoleted TGLSceneObject.h / .cxx - see these
// attic files for previous CVS history
/*************************************************************************
* Copyright (C) 1995-2006, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#include "TGLPolyMarker.h"
#include "TGLDrawFlags.h"
#include "TGLIncludes.h"
#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"
#include "TAttMarker.h"
// For debug tracing
#include "TClass.h"
#include "TError.h"
ClassImp(TGLPolyMarker)
//______________________________________________________________________________
TGLPolyMarker::TGLPolyMarker(const TBuffer3D & buffer) :
TGLLogicalShape(buffer),
fVertices(buffer.fPnts, buffer.fPnts + 3 * buffer.NbPnts()),
fStyle(7)
{
//TAttMarker is not TObject descendant, so I need dynamic_cast
if (TAttMarker *realObj = dynamic_cast<TAttMarker *>(buffer.fID))
fStyle = realObj->GetMarkerStyle();
}
//______________________________________________________________________________
void TGLPolyMarker::DirectDraw(const TGLDrawFlags & flags) const
{
// Debug tracing
if (gDebug > 4) {
Info("TGLPolyMarker::DirectDraw", "this %d (class %s) LOD %d", this, IsA()->GetName(), flags.LOD());
}
const Double_t *vertices = &fVertices[0];
UInt_t size = fVertices.size();
Int_t stacks = 6, slices = 6;
Float_t pointSize = 6.f;
Double_t topRadius = 5.;
switch (fStyle) {
case 27:
stacks = 2, slices = 4;
case 4:case 8:case 20:case 24:
for (UInt_t i = 0; i < size; i += 3) {
glPushMatrix();
glTranslated(vertices[i], vertices[i + 1], vertices[i + 2]);
gluSphere(fgQuad.Get(), 5., slices, stacks);
glPopMatrix();
}
break;
case 22:case 26:
topRadius = 0.;
case 21:case 25:
for (UInt_t i = 0; i < size; i += 3) {
glPushMatrix();
glTranslated(vertices[i], vertices[i + 1], vertices[i + 2]);
gluCylinder(fgQuad.Get(), 5., topRadius, 5., 4, 1);
glPopMatrix();
}
break;
case 23:
for (UInt_t i = 0; i < size; i += 3) {
glPushMatrix();
glTranslated(vertices[i], vertices[i + 1], vertices[i + 2]);
glRotated(180, 1., 0., 0.);
gluCylinder(fgQuad.Get(), 5., 0., 5., 4, 1);
glPopMatrix();
}
break;
case 3: case 2: case 5:
DrawStars();
break;
case 1: case 9: case 10: case 11: default:{
glBegin(GL_POINTS);
for (UInt_t i = 0; i < size; i += 3)
glVertex3dv(vertices + i);
glEnd();
}
break;
case 6:
pointSize = 3.f;
case 7:
glPointSize(pointSize);
glBegin(GL_POINTS);
for (UInt_t i = 0; i < size; i += 3)
glVertex3dv(vertices + i);
glEnd();
glPointSize(1.f);
}
}
//______________________________________________________________________________
void TGLPolyMarker::DrawStars()const
{
//
glDisable(GL_LIGHTING);
for (UInt_t i = 0; i < fVertices.size(); i += 3) {
Double_t x = fVertices[i];
Double_t y = fVertices[i + 1];
Double_t z = fVertices[i + 2];
glBegin(GL_LINES);
if (fStyle == 2 || fStyle == 3) {
glVertex3d(x - 2., y, z);
glVertex3d(x + 2., y, z);
glVertex3d(x, y, z - 2.);
glVertex3d(x, y, z + 2.);
glVertex3d(x, y - 2., z);
glVertex3d(x, y + 2., z);
}
if(fStyle != 2) {
glVertex3d(x - 1.4, y - 1.4, z - 1.4);
glVertex3d(x + 1.4, y + 1.4, z + 1.4);
glVertex3d(x - 1.4, y - 1.4, z + 1.4);
glVertex3d(x + 1.4, y + 1.4, z - 1.4);
glVertex3d(x - 1.4, y + 1.4, z - 1.4);
glVertex3d(x + 1.4, y - 1.4, z + 1.4);
glVertex3d(x - 1.4, y + 1.4, z + 1.4);
glVertex3d(x + 1.4, y - 1.4, z - 1.4);
}
glEnd();
}
glEnable(GL_LIGHTING);
}
// @(#)root/gl:$Name: $:$Id: TGLSphere.cxx $
// Author: Timur Pocheptsov 03/08/2004
// NOTE: This code moved from obsoleted TGLSceneObject.h / .cxx - see these
// attic files for previous CVS history
/*************************************************************************
* Copyright (C) 1995-2006, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
#include "TGLSphere.h"
#include "TGLDrawFlags.h"
#include "TGLIncludes.h"
#include "TBuffer3D.h"
#include "TBuffer3DTypes.h"
// For debug tracing
#include "TClass.h"
#include "TError.h"
ClassImp(TGLSphere)
//______________________________________________________________________________
TGLSphere::TGLSphere(const TBuffer3DSphere &buffer) :
TGLLogicalShape(buffer)
{
// Default ctor
fRadius = buffer.fRadiusOuter;
// TODO:
// Support hollow & cut spheres
// buffer.fRadiusInner;
// buffer.fThetaMin;
// buffer.fThetaMax;
// buffer.fPhiMin;
// buffer.fPhiMax;
}
//______________________________________________________________________________
void TGLSphere::DirectDraw(const TGLDrawFlags & flags) const
{
// Debug tracing
if (gDebug > 4) {
Info("TGLSphere::DirectDraw", "this %d (class %s) LOD %d", this, IsA()->GetName(), flags.LOD());
}
// 4 stack/slice min for gluSphere to work
UInt_t divisions = flags.LOD();
if (divisions < 4) {
divisions = 4;
}
gluSphere(fgQuad.Get(),fRadius, divisions, divisions);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment