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 // NOTE : the gluTessCallback_<> are tools/glutess specific.
0038 ::gluTessCallback_GLU_TESS_VERTEX_DATA (tobj,vertexCallback);
0039 ::gluTessCallback_GLU_TESS_BEGIN_DATA (tobj,beginCallback);
0040 ::gluTessCallback_GLU_TESS_END_DATA (tobj,endCallback);
0041 ::gluTessCallback_GLU_TESS_ERROR_DATA (tobj,errorCallback);
0042 ::gluTessCallback_GLU_TESS_COMBINE_DATA(tobj,combineCallback);
0043
0044 ::gluTessProperty(tobj,(GLUenum)GLU_TESS_WINDING_RULE,GLU_TESS_WINDING_ODD);
0045
0046 for(unsigned int a=0;a<aContour.size();a++) {
0047 if(aContour[a].size()<=1) continue; //should not happen.
0048 size_t vecSize = aContour[a].size()-1;
0049
0050 typedef GLUdouble point[3];
0051 point* tab = new point[vecSize];
0052
0053 ::gluTessBeginPolygon(tobj, this);
0054
0055 ::gluTessBeginContour(tobj);
0056 for(size_t b=0;b<vecSize;b++) {
0057 tab[b][0] = aContour[a][b][0];
0058 tab[b][1] = aContour[a][b][1];
0059 tab[b][2] = aContour[a][b][2];
0060 ::gluTessVertex(tobj, tab[b],tab[b]);
0061 }
0062 ::gluTessEndContour(tobj);
0063
0064 ::gluTessEndPolygon(tobj);
0065
0066 delete [] tab;
0067 }
0068
0069 ::gluDeleteTess(tobj);
0070
0071 for(unsigned int index=0;index<m_combine_tmps.size();index++) {
0072 delete [] m_combine_tmps[index];
0073 }
0074 m_combine_tmps.clear();
0075
0076 if(m_error) m_triangles.clear();
0077 }
0078
0079 protected:
0080 void resetVertex() {m_vertex_number = 0;}
0081 void setBeginType(gl::mode_t aType) {m_begin_type = aType;}
0082 void setError(bool aError) {m_error = aError;}
0083 std::vector<double*>& combineTmps(){return m_combine_tmps;}
0084
0085 void addVertex(const double* vertex) {
0086 // GLU_TRIANGLE_STRIP
0087 // Draws a connected group of triangles. One triangle is defined for each
0088 // vertex presented after the first two vertices. For odd n, vertices n,
0089 // n+1, and n+2 define triangle n. For even n, vertices n+1, n, and n+2
0090 // define triangle n. N-2 triangles are drawn.
0091 if (m_begin_type == gl::triangle_strip()) {
0092 m_tmp.pointC[0] = vertex[0];
0093 m_tmp.pointC[1] = vertex[1];
0094 m_tmp.pointC[2] = vertex[2];
0095
0096 if(m_vertex_number>=2) m_triangles.push_back(m_tmp);
0097
0098 int rest = m_vertex_number % 2;
0099 if(rest==1) {
0100 m_tmp.pointA[0] = vertex[0];
0101 m_tmp.pointA[1] = vertex[1];
0102 m_tmp.pointA[2] = vertex[2];
0103 } else {
0104 m_tmp.pointB[0] = vertex[0];
0105 m_tmp.pointB[1] = vertex[1];
0106 m_tmp.pointB[2] = vertex[2];
0107 }
0108 m_vertex_number++;
0109 }
0110
0111 // GLU_TRIANGLE_FAN
0112 // Draws a connected group of triangles. One triangle is defined for each
0113 // vertex presented after the first two vertices. Vertices 1, n+1,
0114 // and n+2 define triangle n. N-2 triangles are drawn.
0115 else if (m_begin_type == gl::triangle_fan()) {
0116 if (m_vertex_number == 0) {
0117 m_tmp.pointA[0] = vertex[0];
0118 m_tmp.pointA[1] = vertex[1];
0119 m_tmp.pointA[2] = vertex[2];
0120 } else {
0121 m_tmp.pointC[0] = vertex[0];
0122 m_tmp.pointC[1] = vertex[1];
0123 m_tmp.pointC[2] = vertex[2];
0124
0125 if (m_vertex_number >=2 ) {
0126 m_triangles.push_back(m_tmp);
0127 }
0128 m_tmp.pointB[0] = vertex[0];
0129 m_tmp.pointB[1] = vertex[1];
0130 m_tmp.pointB[2] = vertex[2];
0131 }
0132 m_vertex_number++;
0133 }
0134
0135 // GLU_TRIANGLES
0136 // Treats each triplet of vertices as an independent triangle.
0137 // Vertices 3n-2, 3n-1, and 3n define triangle n. N/3 triangles are drawn.
0138 else if (m_begin_type == gl::triangles()) {
0139
0140 int rest = m_vertex_number % 3;
0141
0142 if(rest==2) {
0143 m_tmp.pointC[0] = vertex[0];
0144 m_tmp.pointC[1] = vertex[1];
0145 m_tmp.pointC[2] = vertex[2];
0146
0147 m_triangles.push_back(m_tmp);
0148
0149 } else if(rest==1) {
0150 m_tmp.pointB[0] = vertex[0];
0151 m_tmp.pointB[1] = vertex[1];
0152 m_tmp.pointB[2] = vertex[2];
0153
0154 } else if(rest==0) {
0155 m_tmp.pointA[0] = vertex[0];
0156 m_tmp.pointA[1] = vertex[1];
0157 m_tmp.pointA[2] = vertex[2];
0158 }
0159 m_vertex_number++;
0160
0161 } else {
0162 // do nothing and should never happend
0163 }
0164 }
0165 protected:
0166 typedef GLUvoid(*Func)();
0167
0168 static void
0169 beginCallback(GLUenum aWhich,GLUvoid * aThis) {
0170 tess_contour* This = (tess_contour*)aThis;
0171 This->setBeginType(aWhich);
0172 This->resetVertex();
0173 }
0174
0175 static void
0176 errorCallback(GLUenum aErrorCode,GLUvoid * aThis) {
0177 tess_contour* This = (tess_contour*)aThis;
0178 This->m_out << "tools::tess_contour::errorCallback : " << aErrorCode << std::endl;
0179 This->setError(true);
0180 }
0181
0182 static void
0183 endCallback(void*){}
0184
0185 static void
0186 vertexCallback(GLUvoid *vertex,GLUvoid* aThis) {
0187 tess_contour* This = (tess_contour*)aThis;
0188 This->addVertex((double*)vertex);
0189 }
0190
0191 static void
0192 combineCallback(GLUdouble coords[3],
0193 void* /*vertex_data*/[4],
0194 GLUfloat /*weight*/[4],
0195 void** dataOut,
0196 void* aThis) {
0197 tess_contour* This = (tess_contour*)aThis;
0198 double* vertex = new double[3];
0199 vertex[0] = coords[0];
0200 vertex[1] = coords[1];
0201 vertex[2] = coords[2];
0202 This->combineTmps().push_back(vertex);
0203 *dataOut = vertex;
0204 }
0205
0206 protected:
0207 std::ostream& m_out;
0208 std::vector<tess_triangle>& m_triangles;
0209 tess_triangle m_tmp;
0210 unsigned int m_vertex_number;
0211 gl::mode_t m_begin_type;
0212 bool m_error;
0213 std::vector<double*> m_combine_tmps;
0214 };
0215
0216 }
0217
0218 #endif