Files
geant4/source/analysis/g4tools/include/tools/tess_contour
T
2018-06-29 10:58:11 +02:00

246 lines
7.1 KiB
Plaintext

// Copyright (C) 2010, Guy Barrand. All rights reserved.
// See the file tools.license for terms.
#ifndef tools_tess_contour
#define tools_tess_contour
#include "glutess/glutess"
#include "lina/vec3f"
#include "glprims"
namespace tools {
typedef struct {
double pointA[3];
double pointB[3];
double pointC[3];
} tess_triangle;
class tess_contour {
public:
tess_contour(std::ostream& a_out)
:m_out(a_out),m_vertex_number(0),m_begin_type(gl::triangles()),m_error(false){}
virtual ~tess_contour(){}
protected:
tess_contour(const tess_contour& a_from):m_out(a_from.m_out){}
tess_contour& operator=(const tess_contour&){return *this;}
public:
std::vector<tess_triangle> getFilledArea(const std::vector<std::vector<vec3f> > aContour) {
m_triangles.clear();
m_combine_tmps.clear();
m_error = false;
GLUtesselator* tobj = gluNewTess();
// g++-8.1.0 : the five below lines induce warnings : cast between incompatible function types.
//::gluTessCallback(tobj,(GLUenum)GLU_TESS_VERTEX_DATA, (Func)vertexCallback);
//::gluTessCallback(tobj,(GLUenum)GLU_TESS_BEGIN_DATA, (Func)beginCallback);
//::gluTessCallback(tobj,(GLUenum)GLU_TESS_END_DATA, (Func)endCallback);
//::gluTessCallback(tobj,(GLUenum)GLU_TESS_ERROR_DATA, (Func)errorCallback);
//::gluTessCallback(tobj,(GLUenum)GLU_TESS_COMBINE_DATA,(Func)combineCallback);
// NOTE : the gluTessCallback_<> are inlib/glutess specific.
::gluTessCallback_GLU_TESS_VERTEX_DATA (tobj,vertexCallback);
::gluTessCallback_GLU_TESS_BEGIN_DATA (tobj,beginCallback);
::gluTessCallback_GLU_TESS_END_DATA (tobj,endCallback);
::gluTessCallback_GLU_TESS_ERROR_DATA (tobj,errorCallback);
::gluTessCallback_GLU_TESS_COMBINE_DATA(tobj,combineCallback);
::gluTessProperty(tobj,(GLUenum)GLU_TESS_WINDING_RULE,GLU_TESS_WINDING_ODD);
for(unsigned int a=0;a<aContour.size();a++) {
//if(aContour[a][0]!=aContour[a][aContour[a].size()-1]) continue;
int vecSize = aContour[a].size()-1;
if(vecSize<=0) continue; //should not happen.
typedef GLUdouble point[3];
point* tab = new point[vecSize];
::gluTessBeginPolygon(tobj, this);
::gluTessBeginContour(tobj);
for(unsigned int b=0;b<aContour[a].size()-1;b++) {
tab[b][0] = aContour[a][b][0];
tab[b][1] = aContour[a][b][1];
tab[b][2] = aContour[a][b][2];
::gluTessVertex(tobj, tab[b],tab[b]);
}
::gluTessEndContour(tobj);
::gluTessEndPolygon(tobj);
delete [] tab;
}
::gluDeleteTess(tobj);
for(unsigned int index=0;index<m_combine_tmps.size();index++) {
delete [] m_combine_tmps[index];
}
m_combine_tmps.clear();
if(m_error) m_triangles.clear();
return m_triangles;
}
protected:
void resetVertex() {m_vertex_number = 0;}
void setBeginType(gl::mode_t aType) {m_begin_type = aType;}
void setError(bool aError) {m_error = aError;}
std::vector<double*>& combineTmps(){return m_combine_tmps;}
void addVertex(const double* vertex) {
// GLU_TRIANGLE_STRIP
// Draws a connected group of triangles. One triangle is defined for each
// vertex presented after the first two vertices. For odd n, vertices n,
// n+1, and n+2 define triangle n. For even n, vertices n+1, n, and n+2
// define triangle n. N-2 triangles are drawn.
if (m_begin_type == gl::triangle_strip()) {
m_tmp.pointC[0] = vertex[0];
m_tmp.pointC[1] = vertex[1];
m_tmp.pointC[2] = vertex[2];
if(m_vertex_number>=2) m_triangles.push_back(m_tmp);
int rest = m_vertex_number % 2;
if(rest==1) {
m_tmp.pointA[0] = vertex[0];
m_tmp.pointA[1] = vertex[1];
m_tmp.pointA[2] = vertex[2];
} else {
m_tmp.pointB[0] = vertex[0];
m_tmp.pointB[1] = vertex[1];
m_tmp.pointB[2] = vertex[2];
}
m_vertex_number++;
}
// GLU_TRIANGLE_FAN
// Draws a connected group of triangles. One triangle is defined for each
// vertex presented after the first two vertices. Vertices 1, n+1,
// and n+2 define triangle n. N-2 triangles are drawn.
else if (m_begin_type == gl::triangle_fan()) {
if (m_vertex_number == 0) {
m_tmp.pointA[0] = vertex[0];
m_tmp.pointA[1] = vertex[1];
m_tmp.pointA[2] = vertex[2];
} else {
m_tmp.pointC[0] = vertex[0];
m_tmp.pointC[1] = vertex[1];
m_tmp.pointC[2] = vertex[2];
if (m_vertex_number >=2 ) {
m_triangles.push_back(m_tmp);
}
m_tmp.pointB[0] = vertex[0];
m_tmp.pointB[1] = vertex[1];
m_tmp.pointB[2] = vertex[2];
}
m_vertex_number++;
}
// GLU_TRIANGLES
// Treats each triplet of vertices as an independent triangle.
// Vertices 3n-2, 3n-1, and 3n define triangle n. N/3 triangles are drawn.
else if (m_begin_type == gl::triangles()) {
int rest = m_vertex_number % 3;
if(rest==2) {
m_tmp.pointC[0] = vertex[0];
m_tmp.pointC[1] = vertex[1];
m_tmp.pointC[2] = vertex[2];
m_triangles.push_back(m_tmp);
} else if(rest==1) {
m_tmp.pointB[0] = vertex[0];
m_tmp.pointB[1] = vertex[1];
m_tmp.pointB[2] = vertex[2];
} else if(rest==0) {
m_tmp.pointA[0] = vertex[0];
m_tmp.pointA[1] = vertex[1];
m_tmp.pointA[2] = vertex[2];
}
m_vertex_number++;
} else {
// do nothing and should never happend
}
}
protected:
#ifdef TOOLS_TESS_CONTOUR_STDCALL
typedef GLUvoid(__stdcall *Func)();
#else
typedef GLUvoid(*Func)();
#endif
static void
#ifdef TOOLS_TESS_CONTOUR_STDCALL
__stdcall
#endif
beginCallback(GLUenum aWhich,GLUvoid * aThis) {
tess_contour* This = (tess_contour*)aThis;
This->setBeginType(aWhich);
This->resetVertex();
}
static void
#ifdef TOOLS_TESS_CONTOUR_STDCALL
__stdcall
#endif
errorCallback(GLUenum aErrorCode,GLUvoid * aThis) {
tess_contour* This = (tess_contour*)aThis;
This->m_out << "tools::tess_contour::errorCallback : " << aErrorCode << std::endl;
This->setError(true);
}
static void
#ifdef TOOLS_TESS_CONTOUR_STDCALL
__stdcall
#endif
endCallback(void*){}
static void
#ifdef TOOLS_TESS_CONTOUR_STDCALL
__stdcall
#endif
vertexCallback(GLUvoid *vertex,GLUvoid* aThis) {
tess_contour* This = (tess_contour*)aThis;
This->addVertex((double*)vertex);
}
static void
#ifdef TOOLS_TESS_CONTOUR_STDCALL
__stdcall
#endif
combineCallback(GLUdouble coords[3],
void* /*vertex_data*/[4],
GLUfloat /*weight*/[4],
void** dataOut,
void* aThis) {
tess_contour* This = (tess_contour*)aThis;
double* vertex = new double[3];
vertex[0] = coords[0];
vertex[1] = coords[1];
vertex[2] = coords[2];
This->combineTmps().push_back(vertex);
*dataOut = vertex;
}
protected:
std::ostream& m_out;
tess_triangle m_tmp;
unsigned int m_vertex_number;
gl::mode_t m_begin_type;
bool m_error;
std::vector<tess_triangle> m_triangles;
std::vector<double*> m_combine_tmps;
};
}
#endif