16#include "TGLIncludes.h"
35#if defined(__APPLE_CC__) && __APPLE_CC__ > 4000 && __APPLE_CC__ < 5450 && !defined(__INTEL_COMPILER)
36 typedef GLvoid (*tessfuncptr_t)(...);
37#elif defined(__linux__) || defined(__FreeBSD__) || defined( __OpenBSD__ ) || defined(__sun) || defined (__CYGWIN__) || defined (__APPLE__)
38 typedef GLvoid (*tessfuncptr_t)();
42 #error "Error - need to define type tessfuncptr_t for this platform/compiler"
60 fVertices(buffer.fPnts, buffer.fPnts + 3 * buffer.NbPnts()),
74 descSize += pols[j] + 1;
80 for (
UInt_t numPol = 0, currInd = 0, j = 1; numPol <
fNbPols; ++numPol)
82 Int_t segmentInd = pols[j] + j;
83 Int_t segmentCol = pols[j];
86 Int_t s2 = pols[segmentInd];
90 Int_t numPnts[3] = {0};
92 if (segEnds[0] == segEnds[2]) {
93 numPnts[0] = segEnds[1], numPnts[1] = segEnds[0], numPnts[2] = segEnds[3];
94 }
else if (segEnds[0] == segEnds[3]) {
95 numPnts[0] = segEnds[1], numPnts[1] = segEnds[0], numPnts[2] = segEnds[2];
96 }
else if (segEnds[1] == segEnds[2]) {
97 numPnts[0] = segEnds[0], numPnts[1] = segEnds[1], numPnts[2] = segEnds[3];
99 numPnts[0] = segEnds[0], numPnts[1] = segEnds[1], numPnts[2] = segEnds[2];
103 Int_t sizeInd = currInd++;
107 Int_t lastAdded = numPnts[2];
110 for (; segmentInd != end; segmentInd--) {
111 segEnds[0] =
segs[pols[segmentInd] * 3 + 1];
112 segEnds[1] =
segs[pols[segmentInd] * 3 + 2];
113 if (segEnds[0] == lastAdded) {
115 lastAdded = segEnds[1];
118 lastAdded = segEnds[0];
138 UInt_t nv = mesh->NumberOfVertices();
142 for (i = 0; i < nv; ++i) {
147 fNbPols = mesh->NumberOfPolys();
151 for (i = 0; i <
fNbPols; ++i) descSize += mesh->SizeOfPoly(i) + 1;
155 for (
UInt_t polyIndex = 0; polyIndex <
fNbPols; ++polyIndex) {
156 UInt_t polySize = mesh->SizeOfPoly(polyIndex);
160 for(i = 0; i < polySize; ++i)
fPolyDesc.push_back(mesh->GetVertexIndex(polyIndex, i));
178 class TriangleCollector
185 std::vector<Int_t> fPolyDesc;
189 fPolyDesc.push_back(3);
190 fPolyDesc.push_back(
v0);
191 fPolyDesc.push_back(
v1);
192 fPolyDesc.push_back(
v2);
196 void process_vertex(
Int_t vi)
213 add_triangle(fV0, fV1, vi);
219 if (fNVertices % 2 == 0)
220 add_triangle(fV1, fV0, vi);
222 add_triangle(fV0, fV1, vi);
229 add_triangle(fV0, fV1, vi);
235 throw std::runtime_error(
"TGLFaceSet::EnforceTriangles unexpected type in tess_vertex callback.");
242 fNTriangles(0), fNVertices(0), fV0(-1), fV1(-1), fType(
GL_NONE)
250 Int_t GetNTrianlges() {
return fNTriangles; }
251 std::vector<Int_t>& RefPolyDesc() {
return fPolyDesc; }
253 static void tess_begin(
GLenum type, TriangleCollector* tc)
256 tc->fV0 = tc->fV1 = -1;
260 static void tess_vertex(
Int_t* vi, TriangleCollector* tc)
262 tc->process_vertex(*vi);
265 static void tess_combine(
GLdouble [3],
void* [4],
269 throw std::runtime_error(
"TGLFaceSet::EnforceTriangles tesselator requested vertex combining -- not supported yet.");
272 static void tess_end(TriangleCollector* tc)
279 if (!tess)
throw std::bad_alloc();
281 TriangleCollector tc(tess);
289 Int_t npoints = pols[j++];
294 for (
Int_t k = 0; k < npoints; ++k, ++j)
315 Info(
"TGLFaceSet::DirectDraw",
"this %ld (class %s) LOD %d", (
Long_t)
this, IsA()->GetName(), rnrCtx.
ShapeLOD());
326 Int_t npoints = pols[j++];
328 if (tessObj && npoints > 4) {
331 glNormal3dv(normals + i * 3);
333 for (
Int_t k = 0; k < npoints; ++k, ++j) {
339 glNormal3dv(normals + i * 3);
341 for (
Int_t k = 0; k < npoints; ++k, ++j) {
342 glVertex3dv(pnts + pols[j] * 3);
365 }
else if (
Eq(p1, p3)) {
390 return dx < 1
e-10 && dy < 1
e-10 && dz < 1
e-10;
408 pnts + norm[2] * 3, &
fNormals[i * 3]);
412 while (j < (
UInt_t)polEnd) {
418 pnts + norm[2] * 3, &
fNormals[i * 3]);
#define GLU_TESS_BEGIN_DATA
#define GLU_TESS_COMBINE_DATA
GLAPI void GLAPIENTRY gluBeginPolygon(GLUtesselator *tess)
GLAPI GLUtesselator *GLAPIENTRY gluNewTess(void)
GLAPI void GLAPIENTRY gluTessEndPolygon(GLUtesselator *tess)
#define GLU_TESS_END_DATA
GLAPI void GLAPIENTRY gluTessBeginContour(GLUtesselator *tess)
GLAPI void GLAPIENTRY gluNextContour(GLUtesselator *tess, GLenum type)
GLAPI void GLAPIENTRY gluTessBeginPolygon(GLUtesselator *tess, GLvoid *data)
GLAPI void GLAPIENTRY gluEndPolygon(GLUtesselator *tess)
#define GLU_TESS_VERTEX_DATA
GLAPI void GLAPIENTRY gluTessCallback(GLUtesselator *tess, GLenum which, _GLUfuncptr CallBackFunc)
#define GL_TRIANGLE_STRIP
GLAPI void GLAPIENTRY gluDeleteTess(GLUtesselator *tess)
GLAPI void GLAPIENTRY gluTessVertex(GLUtesselator *tess, GLdouble *location, GLvoid *data)
GLAPI void GLAPIENTRY gluTessEndContour(GLUtesselator *tess)
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Generic 3D primitive description class.
Implements a native ROOT-GL representation of an arbitrary set of polygons.
void EnforceTriangles()
Use GLU tesselator to replace all polygons with N > 3 with triangles.
static void SetEnforceTriangles(Bool_t e)
Set state of static flag EnforceTriangles.
std::vector< Int_t > fPolyDesc
std::vector< Double_t > fNormals
Int_t CheckPoints(const Int_t *source, Int_t *dest) const
CheckPoints.
void SetFromMesh(const RootCsg::TBaseMesh *m)
Should only be done on an empty faceset object.
virtual void DirectDraw(TGLRnrCtx &rnrCtx) const
Debug tracing.
TGLFaceSet(const TBuffer3D &buffer)
constructor
void CalculateNormals()
CalculateNormals.
std::vector< Double_t > fVertices
static Bool_t Eq(const Double_t *p1, const Double_t *p2)
test equality
static Bool_t fgEnforceTriangles
static Bool_t GetEnforceTriangles()
Get current state of static flag EnforceTriangles.
Abstract logical shape - a GL 'drawable' - base for all shapes - faceset sphere etc.
The TGLRnrCtx class aggregates data for a given redering context as needed by various parts of the RO...
static GLUtesselator * GetDrawTesselator3dv()
Returns a tesselator for direct drawing when using 3-vertices with double precision.
T * Normal2Plane(const T v1[3], const T v2[3], const T v3[3], T normal[3])
Calculate a normal vector of a plane.
#define dest(otri, vertexptr)