16#include "TGLIncludes.h"
24#define ROOT_CsgOps_cxx
37#if defined(__APPLE_CC__) && __APPLE_CC__ > 4000 && __APPLE_CC__ < 5450 && !defined(__INTEL_COMPILER)
38 typedef GLvoid (*tessfuncptr_t)(...);
39#elif defined(__linux__) || defined(__FreeBSD__) || defined( __OpenBSD__ ) || defined(__sun) || defined (__CYGWIN__) || defined (__APPLE__)
40 typedef GLvoid (*tessfuncptr_t)();
42 typedef GLvoid (
CALLBACK *tessfuncptr_t)();
44 #error "Error - need to define type tessfuncptr_t for this platform/compiler"
61 fVertices(buffer.fPnts, buffer.fPnts + 3 * buffer.NbPnts()),
75 descSize += pols[j] + 1;
81 for (
UInt_t numPol = 0, currInd = 0, j = 1; numPol <
fNbPols; ++numPol)
83 Int_t segmentInd = pols[j] + j;
84 Int_t segmentCol = pols[j];
87 Int_t s2 = pols[segmentInd];
89 Int_t segEnds[] = {segs[
s1 * 3 + 1], segs[
s1 * 3 + 2],
90 segs[s2 * 3 + 1], segs[s2 * 3 + 2]};
91 Int_t numPnts[3] = {0};
93 if (segEnds[0] == segEnds[2]) {
94 numPnts[0] = segEnds[1], numPnts[1] = segEnds[0], numPnts[2] = segEnds[3];
95 }
else if (segEnds[0] == segEnds[3]) {
96 numPnts[0] = segEnds[1], numPnts[1] = segEnds[0], numPnts[2] = segEnds[2];
97 }
else if (segEnds[1] == segEnds[2]) {
98 numPnts[0] = segEnds[0], numPnts[1] = segEnds[1], numPnts[2] = segEnds[3];
100 numPnts[0] = segEnds[0], numPnts[1] = segEnds[1], numPnts[2] = segEnds[2];
104 Int_t sizeInd = currInd++;
108 Int_t lastAdded = numPnts[2];
111 for (; segmentInd != end; segmentInd--) {
112 segEnds[0] = segs[pols[segmentInd] * 3 + 1];
113 segEnds[1] = segs[pols[segmentInd] * 3 + 2];
114 if (segEnds[0] == lastAdded) {
116 lastAdded = segEnds[1];
119 lastAdded = segEnds[0];
139 UInt_t nv = mesh->NumberOfVertices();
143 for (i = 0; i < nv; ++i) {
148 fNbPols = mesh->NumberOfPolys();
152 for (i = 0; i <
fNbPols; ++i) descSize += mesh->SizeOfPoly(i) + 1;
156 for (
UInt_t polyIndex = 0; polyIndex <
fNbPols; ++polyIndex) {
157 UInt_t polySize = mesh->SizeOfPoly(polyIndex);
161 for(i = 0; i < polySize; ++i)
fPolyDesc.push_back(mesh->GetVertexIndex(polyIndex, i));
179 class TriangleCollector
186 std::vector<Int_t> fPolyDesc;
190 fPolyDesc.push_back(3);
191 fPolyDesc.push_back(
v0);
192 fPolyDesc.push_back(
v1);
193 fPolyDesc.push_back(
v2);
197 void process_vertex(
Int_t vi)
214 add_triangle(fV0, fV1, vi);
218 case GL_TRIANGLE_STRIP:
220 if (fNVertices % 2 == 0)
221 add_triangle(fV1, fV0, vi);
223 add_triangle(fV0, fV1, vi);
228 case GL_TRIANGLE_FAN:
230 add_triangle(fV0, fV1, vi);
236 throw std::runtime_error(
"TGLFaceSet::EnforceTriangles unexpected type in tess_vertex callback.");
242 TriangleCollector(GLUtesselator* ts) :
243 fNTriangles(0), fNVertices(0), fV0(-1), fV1(-1), fType(GL_NONE)
245 gluTessCallback(ts, (GLenum)GLU_TESS_BEGIN_DATA, (tessfuncptr_t)((
void*)tess_begin));
246 gluTessCallback(ts, (GLenum)GLU_TESS_VERTEX_DATA, (tessfuncptr_t)((
void*)tess_vertex));
247 gluTessCallback(ts, (GLenum)GLU_TESS_COMBINE_DATA, (tessfuncptr_t)((
void*)tess_combine));
248 gluTessCallback(ts, (GLenum)GLU_TESS_END_DATA, (tessfuncptr_t)((
void*)tess_end));
251 Int_t GetNTrianlges() {
return fNTriangles; }
252 std::vector<Int_t>& RefPolyDesc() {
return fPolyDesc; }
254 static void tess_begin(GLenum
type, TriangleCollector* tc)
257 tc->fV0 = tc->fV1 = -1;
261 static void tess_vertex(
Int_t* vi, TriangleCollector* tc)
263 tc->process_vertex(*vi);
266 static void tess_combine(GLdouble [3],
void* [4],
267 GLfloat [4],
void** ,
270 throw std::runtime_error(
"TGLFaceSet::EnforceTriangles tesselator requested vertex combining -- not supported yet.");
273 static void tess_end(TriangleCollector* tc)
279 GLUtesselator *tess = gluNewTess();
280 if (!tess)
throw std::bad_alloc();
282 TriangleCollector tc(tess);
290 Int_t npoints = pols[j++];
292 gluTessBeginPolygon(tess, &tc);
293 gluTessBeginContour(tess);
295 for (
Int_t k = 0; k < npoints; ++k, ++j)
297 gluTessVertex(tess, (
Double_t*) pnts + pols[j] * 3, (GLvoid*) &pols[j]);
300 gluTessEndContour(tess);
301 gluTessEndPolygon(tess);
316 Info(
"TGLFaceSet::DirectDraw",
"this %zd (class %s) LOD %d", (
size_t)
this,
IsA()->GetName(), rnrCtx.
ShapeLOD());
327 Int_t npoints = pols[j++];
329 if (tessObj && npoints > 4) {
330 gluBeginPolygon(tessObj);
331 gluNextContour(tessObj, (GLenum)GLU_UNKNOWN);
332 glNormal3dv(normals + i * 3);
334 for (
Int_t k = 0; k < npoints; ++k, ++j) {
335 gluTessVertex(tessObj, (
Double_t *)pnts + pols[j] * 3, (
Double_t *)pnts + pols[j] * 3);
337 gluEndPolygon(tessObj);
340 glNormal3dv(normals + i * 3);
342 for (
Int_t k = 0; k < npoints; ++k, ++j) {
343 glVertex3dv(pnts + pols[j] * 3);
366 }
else if (
Eq(p1, p3)) {
391 return dx < 1
e-10 && dy < 1
e-10 && dz < 1
e-10;
409 pnts + norm[2] * 3, &
fNormals[i * 3]);
413 while (j < (
UInt_t)polEnd) {
419 pnts + norm[2] * 3, &
fNormals[i * 3]);
bool Bool_t
Boolean (0=false, 1=true) (bool)
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t dest
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 type
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Generic 3D primitive description class.
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.
void DirectDraw(TGLRnrCtx &rnrCtx) const override
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
TClass * IsA() const override
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])
Calculates a normal vector of a plane.
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.