Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
REveGluTess.cxx
Go to the documentation of this file.
1 // @(#)root/eve7:$Id$
2 // Authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007, 2018
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 
13 // This is a minimal-change import of GLU libtess from:
14 // git://anongit.freedesktop.org/git/mesa/glu
15 //
16 // Changes to make it build in the horrible one-file-hack way:
17 // - remove include gl.h from glu.h (and replace with the mini-gl defs below);
18 // - comment out clashing typedef EdgePair in tess.c;
19 // - use -Wno-unused-parameter for this cxx file.
20 
21 // Sergey: first include gl code before any normal ROOT includes,
22 // try to avoid clash with other system includes through Rtypes.h
23 
24 #include "glu/GL_glu.h"
25 
26 #include <ROOT/REveGluTess.hxx>
27 
28 #include <math.h>
29 #include <stdlib.h>
30 #include <stdexcept>
31 
32 namespace ROOT {
33 namespace Experimental {
34 namespace EveGlu {
35 
36 //////////////////////////////////////////////////////////////////////////////////////
37 /// TestTriangleHandler is just helper class to get access to protected members of TriangleCollector
38 /// Hide static declarations, let use "native" GL types
39 //////////////////////////////////////////////////////////////////////////////////////
40 
41 class TestTriangleHandler {
42 public:
43  static void tess_begin(GLenum type, TriangleCollector *tc);
44  static void tess_vertex(Int_t *vi, TriangleCollector *tc);
45  static void
46  tess_combine(GLdouble coords[3], void *vertex_data[4], GLfloat weight[4], void **outData, TriangleCollector *tc);
47  static void tess_end(TriangleCollector *tc);
48 };
49 
50 
51 //////////////////////////////////////////////////////////////////////////////////////
52 /// tess_begin
53 
54 void TestTriangleHandler::tess_begin(GLenum type, TriangleCollector *tc)
55 {
56  tc->fNVertices = 0;
57  tc->fV0 = tc->fV1 = -1;
58  tc->fType = type;
59 }
60 
61 //////////////////////////////////////////////////////////////////////////////////////
62 /// tess_vertex
63 
64 void TestTriangleHandler::tess_vertex(Int_t *vi, TriangleCollector *tc)
65 {
66  tc->process_vertex(*vi);
67 }
68 
69 //////////////////////////////////////////////////////////////////////////////////////
70 /// tess_combine
71 
72 void TestTriangleHandler::tess_combine(GLdouble /*coords*/[3], void * /*vertex_data*/[4],
73  GLfloat /*weight*/[4], void ** /*outData*/,
74  TriangleCollector * /*tc*/)
75 {
76  throw std::runtime_error("GLU::TriangleCollector tesselator requested vertex combining -- not supported yet.");
77 }
78 
79 //////////////////////////////////////////////////////////////////////////////////////
80 /// tess_end
81 
82 void TestTriangleHandler::tess_end(TriangleCollector *tc)
83 {
84  tc->fType = GL_NONE;
85 }
86 
87 
88 //==============================================================================
89 // TriangleCollector
90 //==============================================================================
91 
92 //////////////////////////////////////////////////////////////////////////////////////
93 /// constructor
94 
95 TriangleCollector::TriangleCollector()
96 {
97  fType = GL_NONE;
98  fTess = gluNewTess();
99  if (!fTess) throw std::bad_alloc();
100 
101  gluTessCallback(fTess, (GLenum)GLU_TESS_BEGIN_DATA, (_GLUfuncptr) TestTriangleHandler::tess_begin);
102  gluTessCallback(fTess, (GLenum)GLU_TESS_VERTEX_DATA, (_GLUfuncptr) TestTriangleHandler::tess_vertex);
103  gluTessCallback(fTess, (GLenum)GLU_TESS_COMBINE_DATA, (_GLUfuncptr) TestTriangleHandler::tess_combine);
104  gluTessCallback(fTess, (GLenum)GLU_TESS_END_DATA, (_GLUfuncptr) TestTriangleHandler::tess_end);
105 }
106 
107 //////////////////////////////////////////////////////////////////////////////////////
108 /// destructor
109 
110 TriangleCollector::~TriangleCollector()
111 {
112  gluDeleteTess(fTess);
113 }
114 
115 //////////////////////////////////////////////////////////////////////////////////////
116 /// add triangle
117 
118 void TriangleCollector::add_triangle(Int_t v0, Int_t v1, Int_t v2)
119 {
120  fPolyDesc.emplace_back(3);
121  fPolyDesc.emplace_back(v0);
122  fPolyDesc.emplace_back(v1);
123  fPolyDesc.emplace_back(v2);
124  ++fNTriangles;
125 }
126 
127 //////////////////////////////////////////////////////////////////////////////////////
128 /// process_vertex
129 
130 void ROOT::Experimental::EveGlu::TriangleCollector::process_vertex(Int_t vi)
131 {
132  ++fNVertices;
133 
134  if (fV0 == -1) {
135  fV0 = vi;
136  return;
137  }
138  if (fV1 == -1) {
139  fV1 = vi;
140  return;
141  }
142 
143  switch (fType)
144  {
145  case GL_TRIANGLES:
146  {
147  add_triangle(fV0, fV1, vi);
148  fV0 = fV1 = -1;
149  break;
150  }
151  case GL_TRIANGLE_STRIP:
152  {
153  if (fNVertices % 2 == 0)
154  add_triangle(fV1, fV0, vi);
155  else
156  add_triangle(fV0, fV1, vi);
157  fV0 = fV1;
158  fV1 = vi;
159  break;
160  }
161  case GL_TRIANGLE_FAN:
162  {
163  add_triangle(fV0, fV1, vi);
164  fV1 = vi;
165  break;
166  }
167  default:
168  {
169  throw std::runtime_error("GLU::TriangleCollector unexpected type in tess_vertex callback.");
170  }
171  }
172 }
173 
174 //////////////////////////////////////////////////////////////////////////////////////
175 /// ProcessData
176 
177 void ROOT::Experimental::EveGlu::TriangleCollector::ProcessData(const std::vector<Double_t>& verts,
178  const std::vector<Int_t> & polys,
179  const Int_t n_polys)
180 {
181  const Double_t *pnts = &verts[0];
182  const Int_t *pols = &polys[0];
183 
184  for (Int_t i = 0, j = 0; i < n_polys; ++i)
185  {
186  Int_t n_points = pols[j++];
187 
188  gluTessBeginPolygon(fTess, this);
189  gluTessBeginContour(fTess);
190 
191  for (Int_t k = 0; k < n_points; ++k, ++j)
192  {
193  gluTessVertex(fTess, (Double_t*) pnts + pols[j] * 3, (GLvoid*) &pols[j]);
194  }
195 
196  gluTessEndContour(fTess);
197 
198  static int except_cnt = 0;
199 
200  try {
201  gluTessEndPolygon(fTess);
202  } catch(...) {
203  if (except_cnt++ < 100) printf("Catch exception gluTessEndPolygon!\n");
204  }
205  }
206 }
207 
208 } // namespace EveGlu
209 } // namespace Experimental
210 } // namespace ROOT