Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/tess_contour

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.
  3 
  4 #ifndef tools_tess_contour
  5 #define tools_tess_contour
  6 
  7 #include "glutess/glutess"
  8 #include "lina/vec3f"
  9 #include "glprims"
 10 
 11 namespace tools {
 12 
 13 typedef struct {
 14   double pointA[3];
 15   double pointB[3];
 16   double pointC[3];
 17 } tess_triangle;
 18 
 19 class tess_contour {
 20 public:
 21   tess_contour(std::ostream& a_out,std::vector<tess_triangle>& a_triangles)
 22   :m_out(a_out)
 23   ,m_triangles(a_triangles)
 24   ,m_vertex_number(0),m_begin_type(gl::triangles()),m_error(false){}
 25   virtual ~tess_contour(){}
 26 protected:
 27   tess_contour(const tess_contour& a_from):m_out(a_from.m_out),m_triangles(a_from.m_triangles){}
 28   tess_contour& operator=(const tess_contour&){return *this;}
 29 public:
 30   void getFilledArea(const std::vector<std::vector<vec3f> >& aContour) {
 31     m_triangles.clear();
 32     m_combine_tmps.clear();
 33     m_error = false;
 34 
 35     GLUtesselator* tobj = gluNewTess();
 36 
 37     // g++-8.1.0 : the five below lines induce warnings : cast between incompatible function types.
 38     //::gluTessCallback(tobj,(GLUenum)GLU_TESS_VERTEX_DATA, (Func)vertexCallback);
 39     //::gluTessCallback(tobj,(GLUenum)GLU_TESS_BEGIN_DATA,  (Func)beginCallback);
 40     //::gluTessCallback(tobj,(GLUenum)GLU_TESS_END_DATA,    (Func)endCallback);
 41     //::gluTessCallback(tobj,(GLUenum)GLU_TESS_ERROR_DATA,  (Func)errorCallback);
 42     //::gluTessCallback(tobj,(GLUenum)GLU_TESS_COMBINE_DATA,(Func)combineCallback);
 43 
 44     // NOTE : the gluTessCallback_<> are tools/glutess specific.
 45     ::gluTessCallback_GLU_TESS_VERTEX_DATA (tobj,vertexCallback);
 46     ::gluTessCallback_GLU_TESS_BEGIN_DATA  (tobj,beginCallback);
 47     ::gluTessCallback_GLU_TESS_END_DATA    (tobj,endCallback);
 48     ::gluTessCallback_GLU_TESS_ERROR_DATA  (tobj,errorCallback);
 49     ::gluTessCallback_GLU_TESS_COMBINE_DATA(tobj,combineCallback);
 50 
 51     ::gluTessProperty(tobj,(GLUenum)GLU_TESS_WINDING_RULE,GLU_TESS_WINDING_ODD);
 52 
 53     for(unsigned int a=0;a<aContour.size();a++) {
 54       //if(aContour[a][0]!=aContour[a][aContour[a].size()-1]) continue;
 55       if(aContour[a].size()<=1) continue; //should not happen.
 56       size_t vecSize = aContour[a].size()-1;
 57 
 58       typedef GLUdouble point[3];
 59       point* tab = new point[vecSize];
 60 
 61       ::gluTessBeginPolygon(tobj, this);
 62 
 63       ::gluTessBeginContour(tobj);
 64       for(size_t b=0;b<vecSize;b++) {
 65         tab[b][0] = aContour[a][b][0];
 66         tab[b][1] = aContour[a][b][1];
 67         tab[b][2] = aContour[a][b][2];
 68         ::gluTessVertex(tobj, tab[b],tab[b]);
 69       }
 70       ::gluTessEndContour(tobj);
 71 
 72       ::gluTessEndPolygon(tobj);
 73 
 74       delete [] tab;
 75     }
 76 
 77     ::gluDeleteTess(tobj);
 78 
 79     for(unsigned int index=0;index<m_combine_tmps.size();index++) {
 80       delete [] m_combine_tmps[index];
 81     }
 82     m_combine_tmps.clear();
 83 
 84     if(m_error) m_triangles.clear();
 85   }
 86 
 87 protected:
 88   void resetVertex() {m_vertex_number = 0;}
 89   void setBeginType(gl::mode_t aType) {m_begin_type = aType;}
 90   void setError(bool aError) {m_error = aError;}
 91   std::vector<double*>& combineTmps(){return m_combine_tmps;}
 92 
 93   void addVertex(const double* vertex) {
 94     // GLU_TRIANGLE_STRIP
 95     // Draws a connected group of triangles. One triangle is defined for each
 96     // vertex presented after the first two vertices. For odd n, vertices n,
 97     // n+1, and n+2 define triangle n. For even n, vertices n+1, n, and n+2
 98     // define triangle n. N-2 triangles are drawn.
 99     if (m_begin_type == gl::triangle_strip()) {
100       m_tmp.pointC[0] = vertex[0];
101       m_tmp.pointC[1] = vertex[1];
102       m_tmp.pointC[2] = vertex[2];
103 
104       if(m_vertex_number>=2) m_triangles.push_back(m_tmp);
105 
106       int rest = m_vertex_number % 2;
107       if(rest==1) {
108         m_tmp.pointA[0] = vertex[0];
109         m_tmp.pointA[1] = vertex[1];
110         m_tmp.pointA[2] = vertex[2];
111       } else {
112         m_tmp.pointB[0] = vertex[0];
113         m_tmp.pointB[1] = vertex[1];
114         m_tmp.pointB[2] = vertex[2];
115       }
116       m_vertex_number++;
117     }
118 
119     // GLU_TRIANGLE_FAN
120     // Draws a connected group of triangles. One triangle is defined for each
121     // vertex presented after the first two vertices. Vertices 1, n+1,
122     // and n+2 define triangle n. N-2 triangles are drawn.
123     else if (m_begin_type == gl::triangle_fan()) {
124       if (m_vertex_number == 0) {
125         m_tmp.pointA[0] = vertex[0];
126         m_tmp.pointA[1] = vertex[1];
127         m_tmp.pointA[2] = vertex[2];
128       } else {
129         m_tmp.pointC[0] = vertex[0];
130         m_tmp.pointC[1] = vertex[1];
131         m_tmp.pointC[2] = vertex[2];
132 
133         if (m_vertex_number >=2 ) {
134           m_triangles.push_back(m_tmp);
135         }
136         m_tmp.pointB[0] = vertex[0];
137         m_tmp.pointB[1] = vertex[1];
138         m_tmp.pointB[2] = vertex[2];
139       }
140       m_vertex_number++;
141     }
142 
143     // GLU_TRIANGLES
144     // Treats each triplet of vertices as an independent triangle.
145     // Vertices 3n-2, 3n-1, and 3n define triangle n. N/3 triangles are drawn.
146     else if (m_begin_type == gl::triangles()) {
147 
148       int rest = m_vertex_number % 3;
149 
150       if(rest==2) {
151         m_tmp.pointC[0] = vertex[0];
152         m_tmp.pointC[1] = vertex[1];
153         m_tmp.pointC[2] = vertex[2];
154 
155         m_triangles.push_back(m_tmp);
156 
157       } else if(rest==1) {
158         m_tmp.pointB[0] = vertex[0];
159         m_tmp.pointB[1] = vertex[1];
160         m_tmp.pointB[2] = vertex[2];
161 
162       } else if(rest==0) {
163         m_tmp.pointA[0] = vertex[0];
164         m_tmp.pointA[1] = vertex[1];
165         m_tmp.pointA[2] = vertex[2];
166       }
167       m_vertex_number++;
168 
169     } else {
170       // do nothing and should never happend
171     }
172   }
173 protected:
174 #ifdef TOOLS_TESS_CONTOUR_STDCALL
175   typedef GLUvoid(__stdcall *Func)();
176 #else
177   typedef GLUvoid(*Func)();
178 #endif
179 
180   static void
181 #ifdef TOOLS_TESS_CONTOUR_STDCALL
182   __stdcall
183 #endif
184   beginCallback(GLUenum aWhich,GLUvoid * aThis) {
185     tess_contour* This = (tess_contour*)aThis;
186     This->setBeginType(aWhich);
187     This->resetVertex();
188   }
189 
190   static void
191 #ifdef TOOLS_TESS_CONTOUR_STDCALL
192   __stdcall
193 #endif
194   errorCallback(GLUenum aErrorCode,GLUvoid * aThis) {
195     tess_contour* This = (tess_contour*)aThis;
196     This->m_out << "tools::tess_contour::errorCallback : " << aErrorCode << std::endl;
197     This->setError(true);
198   }
199 
200   static void
201 #ifdef TOOLS_TESS_CONTOUR_STDCALL
202   __stdcall
203 #endif
204   endCallback(void*){}
205 
206   static void
207 #ifdef TOOLS_TESS_CONTOUR_STDCALL
208   __stdcall
209 #endif
210   vertexCallback(GLUvoid *vertex,GLUvoid* aThis) {
211     tess_contour* This = (tess_contour*)aThis;
212     This->addVertex((double*)vertex);
213   }
214 
215   static void
216 #ifdef TOOLS_TESS_CONTOUR_STDCALL
217   __stdcall
218 #endif
219   combineCallback(GLUdouble coords[3],
220                               void* /*vertex_data*/[4],
221                               GLUfloat /*weight*/[4],
222                               void** dataOut,
223                               void* aThis) {
224     tess_contour* This = (tess_contour*)aThis;
225     double* vertex = new double[3];
226     vertex[0] = coords[0];
227     vertex[1] = coords[1];
228     vertex[2] = coords[2];
229     This->combineTmps().push_back(vertex);
230     *dataOut = vertex;
231   }
232 
233 protected:
234   std::ostream& m_out;
235   std::vector<tess_triangle>& m_triangles;
236   tess_triangle m_tmp;
237   unsigned int m_vertex_number;
238   gl::mode_t m_begin_type;
239   bool m_error;
240   std::vector<double*> m_combine_tmps;
241 };
242 
243 }
244 
245 #endif