Warning, /include/Geant4/tools/tess_contour is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef tools_tess_contour
0005 #define tools_tess_contour
0006
0007 #include "glutess/glutess"
0008 #include "lina/vec3f"
0009 #include "glprims"
0010
0011 namespace tools {
0012
0013 typedef struct {
0014 double pointA[3];
0015 double pointB[3];
0016 double pointC[3];
0017 } tess_triangle;
0018
0019 class tess_contour {
0020 public:
0021 tess_contour(std::ostream& a_out,std::vector<tess_triangle>& a_triangles)
0022 :m_out(a_out)
0023 ,m_triangles(a_triangles)
0024 ,m_vertex_number(0),m_begin_type(gl::triangles()),m_error(false){}
0025 virtual ~tess_contour(){}
0026 protected:
0027 tess_contour(const tess_contour& a_from):m_out(a_from.m_out),m_triangles(a_from.m_triangles){}
0028 tess_contour& operator=(const tess_contour&){return *this;}
0029 public:
0030 void getFilledArea(const std::vector<std::vector<vec3f> > aContour) {
0031 m_triangles.clear();
0032 m_combine_tmps.clear();
0033 m_error = false;
0034
0035 GLUtesselator* tobj = gluNewTess();
0036
0037 // g++-8.1.0 : the five below lines induce warnings : cast between incompatible function types.
0038 //::gluTessCallback(tobj,(GLUenum)GLU_TESS_VERTEX_DATA, (Func)vertexCallback);
0039 //::gluTessCallback(tobj,(GLUenum)GLU_TESS_BEGIN_DATA, (Func)beginCallback);
0040 //::gluTessCallback(tobj,(GLUenum)GLU_TESS_END_DATA, (Func)endCallback);
0041 //::gluTessCallback(tobj,(GLUenum)GLU_TESS_ERROR_DATA, (Func)errorCallback);
0042 //::gluTessCallback(tobj,(GLUenum)GLU_TESS_COMBINE_DATA,(Func)combineCallback);
0043
0044 // NOTE : the gluTessCallback_<> are tools/glutess specific.
0045 ::gluTessCallback_GLU_TESS_VERTEX_DATA (tobj,vertexCallback);
0046 ::gluTessCallback_GLU_TESS_BEGIN_DATA (tobj,beginCallback);
0047 ::gluTessCallback_GLU_TESS_END_DATA (tobj,endCallback);
0048 ::gluTessCallback_GLU_TESS_ERROR_DATA (tobj,errorCallback);
0049 ::gluTessCallback_GLU_TESS_COMBINE_DATA(tobj,combineCallback);
0050
0051 ::gluTessProperty(tobj,(GLUenum)GLU_TESS_WINDING_RULE,GLU_TESS_WINDING_ODD);
0052
0053 for(unsigned int a=0;a<aContour.size();a++) {
0054 //if(aContour[a][0]!=aContour[a][aContour[a].size()-1]) continue;
0055 if(aContour[a].size()<=1) continue; //should not happen.
0056 size_t vecSize = aContour[a].size()-1;
0057
0058 typedef GLUdouble point[3];
0059 point* tab = new point[vecSize];
0060
0061 ::gluTessBeginPolygon(tobj, this);
0062
0063 ::gluTessBeginContour(tobj);
0064 for(size_t b=0;b<vecSize;b++) {
0065 tab[b][0] = aContour[a][b][0];
0066 tab[b][1] = aContour[a][b][1];
0067 tab[b][2] = aContour[a][b][2];
0068 ::gluTessVertex(tobj, tab[b],tab[b]);
0069 }
0070 ::gluTessEndContour(tobj);
0071
0072 ::gluTessEndPolygon(tobj);
0073
0074 delete [] tab;
0075 }
0076
0077 ::gluDeleteTess(tobj);
0078
0079 for(unsigned int index=0;index<m_combine_tmps.size();index++) {
0080 delete [] m_combine_tmps[index];
0081 }
0082 m_combine_tmps.clear();
0083
0084 if(m_error) m_triangles.clear();
0085 }
0086
0087 protected:
0088 void resetVertex() {m_vertex_number = 0;}
0089 void setBeginType(gl::mode_t aType) {m_begin_type = aType;}
0090 void setError(bool aError) {m_error = aError;}
0091 std::vector<double*>& combineTmps(){return m_combine_tmps;}
0092
0093 void addVertex(const double* vertex) {
0094 // GLU_TRIANGLE_STRIP
0095 // Draws a connected group of triangles. One triangle is defined for each
0096 // vertex presented after the first two vertices. For odd n, vertices n,
0097 // n+1, and n+2 define triangle n. For even n, vertices n+1, n, and n+2
0098 // define triangle n. N-2 triangles are drawn.
0099 if (m_begin_type == gl::triangle_strip()) {
0100 m_tmp.pointC[0] = vertex[0];
0101 m_tmp.pointC[1] = vertex[1];
0102 m_tmp.pointC[2] = vertex[2];
0103
0104 if(m_vertex_number>=2) m_triangles.push_back(m_tmp);
0105
0106 int rest = m_vertex_number % 2;
0107 if(rest==1) {
0108 m_tmp.pointA[0] = vertex[0];
0109 m_tmp.pointA[1] = vertex[1];
0110 m_tmp.pointA[2] = vertex[2];
0111 } else {
0112 m_tmp.pointB[0] = vertex[0];
0113 m_tmp.pointB[1] = vertex[1];
0114 m_tmp.pointB[2] = vertex[2];
0115 }
0116 m_vertex_number++;
0117 }
0118
0119 // GLU_TRIANGLE_FAN
0120 // Draws a connected group of triangles. One triangle is defined for each
0121 // vertex presented after the first two vertices. Vertices 1, n+1,
0122 // and n+2 define triangle n. N-2 triangles are drawn.
0123 else if (m_begin_type == gl::triangle_fan()) {
0124 if (m_vertex_number == 0) {
0125 m_tmp.pointA[0] = vertex[0];
0126 m_tmp.pointA[1] = vertex[1];
0127 m_tmp.pointA[2] = vertex[2];
0128 } else {
0129 m_tmp.pointC[0] = vertex[0];
0130 m_tmp.pointC[1] = vertex[1];
0131 m_tmp.pointC[2] = vertex[2];
0132
0133 if (m_vertex_number >=2 ) {
0134 m_triangles.push_back(m_tmp);
0135 }
0136 m_tmp.pointB[0] = vertex[0];
0137 m_tmp.pointB[1] = vertex[1];
0138 m_tmp.pointB[2] = vertex[2];
0139 }
0140 m_vertex_number++;
0141 }
0142
0143 // GLU_TRIANGLES
0144 // Treats each triplet of vertices as an independent triangle.
0145 // Vertices 3n-2, 3n-1, and 3n define triangle n. N/3 triangles are drawn.
0146 else if (m_begin_type == gl::triangles()) {
0147
0148 int rest = m_vertex_number % 3;
0149
0150 if(rest==2) {
0151 m_tmp.pointC[0] = vertex[0];
0152 m_tmp.pointC[1] = vertex[1];
0153 m_tmp.pointC[2] = vertex[2];
0154
0155 m_triangles.push_back(m_tmp);
0156
0157 } else if(rest==1) {
0158 m_tmp.pointB[0] = vertex[0];
0159 m_tmp.pointB[1] = vertex[1];
0160 m_tmp.pointB[2] = vertex[2];
0161
0162 } else if(rest==0) {
0163 m_tmp.pointA[0] = vertex[0];
0164 m_tmp.pointA[1] = vertex[1];
0165 m_tmp.pointA[2] = vertex[2];
0166 }
0167 m_vertex_number++;
0168
0169 } else {
0170 // do nothing and should never happend
0171 }
0172 }
0173 protected:
0174 #ifdef TOOLS_TESS_CONTOUR_STDCALL
0175 typedef GLUvoid(__stdcall *Func)();
0176 #else
0177 typedef GLUvoid(*Func)();
0178 #endif
0179
0180 static void
0181 #ifdef TOOLS_TESS_CONTOUR_STDCALL
0182 __stdcall
0183 #endif
0184 beginCallback(GLUenum aWhich,GLUvoid * aThis) {
0185 tess_contour* This = (tess_contour*)aThis;
0186 This->setBeginType(aWhich);
0187 This->resetVertex();
0188 }
0189
0190 static void
0191 #ifdef TOOLS_TESS_CONTOUR_STDCALL
0192 __stdcall
0193 #endif
0194 errorCallback(GLUenum aErrorCode,GLUvoid * aThis) {
0195 tess_contour* This = (tess_contour*)aThis;
0196 This->m_out << "tools::tess_contour::errorCallback : " << aErrorCode << std::endl;
0197 This->setError(true);
0198 }
0199
0200 static void
0201 #ifdef TOOLS_TESS_CONTOUR_STDCALL
0202 __stdcall
0203 #endif
0204 endCallback(void*){}
0205
0206 static void
0207 #ifdef TOOLS_TESS_CONTOUR_STDCALL
0208 __stdcall
0209 #endif
0210 vertexCallback(GLUvoid *vertex,GLUvoid* aThis) {
0211 tess_contour* This = (tess_contour*)aThis;
0212 This->addVertex((double*)vertex);
0213 }
0214
0215 static void
0216 #ifdef TOOLS_TESS_CONTOUR_STDCALL
0217 __stdcall
0218 #endif
0219 combineCallback(GLUdouble coords[3],
0220 void* /*vertex_data*/[4],
0221 GLUfloat /*weight*/[4],
0222 void** dataOut,
0223 void* aThis) {
0224 tess_contour* This = (tess_contour*)aThis;
0225 double* vertex = new double[3];
0226 vertex[0] = coords[0];
0227 vertex[1] = coords[1];
0228 vertex[2] = coords[2];
0229 This->combineTmps().push_back(vertex);
0230 *dataOut = vertex;
0231 }
0232
0233 protected:
0234 std::ostream& m_out;
0235 std::vector<tess_triangle>& m_triangles;
0236 tess_triangle m_tmp;
0237 unsigned int m_vertex_number;
0238 gl::mode_t m_begin_type;
0239 bool m_error;
0240 std::vector<double*> m_combine_tmps;
0241 };
0242
0243 }
0244
0245 #endif