#include "config.h" #ifdef CGAL_POLYHEDRON_DEMO_USE_NEF #include "Nef_type.h" #include #include #include #define GL_MACRO(type) case type: std::cerr << #type; break; inline void CGAL_GLU_TESS_CALLBACK beginCallback(GLenum which) { // std::cerr << "glBegin("; // switch(which) // { // GL_MACRO(GL_POINTS); // GL_MACRO(GL_LINES); // GL_MACRO(GL_LINE_STRIP); // GL_MACRO(GL_LINE_LOOP); // GL_MACRO(GL_TRIANGLES); // GL_MACRO(GL_TRIANGLE_STRIP); // GL_MACRO(GL_TRIANGLE_FAN); // GL_MACRO(GL_QUADS); // GL_MACRO(GL_QUAD_STRIP); // GL_MACRO(GL_POLYGON); // } // std::cerr << ")\n"; glBegin(which); } inline void CGAL_GLU_TESS_CALLBACK endCallback(void) { // std::cerr << "glEnd()\n"; glEnd(); } inline void CGAL_GLU_TESS_CALLBACK errorCallback(GLenum errorCode) { const GLubyte *estring; estring = gluErrorString(errorCode); fprintf(stderr, "Tessellation Error: %s\n", estring); std::exit (0); } inline void CGAL_GLU_TESS_CALLBACK vertexCallback(GLvoid* vertex, GLvoid* user) { GLdouble* pc(static_cast(vertex)); GLdouble* pu(static_cast(user)); // CGAL_NEF_TRACEN("vertexCallback coord "<sncp()) GLboolean old_light_model; ::glGetBooleanv(GL_LIGHT_MODEL_TWO_SIDE, &old_light_model); ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); GLUtesselator* tess_ = ::gluNewTess(); ::gluTessCallback(tess_, GLenum(GLU_TESS_VERTEX_DATA), (GLvoid (CGAL_GLU_TESS_CALLBACK *)(CGAL_GLU_TESS_DOTS)) &vertexCallback); ::gluTessCallback(tess_, GLenum(GLU_TESS_BEGIN), (GLvoid (CGAL_GLU_TESS_CALLBACK *)(CGAL_GLU_TESS_DOTS)) &beginCallback); ::gluTessCallback(tess_, GLenum(GLU_TESS_END), (GLvoid (CGAL_GLU_TESS_CALLBACK *)(CGAL_GLU_TESS_DOTS)) &endCallback); ::gluTessCallback(tess_, GLenum(GLU_TESS_ERROR), (GLvoid (CGAL_GLU_TESS_CALLBACK *)(CGAL_GLU_TESS_DOTS)) &errorCallback); ::gluTessProperty(tess_, GLenum(GLU_TESS_WINDING_RULE), GLU_TESS_WINDING_POSITIVE); for(Nef_polyhedron::Halffacet_const_iterator f = p->halffacets_begin (), end = p->halffacets_end(); f != end; ++f) { if(f->is_twin()) continue; Nef_polyhedron::Vector_3 v = f->plane().orthogonal_vector(); GLdouble normal[3]; normal[0] = CGAL::to_double(v.x()); normal[1] = CGAL::to_double(v.y()); normal[2] = CGAL::to_double(v.z()); GLdouble norm = normal[0]*normal[0] + normal[1]*normal[1] + normal[2]*normal[2]; norm = CGAL::sqrt(norm); normal[0] /= norm; normal[1] /= norm; normal[2] /= norm; ::gluTessBeginPolygon(tess_, normal); ::gluTessNormal(tess_,normal[0],normal[1],normal[2]); QList points; for(Nef_polyhedron::Halffacet_cycle_const_iterator fc = f->facet_cycles_begin(), end = f->facet_cycles_end(); fc != end; ++fc) { if ( fc.is_shalfedge() ) { ::gluTessBeginContour(tess_); Nef_polyhedron::SHalfedge_const_handle h = fc; Nef_polyhedron::SHalfedge_around_facet_const_circulator hc(h), he(hc); CGAL_For_all(hc,he){ // all vertex coordinates in facet cycle Nef_polyhedron::SVertex_const_handle v = hc->source(); const Nef_polyhedron::Point_3& point = v->source()->point(); int i = points.size(); DPoint dp; points.push_back(dp); points[i].coords[0] = CGAL::to_double(point.x()); points[i].coords[1] = CGAL::to_double(point.y()); points[i].coords[2] = CGAL::to_double(point.z()); ::gluTessVertex(tess_, static_cast(static_cast(&(points[i].coords))), &(points[i].coords)); } // end facet cycles verticeses ::gluTessEndContour(tess_); } } // end facet cycles ::gluTessEndPolygon(tess_); } // end facets ::gluDeleteTess(tess_); ::glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, old_light_model); GLenum gl_error = ::glGetError(); if(gl_error != GL_NO_ERROR) { std::cerr << "OPENGL ERROR in gl_render_nef_facets!\n " << ::gluErrorString(gl_error) << "\n"; } } // end gl_render_nef_facets void gl_render_nef_edges(Nef_polyhedron *p) { ::glBegin(GL_LINES); for(Nef_polyhedron::Halfedge_const_iterator e = p->halfedges_begin(), end = p->halfedges_end(); e != end; ++e) { const Nef_polyhedron::Vertex_const_handle& s = e->source(); const Nef_polyhedron::Vertex_const_handle& t = e->twin()->source(); const Nef_polyhedron::Point_3& a = s->point(); const Nef_polyhedron::Point_3& b = t->point(); ::glVertex3d(CGAL::to_double(a.x()), CGAL::to_double(a.y()), CGAL::to_double(a.z())); ::glVertex3d(CGAL::to_double(b.x()), CGAL::to_double(b.y()), CGAL::to_double(b.z())); } ::glEnd(); GLenum gl_error = ::glGetError(); if(gl_error != GL_NO_ERROR) { std::cerr << "OPENGL ERROR in gl_render_nef_edges!\n " << ::gluErrorString(gl_error) << "\n"; } } void gl_render_nef_vertices(Nef_polyhedron* p) { ::glBegin(GL_POINTS); for(Nef_polyhedron::Vertex_const_iterator v = p->vertices_begin(), end = p->vertices_end(); v != end; ++v) { const Nef_polyhedron::Point_3& p = v->point(); ::glVertex3d(CGAL::to_double(p.x()), CGAL::to_double(p.y()), CGAL::to_double(p.z())); } ::glEnd(); GLenum gl_error = ::glGetError(); if(gl_error != GL_NO_ERROR) { std::cerr << "OPENGL ERROR in gl_render_nef_vertices!\n " << ::gluErrorString(gl_error) << "\n"; } } #endif // CGAL_POLYHEDRON_DEMO_USE_NEF