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)();
40 typedef GLvoid (
CALLBACK *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];
84 Int_t s1 = pols[segmentInd];
86 Int_t s2 = pols[segmentInd];
88 Int_t segEnds[] = {segs[s1 * 3 + 1], segs[s1 * 3 + 2],
89 segs[s2 * 3 + 1], segs[s2 * 3 + 2]};
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
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);
217 case GL_TRIANGLE_STRIP:
219 if (fNVertices % 2 == 0)
220 add_triangle(fV1, fV0, vi);
222 add_triangle(fV0, fV1, vi);
227 case GL_TRIANGLE_FAN:
229 add_triangle(fV0, fV1, vi);
235 throw std::runtime_error(
"TGLFaceSet::EnforceTriangles unexpected type in tess_vertex callback.");
241 TriangleCollector(GLUtesselator* ts) :
242 fNTriangles(0), fNVertices(0), fV0(-1), fV1(-1),
fType(GL_NONE)
244 gluTessCallback(ts, (GLenum)GLU_TESS_BEGIN_DATA, (tessfuncptr_t) tess_begin);
245 gluTessCallback(ts, (GLenum)GLU_TESS_VERTEX_DATA, (tessfuncptr_t) tess_vertex);
246 gluTessCallback(ts, (GLenum)GLU_TESS_COMBINE_DATA, (tessfuncptr_t) tess_combine);
247 gluTessCallback(ts, (GLenum)GLU_TESS_END_DATA, (tessfuncptr_t) tess_end);
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],
266 GLfloat [4],
void** ,
269 throw std::runtime_error(
"TGLFaceSet::EnforceTriangles tesselator requested vertex combining -- not supported yet.");
272 static void tess_end(TriangleCollector* tc)
278 GLUtesselator *tess = gluNewTess();
279 if (!tess)
throw std::bad_alloc();
281 TriangleCollector tc(tess);
289 Int_t npoints = pols[j++];
291 gluTessBeginPolygon(tess, &tc);
292 gluTessBeginContour(tess);
294 for (
Int_t k = 0; k < npoints; ++k, ++j)
296 gluTessVertex(tess, (
Double_t*) pnts + pols[j] * 3, (GLvoid*) &pols[j]);
299 gluTessEndContour(tess);
300 gluTessEndPolygon(tess);
306 fNbPols = tc.GetNTrianlges();
326 Int_t npoints = pols[j++];
328 if (tessObj && npoints > 4) {
329 gluBeginPolygon(tessObj);
330 gluNextContour(tessObj, (GLenum)GLU_UNKNOWN);
331 glNormal3dv(normals + i * 3);
333 for (
Int_t k = 0; k < npoints; ++k, ++j) {
334 gluTessVertex(tessObj, (
Double_t *)pnts + pols[j] * 3, (
Double_t *)pnts + pols[j] * 3);
336 gluEndPolygon(tessObj);
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) {
413 norm[ngood++] = fPolyDesc[j++];
418 pnts + norm[2] * 3, &
fNormals[i * 3]);
std::string GetName(const std::string &scope_name)
The TGLRnrCtx class aggregates data for a given redering context as needed by various parts of the RO...
static double p3(double t, double a, double b, double c, double d)
void SetFromMesh(const RootCsg::TBaseMesh *m)
Should only be done on an empty faceset object.
Implements a native ROOT-GL representation of an arbitrary set of polygons.
T * Normal2Plane(const T v1[3], const T v2[3], const T v3[3], T normal[3])
Int_t CheckPoints(const Int_t *source, Int_t *dest) const
CheckPoints.
static double p2(double t, double a, double b, double c)
void Info(const char *location, const char *msgfmt,...)
std::vector< Int_t > fPolyDesc
static void SetEnforceTriangles(Bool_t e)
Set state of static flag EnforceTriangles.
static Bool_t GetEnforceTriangles()
Get current state of static flag EnforceTriangles.
Generic 3D primitive description class.
static Bool_t Eq(const Double_t *p1, const Double_t *p2)
test equality
static double p1(double t, double a, double b)
Abstract logical shape - a GL 'drawable' - base for all shapes - faceset sphere etc.
std::vector< Double_t > fVertices
virtual void DirectDraw(TGLRnrCtx &rnrCtx) const
Debug tracing.
static Bool_t fgEnforceTriangles
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
void EnforceTriangles()
Use GLU tesselator to replace all polygons with N > 3 with triangles.
void CalculateNormals()
CalculateNormals.
TGLFaceSet(const TBuffer3D &buffer)
constructor
#define dest(otri, vertexptr)
static GLUtesselator * GetDrawTesselator3dv()
Returns a tesselator for direct drawing when using 3-vertices with double precision.
double norm(double *x, double *p)
std::vector< Double_t > fNormals