diff --git a/GraphicsView/include/CGAL/Buffer_for_vao.h b/GraphicsView/include/CGAL/Buffer_for_vao.h index b7658d45021..a0148cd4c0b 100644 --- a/GraphicsView/include/CGAL/Buffer_for_vao.h +++ b/GraphicsView/include/CGAL/Buffer_for_vao.h @@ -426,25 +426,7 @@ public: const Local_point& S=facet[id]; const Local_point& T=facet[(id+1==facet.size())?0:id+1]; Local_vector V1=Local_vector((T-S).x(), (T-S).y(), (T-S).z()); - if(std::isnan(S.x()) || - std::isnan(S.y()) || - std::isnan(S.z())) - { - return false; - } - if(std::isnan(T.x()) || - std::isnan(T.y()) || - std::isnan(T.z())) - { - return false; - } - const Local_point& U=facet[(id+2==facet.size())?0:id+2]; - if(std::isnan(U.x()) || - std::isnan(U.y()) || - std::isnan(U.z())) - { - return false; - } + const Local_point& U=facet[(id+2>=facet.size())?id+2-facet.size():id+2]; Local_vector V2=Local_vector((U-T).x(), (U-T).y(), (U-T).z()); orientation = Local_kernel::Orientation_3()(V1, V2, normal); @@ -465,7 +447,7 @@ public: const Local_point& T=facet[(id+1==facet.size())?0:id+1]; Local_vector V1=Local_vector((T-S).x(), (T-S).y(), (T-S).z()); - const Local_point& U=facet[(id+2==facet.size())?0:id+2]; + const Local_point& U=facet[(id+2>=facet.size())?id+2-facet.size():id+2]; Local_vector V2=Local_vector((U-T).x(), (U-T).y(), (U-T).z()); local_orientation=Local_kernel::Orientation_3()(V1, V2, normal) ; diff --git a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h index de17e0d32f5..18213239d26 100644 --- a/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h +++ b/GraphicsView/include/CGAL/Qt/Basic_viewer_qt.h @@ -740,7 +740,7 @@ protected: setKeyDescription(::Qt::Key_E, "Toggles edges display"); setKeyDescription(::Qt::Key_F, "Toggles faces display"); setKeyDescription(::Qt::Key_G, "Switch between flat/Gouraud shading display"); - setKeyDescription(::Qt::Key_M, "Toggles mono color for all faces"); + setKeyDescription(::Qt::Key_M, "Toggles mono color"); setKeyDescription(::Qt::Key_N, "Inverse direction of normals"); setKeyDescription(::Qt::Key_V, "Toggles vertices display"); setKeyDescription(::Qt::Key_Plus, "Increase size of edges"); @@ -935,8 +935,11 @@ protected: } virtual QString helpString() const + { return helpString("CGAL Basic Viewer"); } + + virtual QString helpString(const char* title) const { - QString text("

C G A L B a s i c V i e w e r

"); + QString text(QString("

")+QString(title)+QString("

")); text += "Use the mouse to move the camera around the object. "; text += "You can respectively revolve around, zoom and translate with " "the three mouse buttons. "; @@ -966,7 +969,7 @@ protected: return text; } -private: +protected: bool m_draw_vertices; bool m_draw_edges; bool m_draw_faces; diff --git a/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt b/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt index 108432031ff..d23afa5eb3d 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt +++ b/Linear_cell_complex/demo/Linear_cell_complex/CMakeLists.txt @@ -46,7 +46,7 @@ if ( NOT (CGAL_FOUND AND CGAL_Qt5_FOUND AND Qt5_FOUND ) ) else() -add_definitions(-DQT_NO_KEYWORDS) +add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS) # ui file, created wih Qt Designer qt5_wrap_ui(uis MainWindow.ui CreateMesh.ui CreateMenger.ui @@ -64,7 +64,7 @@ add_executable(Linear_cell_complex_3_demo add_to_cached_list(CGAL_EXECUTABLE_TARGETS Linear_cell_complex_3_demo) -target_link_libraries(Linear_cell_complex_3_demo PRIVATE +target_link_libraries(Linear_cell_complex_3_demo PUBLIC CGAL::CGAL CGAL::CGAL_Qt5 Qt5::Gui Qt5::OpenGL) include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake) diff --git a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp index a78780d3e78..e2713d93608 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp +++ b/Linear_cell_complex/demo/Linear_cell_complex/MainWindow.cpp @@ -39,7 +39,7 @@ void subdivide_lcc_pqq (LCC & m); #define DELAY_STATUSMSG 1500 -MainWindow::MainWindow (QWidget * parent):CGAL::Qt::DemosMainWindow (parent), +MainWindow::MainWindow (QWidget * parent) : CGAL::Qt::DemosMainWindow (parent), nbcube (0), dialogmesh (this), dialogmenger(this), @@ -78,7 +78,7 @@ MainWindow::MainWindow (QWidget * parent):CGAL::Qt::DemosMainWindow (parent), QObject::connect(&dialogmesh, SIGNAL(accepted()), this, SLOT(onCreateMeshOk())); - this->viewer->setScene(&scene); + this->viewer->setScene(&scene, false); connect_actions (); this->addAboutDemo (":/cgal/help/about_Linear_cell_complex_3.html"); diff --git a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp index 3bef476f899..018d0bdad69 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp +++ b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.cpp @@ -19,928 +19,44 @@ // Author(s) : Guillaume Damiand // Contributor(s): Kumar Snehasish // + #include "Viewer.h" - -#include -#include -#include -#include - #include -#include -//Vertex source code -const char vertex_source[] = - { - "#version 120 \n" - "attribute highp vec4 vertex;\n" - "attribute highp vec3 normal;\n" - "attribute highp vec3 color;\n" +Viewer::Viewer(QWidget* parent) : + Base(parent, NULL, ""), + m_previous_scene_empty(true) +{} - "uniform highp mat4 mvp_matrix;\n" - "uniform highp mat4 mv_matrix; \n" - "uniform highp float point_size; \n" - - "varying highp vec4 fP; \n" - "varying highp vec3 fN; \n" - "varying highp vec4 fColor; \n" - "void main(void)\n" - "{\n" - " gl_PointSize = point_size; \n" - " fP = mv_matrix * vertex; \n" - " fN = mat3(mv_matrix)* normal; \n" - " fColor = vec4(color, 1.0); \n" - " gl_Position = mvp_matrix * vertex;\n" - "}" - }; - -//Vertex source code -const char fragment_source[] = - { - "#version 120 \n" - "varying highp vec4 fP; \n" - "varying highp vec3 fN; \n" - "varying highp vec4 fColor; \n" - "uniform vec4 light_pos; \n" - "uniform vec4 light_diff; \n" - "uniform vec4 light_spec; \n" - "uniform vec4 light_amb; \n" - "uniform float spec_power ; \n" - - "void main(void) { \n" - - " vec3 L = light_pos.xyz - fP.xyz; \n" - " vec3 V = -fP.xyz; \n" - - " vec3 N = normalize(fN); \n" - " L = normalize(L); \n" - " V = normalize(V); \n" - - " vec3 R = reflect(-L, N); \n" - " vec4 diffuse = max(dot(N,L), 0.0) * light_diff * fColor; \n" - " vec4 specular = pow(max(dot(R,V), 0.0), spec_power) * light_spec; \n" - - "gl_FragColor = light_amb*fColor + diffuse ; \n" - "} \n" - "\n" - }; - -//Vertex source code -const char vertex_source_p_l[] = - { - "#version 120 \n" - "attribute highp vec4 vertex;\n" - "uniform highp mat4 mvp_matrix;\n" - "uniform highp float point_size; \n" - "void main(void)\n" - "{\n" - " gl_PointSize = point_size; \n" - " gl_Position = mvp_matrix * vertex;\n" - "}" - }; -//Vertex source code -const char fragment_source_p_l[] = - { - "#version 120 \n" - "uniform highp vec4 color; \n" - "void main(void) { \n" - "gl_FragColor = color; \n" - "} \n" - "\n" - }; - -Viewer::Viewer(QWidget* parent) - : CGAL::QGLViewer(parent), - wireframe(false), - flatShading(true), - edges(true), - vertices(true), - inverse_normal(false), - size_points(7.), - size_edges(3.1), - ambient(0.6f, 0.5f, 0.5f, 0.5f), - m_previous_scene_empty(true), - are_buffers_initialized(false) +void Viewer::setScene(Scene* scene_, bool doredraw) { -} - -Viewer::~Viewer() -{ - for (int i=0; icompileSourceCode(vertex_source)) - { - std::cerr<<"Compiling vertex source FAILED"<compileSourceCode(fragment_source)) - { - std::cerr<<"Compiling fragmentsource FAILED"<compileSourceCode(vertex_source_p_l)) - { - std::cerr<<"Compiling vertex source FAILED"<compileSourceCode(fragment_source_p_l)) - { - std::cerr<<"Compiling fragmentsource FAILED"<(pos_facets.size()*sizeof(float))); - vertexLocation[0] = rendering_program.attributeLocation("vertex"); - rendering_program.bind(); - rendering_program.enableAttributeArray(vertexLocation[0]); - rendering_program.setAttributeBuffer(vertexLocation[0],GL_FLOAT,0,3); - rendering_program.release(); - buffers[0].release(); - - //normals of the facets - buffers[1].bind(); - buffers[1].allocate(flat_normals.data(), - static_cast(flat_normals.size()*sizeof(float))); - normalsLocation = rendering_program.attributeLocation("normal"); - rendering_program.bind(); - rendering_program.enableAttributeArray(normalsLocation); - rendering_program.setAttributeBuffer(normalsLocation,GL_FLOAT,0,3); - buffers[1].release(); - - //colors of the facets - buffers[2].bind(); - buffers[2].allocate(colors.data(), - static_cast(colors.size()*sizeof(float))); - colorsLocation = rendering_program.attributeLocation("color"); - rendering_program.bind(); - rendering_program.enableAttributeArray(colorsLocation); - rendering_program.setAttributeBuffer(colorsLocation,GL_FLOAT,0,3); - buffers[2].release(); - rendering_program.release(); - - vao[0].release(); - vao[1].bind(); - - //points of the facets - buffers[3].bind(); - buffers[3].allocate(pos_facets.data(), static_cast(pos_facets.size()*sizeof(float))); - vertexLocation[0] = rendering_program.attributeLocation("vertex"); - rendering_program.bind(); - rendering_program.enableAttributeArray(vertexLocation[0]); - rendering_program.setAttributeBuffer(vertexLocation[0],GL_FLOAT,0,3); - rendering_program.release(); - buffers[3].release(); - - //normals of the facets - buffers[4].bind(); - buffers[4].allocate(smooth_normals.data(), - static_cast(smooth_normals.size()*sizeof(float))); - normalsLocation = rendering_program.attributeLocation("normal"); - rendering_program.bind(); - rendering_program.enableAttributeArray(normalsLocation); - rendering_program.setAttributeBuffer(normalsLocation,GL_FLOAT,0,3); - buffers[4].release(); - - //colors of the facets - buffers[5].bind(); - buffers[5].allocate(colors.data(), static_cast(colors.size()*sizeof(float))); - colorsLocation = rendering_program.attributeLocation("color"); - rendering_program.bind(); - rendering_program.enableAttributeArray(colorsLocation); - rendering_program.setAttributeBuffer(colorsLocation,GL_FLOAT,0,3); - buffers[5].release(); - rendering_program.release(); - - vao[1].release(); - - //The lines - vao[2].bind(); - buffers[6].bind(); - buffers[6].allocate(pos_lines.data(), static_cast(pos_lines.size()*sizeof(float))); - vertexLocation[2] = rendering_program_p_l.attributeLocation("vertex"); - rendering_program_p_l.bind(); - rendering_program_p_l.enableAttributeArray(vertexLocation[2]); - rendering_program_p_l.setAttributeBuffer(vertexLocation[2],GL_FLOAT,0,3); - buffers[6].release(); - rendering_program_p_l.release(); - vao[2].release(); - - //The points - vao[3].bind(); - buffers[7].bind(); - buffers[7].allocate(pos_points.data(), static_cast(pos_points.size()*sizeof(float))); - vertexLocation[2] = rendering_program_p_l.attributeLocation("vertex"); - rendering_program_p_l.bind(); - rendering_program_p_l.enableAttributeArray(vertexLocation[2]); - rendering_program_p_l.setAttributeBuffer(vertexLocation[2],GL_FLOAT,0,3); - buffers[7].release(); - rendering_program_p_l.release(); - vao[3].release(); - - are_buffers_initialized = true; -} - -void Viewer::compute_face(Dart_handle dh, LCC::size_type markface) -{ - LCC &lcc = *scene->lcc; - - CGAL::mark_cell(lcc, dh, markface); - - double r = (double)lcc.info<3>(dh).color().r()/255.0; - double g = (double)lcc.info<3>(dh).color().g()/255.0; - double b = (double)lcc.info<3>(dh).color().b()/255.0; - if ( !lcc.is_free(dh, 3) ) - { - r += (double)lcc.info<3>(lcc.beta(dh,3)).color().r()/255.0; - g += (double)lcc.info<3>(lcc.beta(dh,3)).color().g()/255.0; - b += (double)lcc.info<3>(lcc.beta(dh,3)).color().b()/255.0; - r /= 2; g /= 2; b /= 2; - } - - //compute flat normals - LCC::Vector normal = CGAL::compute_normal_of_cell_2(lcc,dh); - normal = normal/(CGAL::sqrt(normal*normal)); - if (inverse_normal) - normal=normal*-1; - - if (lcc.beta<1,1,1>(dh)!=dh) - { - try // Try catch to avoir crash of triangulation - { - P_traits cdt_traits(normal); - CDT cdt(cdt_traits); - - // Iterates on the vector of facet handles - CDT::Vertex_handle previous = NULL, first = NULL; - for (LCC::Dart_of_orbit_range<1>::const_iterator - he_circ = lcc.darts_of_orbit<1>(dh).begin(), - he_circ_end = lcc.darts_of_orbit<1>(dh).end(); - he_circ!=he_circ_end; ++he_circ) - { - CDT::Vertex_handle vh = cdt.insert(lcc.point(he_circ)); - if(first == NULL) - { first = vh; } - vh->info().v = CGAL::compute_normal_of_cell_0(lcc, he_circ); - if (inverse_normal) vh->info().v=vh->info().v*-1; - if(previous!=NULL && previous != vh) - { cdt.insert_constraint(previous, vh); } - previous = vh; - } - if (previous!=NULL) - cdt.insert_constraint(previous, first); - - // sets mark is_external - for(CDT::All_faces_iterator fit = cdt.all_faces_begin(), - fitend = cdt.all_faces_end(); fit!=fitend; ++fit) - { - fit->info().is_external = true; - fit->info().is_process = false; - } - //check if the facet is external or internal - std::queue face_queue; - CDT::Face_handle face_internal = NULL; - face_queue.push(cdt.infinite_vertex()->face()); - while(! face_queue.empty() ) - { - CDT::Face_handle fh = face_queue.front(); - face_queue.pop(); - if(!fh->info().is_process) - { - fh->info().is_process = true; - for(int i = 0; i <3; ++i) - { - if(!cdt.is_constrained(std::make_pair(fh, i))) - { - face_queue.push(fh->neighbor(i)); - } - else if (face_internal==NULL) - { - face_internal = fh->neighbor(i); - } - } - } - } - - if ( face_internal!=NULL ) - face_queue.push(face_internal); - - while(! face_queue.empty() ) - { - CDT::Face_handle fh = face_queue.front(); - face_queue.pop(); - if(!fh->info().is_process) - { - fh->info().is_process = true; - fh->info().is_external = false; - for(int i = 0; i <3; ++i) - { - if(!cdt.is_constrained(std::make_pair(fh, i))) - { - face_queue.push(fh->neighbor(i)); - } - } - } - } - - //iterates on the internal faces to add the vertices to the positions - //and the normals to the appropriate vectors - for(CDT::Finite_faces_iterator ffit = cdt.finite_faces_begin(), - ffitend = cdt.finite_faces_end(); ffit != ffitend; ++ffit) - { - if(!ffit->info().is_external) - { - flat_normals.push_back(normal.x()); - flat_normals.push_back(normal.y()); - flat_normals.push_back(normal.z()); - - flat_normals.push_back(normal.x()); - flat_normals.push_back(normal.y()); - flat_normals.push_back(normal.z()); - - flat_normals.push_back(normal.x()); - flat_normals.push_back(normal.y()); - flat_normals.push_back(normal.z()); - - smooth_normals.push_back(ffit->vertex(0)->info().v.x()); - smooth_normals.push_back(ffit->vertex(0)->info().v.y()); - smooth_normals.push_back(ffit->vertex(0)->info().v.z()); - - smooth_normals.push_back(ffit->vertex(1)->info().v.x()); - smooth_normals.push_back(ffit->vertex(1)->info().v.y()); - smooth_normals.push_back(ffit->vertex(1)->info().v.z()); - - smooth_normals.push_back(ffit->vertex(2)->info().v.x()); - smooth_normals.push_back(ffit->vertex(2)->info().v.y()); - smooth_normals.push_back(ffit->vertex(2)->info().v.z()); - - pos_facets.push_back(ffit->vertex(0)->point().x()); - pos_facets.push_back(ffit->vertex(0)->point().y()); - pos_facets.push_back(ffit->vertex(0)->point().z()); - - pos_facets.push_back(ffit->vertex(1)->point().x()); - pos_facets.push_back(ffit->vertex(1)->point().y()); - pos_facets.push_back(ffit->vertex(1)->point().z()); - - pos_facets.push_back(ffit->vertex(2)->point().x()); - pos_facets.push_back(ffit->vertex(2)->point().y()); - pos_facets.push_back(ffit->vertex(2)->point().z()); - - colors.push_back(r);colors.push_back(g);colors.push_back(b); - colors.push_back(r);colors.push_back(g);colors.push_back(b); - colors.push_back(r);colors.push_back(g);colors.push_back(b); - } - } - } - catch(...) - { // Triangulation crash: the face is not filled - } - } - else - { // The face is a triangle - colors.push_back(r);colors.push_back(g);colors.push_back(b); - colors.push_back(r);colors.push_back(g);colors.push_back(b); - colors.push_back(r);colors.push_back(g);colors.push_back(b); - - flat_normals.push_back(normal.x()); - flat_normals.push_back(normal.y()); - flat_normals.push_back(normal.z()); - - flat_normals.push_back(normal.x()); - flat_normals.push_back(normal.y()); - flat_normals.push_back(normal.z()); - - flat_normals.push_back(normal.x()); - flat_normals.push_back(normal.y()); - flat_normals.push_back(normal.z()); - - for (LCC::Dart_of_orbit_range<1>::const_iterator - orbitIter = lcc.darts_of_orbit<1>(dh).begin(); - orbitIter.cont(); ++orbitIter) - { - //compute Smooth normals - LCC::Vector normal = CGAL::compute_normal_of_cell_0(lcc,orbitIter); - normal = normal/(CGAL::sqrt(normal*normal)); - if (inverse_normal) normal=normal*-1; - - smooth_normals.push_back(normal.x()); - smooth_normals.push_back(normal.y()); - smooth_normals.push_back(normal.z()); - - const LCC::Point& p = lcc.point(orbitIter); - pos_facets.push_back(p.x()); - pos_facets.push_back(p.y()); - pos_facets.push_back(p.z()); - } - } -} - -void Viewer::compute_edge(Dart_handle dh, LCC::size_type markedge) -{ - LCC &lcc = *scene->lcc; - - CGAL::mark_cell(lcc, dh, markedge); - - const LCC::Point& p = lcc.point(dh); - Dart_handle d2 = lcc.other_extremity(dh); - if ( d2!=NULL ) - { - const LCC::Point& p2 = lcc.point(d2); - pos_lines.push_back(p.x()); - pos_lines.push_back(p.y()); - pos_lines.push_back(p.z()); - - pos_lines.push_back(p2.x()); - pos_lines.push_back(p2.y()); - pos_lines.push_back(p2.z()); - } -} - -void Viewer::compute_vertex(Dart_handle dh, LCC::size_type markvertex, bool& empty) -{ - LCC &lcc = *scene->lcc; - - CGAL::mark_cell(lcc, dh, markvertex); - - const LCC::Point& p = lcc.point(dh); - pos_points.push_back(p.x()); - pos_points.push_back(p.y()); - pos_points.push_back(p.z()); - - if ( empty ) - { - bb = p.bbox(); - empty = false; - } - else - bb = bb + p.bbox(); -} - -void Viewer::compute_elements() -{ - LCC &lcc = *scene->lcc; - - pos_facets.clear(); - flat_normals.clear(); - smooth_normals.clear(); - colors.clear(); - pos_lines.clear(); - pos_points.clear(); - - if ( lcc.is_empty() ) - { - bb = LCC::Point(CGAL::ORIGIN).bbox(); - bb = bb + LCC::Point(1,1,1).bbox(); // To avoid a warning from Qglviewer - return; - } - - LCC::size_type markvertex = lcc.get_new_mark(); - LCC::size_type markedge = lcc.get_new_mark(); - LCC::size_type markface = lcc.get_new_mark(); - - bool empty = true; - for (LCC::Attribute_range<3>::type::iterator it=lcc.attributes<3>().begin(), - itend=lcc.attributes<3>().end(); it!=itend; ++it ) - { - if ( it->info().is_visible() ) - { - for(LCC::Dart_of_cell_range<3>::iterator - dartIter=lcc.darts_of_cell<3>(lcc.dart_of_attribute<3>(it)).begin(); - dartIter.cont(); ++dartIter) - { - if ( it->info().is_filled() && !lcc.is_marked(dartIter, markface) ) - compute_face(dartIter, markface); - - if ( !lcc.is_marked(dartIter, markedge) ) - compute_edge(dartIter, markedge); - - if ( !lcc.is_marked(dartIter, markvertex) ) - compute_vertex(dartIter, markvertex, empty); - } - } - } - - if ( empty ) - { - bb = LCC::Point(CGAL::ORIGIN).bbox(); - bb = bb + LCC::Point(1,1,1).bbox(); // To avoid a warning from Qglviewer - } - - for (LCC::Dart_range::iterator it=lcc.darts().begin(), - itend=lcc.darts().end(); it!=itend; ++it ) - { - lcc.unmark(it, markvertex); - lcc.unmark(it, markedge); - lcc.unmark(it, markface); - } - - lcc.free_mark(markvertex); - lcc.free_mark(markedge); - lcc.free_mark(markface); -} - -void Viewer::attrib_buffers(CGAL::QGLViewer* viewer) -{ - QMatrix4x4 mvpMatrix; - QMatrix4x4 mvMatrix; - double mat[16]; - viewer->camera()->getModelViewProjectionMatrix(mat); - for(int i=0; i < 16; i++) - { - mvpMatrix.data()[i] = (float)mat[i]; - } - viewer->camera()->getModelViewMatrix(mat); - for(int i=0; i < 16; i++) - { - mvMatrix.data()[i] = (float)mat[i]; - } - // define material - QVector4D diffuse( 0.9f, - 0.9f, - 0.9f, - 0.9f ); - - QVector4D specular( 0.0f, - 0.0f, - 0.0f, - 1.0f ); - - - QVector4D position((bb.xmax()-bb.xmin())/2, (bb.ymax()-bb.ymin())/2,bb.zmax(), 0.0 ); - GLfloat shininess = 1.0f; - - rendering_program.bind(); - mvpLocation[0] = rendering_program.uniformLocation("mvp_matrix"); - mvLocation = rendering_program.uniformLocation("mv_matrix"); - lightLocation[0] = rendering_program.uniformLocation("light_pos"); - lightLocation[1] = rendering_program.uniformLocation("light_diff"); - lightLocation[2] = rendering_program.uniformLocation("light_spec"); - lightLocation[3] = rendering_program.uniformLocation("light_amb"); - lightLocation[4] = rendering_program.uniformLocation("spec_power"); - - rendering_program.setUniformValue(lightLocation[0], position); - rendering_program.setUniformValue(lightLocation[1], diffuse); - rendering_program.setUniformValue(lightLocation[2], specular); - rendering_program.setUniformValue(lightLocation[3], ambient); - rendering_program.setUniformValue(lightLocation[4], shininess); - rendering_program.setUniformValue(mvpLocation[0], mvpMatrix); - rendering_program.setUniformValue(mvLocation, mvMatrix); - - rendering_program.release(); - rendering_program_p_l.bind(); - mvpLocation[1] = rendering_program_p_l.uniformLocation("mvp_matrix"); - colorLocation = rendering_program_p_l.uniformLocation("color"); - rendering_program.setUniformValue(mvpLocation[1], mvpMatrix); - rendering_program_p_l.release(); + scene = scene_; + set_lcc(scene->lcc, doredraw); } void Viewer::sceneChanged() { - compute_elements(); - this->camera()->setSceneBoundingBox(CGAL::qglviewer::Vec(bb.xmin(), - bb.ymin(), - bb.zmin()), - CGAL::qglviewer::Vec(bb.xmax(), - bb.ymax(), - bb.zmax())); - are_buffers_initialized = false; - + Base::compute_elements(); + this->camera()-> + setSceneBoundingBox(CGAL::qglviewer::Vec(m_bounding_box.xmin(), + m_bounding_box.ymin(), + m_bounding_box.zmin()), + CGAL::qglviewer::Vec(m_bounding_box.xmax(), + m_bounding_box.ymax(), + m_bounding_box.zmax())); + Base::redraw(); if (m_previous_scene_empty) - this->showEntireScene(); - else - this->update(); + { this->showEntireScene(); } m_previous_scene_empty = scene->lcc->is_empty(); // for the next call to sceneChanged } -void Viewer::draw() -{ - if(scene) - { - glEnable(GL_DEPTH_TEST); - if(!are_buffers_initialized) - initialize_buffers(); - - QColor color; - if ( !wireframe ) - { - if(flatShading) - { - vao[0].bind(); - attrib_buffers(this); - rendering_program.bind(); - glDrawArrays(GL_TRIANGLES, 0, static_cast(pos_facets.size()/3)); - rendering_program.release(); - vao[0].release(); - } - else - { - vao[1].bind(); - attrib_buffers(this); - rendering_program.bind(); - glDrawArrays(GL_TRIANGLES, 0, static_cast(pos_facets.size()/3)); - rendering_program.release(); - vao[1].release(); - } - } - if(edges) - { - vao[2].bind(); - attrib_buffers(this); - color.setRgbF(0.2f, 0.2f, 0.7f); - rendering_program_p_l.bind(); - rendering_program_p_l.setAttributeValue(colorLocation,color); - glLineWidth(size_edges); - glDrawArrays(GL_LINES, 0, static_cast(pos_lines.size()/3)); - rendering_program_p_l.release(); - vao[2].release(); - } - if(vertices) - { - vao[3].bind(); - attrib_buffers(this); - color.setRgbF(.2f,.2f,.6f); - rendering_program_p_l.bind(); - rendering_program_p_l.setAttributeValue(colorLocation,color); - rendering_program_p_l.setUniformValue("point_size", GLfloat(size_points)); - glDrawArrays(GL_POINTS, 0, static_cast(pos_points.size()/3)); - rendering_program_p_l.release(); - vao[3].release(); - } - } -} -void Viewer::init() -{ - // Restore previous viewer state. - restoreStateFromFile(); - initializeOpenGLFunctions(); - // Define 'Control+Q' as the new exit shortcut (default was 'Escape') - setShortcut(CGAL::qglviewer::EXIT_VIEWER, Qt::CTRL+Qt::Key_Q); - - // Add custom key description (see keyPressEvent). - setKeyDescription(Qt::Key_W, "Toggles wire frame display"); - setKeyDescription(Qt::Key_F, "Toggles flat shading display"); - setKeyDescription(Qt::Key_E, "Toggles edges display"); - setKeyDescription(Qt::Key_V, "Toggles vertices display"); - setKeyDescription(Qt::Key_N, "Inverse direction of normals"); - setKeyDescription(Qt::Key_Plus, "Increase size of edges"); - setKeyDescription(Qt::Key_Minus, "Decrease size of edges"); - setKeyDescription(Qt::Key_Plus+Qt::ShiftModifier, "Increase size of vertices"); - setKeyDescription(Qt::Key_Minus+Qt::ShiftModifier, "Decrease size of vertices"); - setKeyDescription(Qt::Key_PageDown, "Increase light (all colors, use shift/alt/ctrl for one rgb component)"); - setKeyDescription(Qt::Key_PageUp, "Decrease light (all colors, use shift/alt/ctrl for one rgb component)"); - - // Light default parameters - glLineWidth(size_edges); - glEnable(GL_POLYGON_OFFSET_FILL); - glPolygonOffset(1.0f,1.0f); - glClearColor(1.0f,1.0f,1.0f,0.0f); - - glDisable(GL_BLEND); - glDisable(GL_LINE_SMOOTH); - glDisable(GL_POLYGON_SMOOTH_HINT); - glBlendFunc(GL_ONE, GL_ZERO); - glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST); - compile_shaders(); -} - void Viewer::keyPressEvent(QKeyEvent *e) { - const Qt::KeyboardModifiers modifiers = e->modifiers(); - - if ((e->key()==Qt::Key_W) && (modifiers==Qt::NoButton)) - { - wireframe = !wireframe; - if (wireframe) - { - displayMessage("Wireframe."); - } - else - { - displayMessage("Filled faces."); - } - update(); - } - else if ((e->key()==Qt::Key_F) && (modifiers==Qt::NoButton)) - { - flatShading = !flatShading; - if (flatShading) - displayMessage("Flat shading."); - else - displayMessage("Gouraud shading."); - - update(); - - } - else if ((e->key()==Qt::Key_E) && (modifiers==Qt::NoButton)) - { - edges = !edges; - displayMessage(QString("Draw edges=%1.").arg(edges?"true":"false")); - - update(); - } - else if ((e->key()==Qt::Key_V) && (modifiers==Qt::NoButton)) - { - vertices = !vertices; - displayMessage(QString("Draw vertices=%1.").arg(vertices?"true":"false")); - update(); - } - else if ((e->key()==Qt::Key_N) && (modifiers==Qt::NoButton)) - { - inverse_normal = !inverse_normal; - displayMessage(QString("Inverse normal=%1.").arg(inverse_normal?"true":"false")); - sceneChanged(); - } - else if ((e->key()==Qt::Key_Plus) && (modifiers==Qt::KeypadModifier)) - { - size_edges+=.5; - displayMessage(QString("Size of edges=%1.").arg(size_edges)); - update(); - } - else if ((e->key()==Qt::Key_Minus) && (modifiers==Qt::KeypadModifier)) - { - if (size_edges>.5) size_edges-=.5; - displayMessage(QString("Size of edges=%1.").arg(size_edges)); - update(); - } - else if ((e->key()==Qt::Key_Plus) && (modifiers==(Qt::ShiftModifier|Qt::KeypadModifier))) - { - size_points+=.5; - displayMessage(QString("Size of points=%1.").arg(size_points)); - update(); - } - else if ((e->key()==Qt::Key_Minus) && (modifiers==(Qt::ShiftModifier|Qt::KeypadModifier))) - { - if (size_points>.5) size_points-=.5; - displayMessage(QString("Size of points=%1.").arg(size_points)); - update(); - } - else if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) - { - ambient.setX(ambient.x()+.1); - if (ambient.x()>1.) ambient.setX(1.); - ambient.setY(ambient.x()+.1); - if (ambient.y()>1.) ambient.setY(1.); - ambient.setZ(ambient.x()+.1); - if (ambient.z()>1.) ambient.setZ(1.); - displayMessage(QString("Light color=(%1 %2 %3)."). - arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); - update(); - } - else if ((e->key()==Qt::Key_PageDown) && (modifiers==Qt::NoButton)) - { - ambient.setX(ambient.x()-.1); - if (ambient.x()<0.) ambient.setX(0.); - ambient.setY(ambient.y()-.1); - if (ambient.y()<0.) ambient.setY(0.); - ambient.setZ(ambient.z()-.1); - if (ambient.z()<0.) ambient.setZ(0.); - displayMessage(QString("Light color=(%1 %2 %3)."). - arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); - update(); - } - else if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::ShiftModifier)) - { - ambient.setX(ambient.x()+.1); - if (ambient.x()>1.) ambient.setX(1.); - displayMessage(QString("Light color=(%1 %2 %3)."). - arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); - update(); - } - else if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::AltModifier)) - { - ambient.setY(ambient.y()+.1); - if (ambient.y()>1.) ambient.setY(1.); - displayMessage(QString("Light color=(%1 %2 %3)."). - arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); - update(); - } - else if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::ControlModifier)) - { - ambient.setZ(ambient.z()+.1); - if (ambient.z()>1.) ambient.setZ(1.); - displayMessage(QString("Light color=(%1 %2 %3)."). - arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); - update(); - } - else if ((e->key()==Qt::Key_PageDown) && (modifiers==Qt::ShiftModifier)) - { - ambient.setX(ambient.x()-.1); - if (ambient.x()<0.) ambient.setX(0.); - displayMessage(QString("Light color=(%1 %2 %3)."). - arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); - update(); - } - else if ((e->key()==Qt::Key_PageDown) && (modifiers==Qt::AltModifier)) - { - ambient.setY(ambient.y()-.1); - if (ambient.y()<0.) ambient.setY(0.); - displayMessage(QString("Light color=(%1 %2 %3)."). - arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); - update(); - } - else if ((e->key()==Qt::Key_PageDown) && (modifiers==Qt::ControlModifier)) - { - ambient.setZ(ambient.z()-.1); - if (ambient.z()<0.) ambient.setZ(0.); - displayMessage(QString("Light color=(%1 %2 %3)."). - arg(ambient.x()).arg(ambient.y()).arg(ambient.z())); - update(); - } - else - CGAL::QGLViewer::keyPressEvent(e); + // const Qt::KeyboardModifiers modifiers = e->modifiers(); + Base::keyPressEvent(e); } QString Viewer::helpString() const -{ - QString text("

L C C V i e w e r

"); - text += "Use the mouse to move the camera around the object. "; - text += "You can respectively revolve around, zoom and translate with " - "the three mouse buttons. "; - text += "Left and middle buttons pressed together rotate around the " - "camera view direction axis

"; - text += "Pressing Alt and one of the function keys " - "(F1..F12) defines a camera keyFrame. "; - text += "Simply press the function key again to restore it. Several " - "keyFrames define a "; - text += "camera path. Paths are saved when you quit the application and " - "restored at next start.

"; - text += "Press F to display the frame rate, A for the " - "world axis, "; - text += "Alt+Return for full screen mode and Control+S to " - "save a snapshot. "; - text += "See the Keyboard tab in this window for a complete " - "shortcut list.

"; - text += "Double clicks automates single click actions: A left button " - "double click aligns the closer axis with the camera (if close enough). "; - text += "A middle button double click fits the zoom of the camera and " - "the right button re-centers the scene.

"; - text += "A left button double click while holding right button pressed " - "defines the camera Revolve Around Point. "; - text += "See the Mouse tab and the documentation web pages for " - "details.

"; - text += "Press Escape to exit the viewer."; - return text; -} +{ return Base::helpString("LCC Demo"); } diff --git a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h index 894ec46eaa3..d42dbbe6713 100644 --- a/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h +++ b/Linear_cell_complex/demo/Linear_cell_complex/Viewer.h @@ -23,96 +23,114 @@ #define VIEWER_H #include "typedefs.h" +#include -#include -#include -#include -#include -#include -#include -#include -#include +// Functor used by SimpleLCCViewerQt to colorize of not elements. +struct MyDrawingFunctorLCC +{ + /// @return true iff the volume containing dh is drawn. + template + bool draw_volume(const LCC& alcc, + typename LCC::Dart_const_handle dh) const + { return alcc.template info<3>(dh).is_visible(); } + /// @return true iff the face containing dh is drawn. + template + bool draw_face(const LCC&, + typename LCC::Dart_const_handle) const + { return true; } + /// @return true iff the edge containing dh is drawn. + template + bool draw_edge(const LCC&, + typename LCC::Dart_const_handle) const + { return true; } + /// @return true iff the vertex containing dh is drawn. + template + bool draw_vertex(const LCC&, + typename LCC::Dart_const_handle) const + { return true; } -#define NB_VBO_BUFFERS 8 -#define NB_VAO_BUFFERS 4 + /// @return true iff the volume containing dh is drawn in wireframe. + template + bool volume_wireframe(const LCC& alcc, + typename LCC::Dart_const_handle dh) const + { return !(alcc.template info<3>(dh).is_filled()); } + /// @return true iff the face containing dh is drawn in wireframe. + template + bool face_wireframe(const LCC&, + typename LCC::Dart_const_handle) const + { return false; } -class Viewer : public CGAL::QGLViewer + /// @return true iff the volume containing dh is colored. + template + bool colored_volume(const LCC&, + typename LCC::Dart_const_handle) const + { return true; } + /// @return true iff the face containing dh is colored. + /// if we have also colored_volume(alcc, dh), the volume color is + /// ignored and only the face color is considered. + template + bool colored_face(const LCC&, + typename LCC::Dart_const_handle) const + { return false; } + /// @return true iff the edge containing dh is colored. + template + bool colored_edge(const LCC&, + typename LCC::Dart_const_handle) const + { return false; } + /// @return true iff the vertex containing dh is colored. + template + bool colored_vertex(const LCC&, + typename LCC::Dart_const_handle) const + { return false; } + + /// @return the color of the volume containing dh + /// used only if colored_volume(alcc, dh) and !colored_face(alcc, dh) + template + CGAL::Color volume_color(const LCC& alcc, + typename LCC::Dart_const_handle dh) const + { return alcc.template info<3>(dh).color(); } + /// @return the color of the face containing dh + /// used only if colored_face(alcc, dh) + template + CGAL::Color face_color(const LCC& alcc, + typename LCC::Dart_const_handle dh) const + { + CGAL::Random random((unsigned int)(alcc.darts().index(dh))); + return get_random_color(random); + } + /// @return the color of the edge containing dh + /// used only if colored_edge(alcc, dh) + template + CGAL::Color edge_color(const LCC&, + typename LCC::Dart_const_handle) const + { return CGAL::Color(0, 0, 0); } + /// @return the color of the vertex containing dh + /// used only if colored_vertex(alcc, dh) + template + CGAL::Color vertex_color(const LCC&, + typename LCC::Dart_const_handle) const + { return CGAL::Color(0, 0, 0); } +}; + + +class Viewer : public CGAL::SimpleLCCViewerQt { Q_OBJECT - typedef LCC::Dart_handle Dart_handle; - typedef LCC::Dart_const_handle Dart_const_handle; + typedef CGAL::SimpleLCCViewerQt Base; public: Viewer(QWidget* parent); - - ~Viewer(); - - void setScene(Scene* scene_) - { scene = scene_; } - -public: - void draw(); - - virtual void init(); - + void setScene(Scene* scene_, bool doredraw=true); void keyPressEvent(QKeyEvent *e); - virtual QString helpString() const; public Q_SLOTS: - void sceneChanged(); -private: - void initialize_buffers(); - void attrib_buffers(CGAL::QGLViewer*); - void compile_shaders(); - - void compute_elements(); - void compute_face(Dart_handle dh, LCC::size_type markface); - void compute_edge(Dart_handle dh, LCC::size_type markedge); - void compute_vertex(Dart_handle dh, LCC::size_type markvertex, bool& empty); - private: Scene* scene; - - bool wireframe; - bool flatShading; - bool edges; - bool vertices; - bool inverse_normal; - - double size_points; - double size_edges; - - QVector4D ambient; - bool m_previous_scene_empty; - bool are_buffers_initialized; - - //Shaders elements - int vertexLocation[3]; - int normalsLocation; - int mvpLocation[2]; - int mvLocation; - int colorLocation; - int colorsLocation; - int lightLocation[5]; - - std::vector pos_points; - std::vector pos_lines; - std::vector pos_facets; - std::vector smooth_normals; - std::vector flat_normals; - std::vector colors; - - QGLBuffer buffers[NB_VBO_BUFFERS]; - QOpenGLVertexArrayObject vao[NB_VAO_BUFFERS]; - QOpenGLShaderProgram rendering_program; - QOpenGLShaderProgram rendering_program_p_l; - - CGAL::Bbox_3 bb; }; #endif diff --git a/Linear_cell_complex/include/CGAL/draw_linear_cell_complex.h b/Linear_cell_complex/include/CGAL/draw_linear_cell_complex.h index 70249fd05f6..1cdc247d855 100644 --- a/Linear_cell_complex/include/CGAL/draw_linear_cell_complex.h +++ b/Linear_cell_complex/include/CGAL/draw_linear_cell_complex.h @@ -31,15 +31,96 @@ namespace CGAL { // Default color functor; user can change it to have its own face color -struct DefaultColorFunctorLCC +struct DefaultDrawingFunctorLCC { + /// @return true iff the volume containing dh is drawn. template - static CGAL::Color run(const LCC& alcc, - typename LCC::Dart_const_handle dh) - { - if (dh==alcc.null_handle) // use to get the mono color - return CGAL::Color(100, 125, 200); // R G B between 0-255 + bool draw_volume(const LCC&, + typename LCC::Dart_const_handle) const + { return true; } + /// @return true iff the face containing dh is drawn. + template + bool draw_face(const LCC&, + typename LCC::Dart_const_handle) const + { return true; } + /// @return true iff the edge containing dh is drawn. + template + bool draw_edge(const LCC&, + typename LCC::Dart_const_handle) const + { return true; } + /// @return true iff the vertex containing dh is drawn. + template + bool draw_vertex(const LCC&, + typename LCC::Dart_const_handle) const + { return true; } + /// @return true iff the volume containing dh is drawn in wireframe. + template + bool volume_wireframe(const LCC&, + typename LCC::Dart_const_handle) const + { return false; } + /// @return true iff the face containing dh is drawn in wireframe. + template + bool face_wireframe(const LCC&, + typename LCC::Dart_const_handle) const + { return false; } + + /// @return true iff the volume containing dh is colored. + template + bool colored_volume(const LCC&, + typename LCC::Dart_const_handle) const + { return true; } + /// @return true iff the face containing dh is colored. + /// if we have also colored_volume(alcc, dh), the volume color is + /// ignored and only the face color is considered. + template + bool colored_face(const LCC&, + typename LCC::Dart_const_handle) const + { return false; } + /// @return true iff the edge containing dh is colored. + template + bool colored_edge(const LCC&, + typename LCC::Dart_const_handle) const + { return false; } + /// @return true iff the vertex containing dh is colored. + template + bool colored_vertex(const LCC&, + typename LCC::Dart_const_handle) const + { return false; } + + /// @return the color of the volume containing dh + /// used only if colored_volume(alcc, dh) and !colored_face(alcc, dh) + template + CGAL::Color volume_color(const LCC& alcc, + typename LCC::Dart_const_handle dh) const + { + CGAL::Random random((unsigned int)(alcc.darts().index(dh))); + return get_random_color(random); + } + /// @return the color of the face containing dh + /// used only if colored_face(alcc, dh) + template + CGAL::Color face_color(const LCC& alcc, + typename LCC::Dart_const_handle dh) const + { + CGAL::Random random((unsigned int)(alcc.darts().index(dh))); + return get_random_color(random); + } + /// @return the color of the edge containing dh + /// used only if colored_edge(alcc, dh) + template + CGAL::Color edge_color(const LCC& alcc, + typename LCC::Dart_const_handle dh) const + { + CGAL::Random random((unsigned int)(alcc.darts().index(dh))); + return get_random_color(random); + } + /// @return the color of the vertex containing dh + /// used only if colored_vertex(alcc, dh) + template + CGAL::Color vertex_color(const LCC& alcc, + typename LCC::Dart_const_handle dh) const + { CGAL::Random random((unsigned int)(alcc.darts().index(dh))); return get_random_color(random); } @@ -73,7 +154,7 @@ struct LCC_geom_utils }; // Viewer class for LCC -template +template class SimpleLCCViewerQt : public Basic_viewer_qt { typedef Basic_viewer_qt Base; @@ -89,42 +170,68 @@ public: /// @param anofaces if true, do not draw faces (faces are not computed; this can be /// usefull for very big object where this time could be long) SimpleLCCViewerQt(QWidget* parent, - const LCC& alcc, + const LCC* alcc=NULL, const char* title="Basic LCC Viewer", bool anofaces=false, - const ColorFunctor& fcolor=ColorFunctor()) : + const DrawingFunctorLCC& drawing_functor=DrawingFunctorLCC()) : // First draw: vertices; edges, faces; multi-color; inverse normal Base(parent, title, true, true, true, false, true), lcc(alcc), m_nofaces(anofaces), - m_fcolor(fcolor) + m_random_face_color(false), + m_drawing_functor(drawing_functor) { compute_elements(); } protected: - void compute_face(Dart_const_handle dh) + void set_lcc(const LCC* alcc, bool doredraw=true) { + lcc=alcc; + compute_elements(); + if (doredraw) { redraw(); } + } + + void compute_face(Dart_const_handle dh, Dart_const_handle voldh) + { + if (m_nofaces || !m_drawing_functor.draw_face(*lcc, dh)) return; + // We fill only closed faces. Dart_const_handle cur=dh; Dart_const_handle min=dh; do { - if (!lcc.is_next_exist(cur)) return; // open face=>not filled + if (!lcc->is_next_exist(cur)) return; // open face=>not filled if (curnext(cur); } while(cur!=dh); - - CGAL::Color c=m_fcolor.run(lcc, dh); - face_begin(c); + + if (m_random_face_color) + { + CGAL::Random random((unsigned int)(lcc->darts().index(dh))); + CGAL::Color c=get_random_color(random); + face_begin(c); + } + else if (m_drawing_functor.colored_face(*lcc, dh)) + { + CGAL::Color c=m_drawing_functor.face_color(*lcc, dh); + face_begin(c); + } + else if (m_drawing_functor.colored_volume(*lcc, voldh)) + { + CGAL::Color c=m_drawing_functor.volume_color(*lcc, voldh); + face_begin(c); + } + else + { face_begin(); } cur=dh; do { - add_point_in_face(lcc.point(cur), LCC_geom_utils:: - get_vertex_normal(lcc, cur)); - cur=lcc.next(cur); + add_point_in_face(lcc->point(cur), LCC_geom_utils:: + get_vertex_normal(*lcc, cur)); + cur=lcc->next(cur); } while(cur!=dh); @@ -133,77 +240,143 @@ protected: void compute_edge(Dart_const_handle dh) { - Point p1 = lcc.point(dh); - Dart_const_handle d2 = lcc.other_extremity(dh); + if (!m_drawing_functor.draw_edge(*lcc, dh)) return; + + Point p1 = lcc->point(dh); + Dart_const_handle d2 = lcc->other_extremity(dh); if (d2!=NULL) - { add_segment(p1, lcc.point(d2)); } + { + if (m_drawing_functor.colored_edge(*lcc, dh)) + { add_segment(p1, lcc->point(d2), m_drawing_functor.edge_color(*lcc, dh)); } + else + { add_segment(p1, lcc->point(d2)); } + } } void compute_vertex(Dart_const_handle dh) - { add_point(lcc.point(dh)); } + { + if (!m_drawing_functor.draw_vertex(*lcc, dh)) return; + + if (m_drawing_functor.colored_vertex(*lcc, dh)) + { add_point(lcc->point(dh), m_drawing_functor.vertex_color(*lcc, dh)); } + else + { add_point(lcc->point(dh)); } + } void compute_elements() { clear(); + if (lcc==NULL) return; + + typename LCC::size_type markvolumes = lcc->get_new_mark(); + typename LCC::size_type markfaces = lcc->get_new_mark(); + typename LCC::size_type markedges = lcc->get_new_mark(); + typename LCC::size_type markvertices = lcc->get_new_mark(); - typename LCC::size_type markfaces = lcc.get_new_mark(); - typename LCC::size_type markedges = lcc.get_new_mark(); - typename LCC::size_type markvertices = lcc.get_new_mark(); - - for (typename LCC::Dart_range::const_iterator it=lcc.darts().begin(), - itend=lcc.darts().end(); it!=itend; ++it ) + for (typename LCC::Dart_range::const_iterator it=lcc->darts().begin(), + itend=lcc->darts().end(); it!=itend; ++it ) { - if ( !m_nofaces && !lcc.is_marked(it, markfaces) ) + if (!lcc->is_marked(it, markvolumes) && + m_drawing_functor.draw_volume(*lcc, it)) { - compute_face(it); - CGAL::mark_cell(lcc, it, markfaces); - } - - if ( !lcc.is_marked(it, markedges) ) - { - compute_edge(it); - CGAL::mark_cell(lcc, it, markedges); - } - - if ( !lcc.is_marked(it, markvertices) ) - { - compute_vertex(it); - CGAL::mark_cell(lcc, it, markvertices); + for (typename LCC::template Dart_of_cell_basic_range<3>:: + const_iterator itv=lcc->template darts_of_cell_basic<3>(it, markvolumes).begin(), + itvend=lcc->template darts_of_cell_basic<3>(it, markvolumes).end(); + itv!=itvend; ++itv) + { + lcc->mark(itv, markvolumes); // To be sure that all darts of the basic iterator will be marked + if (!lcc->is_marked(itv, markfaces) && + m_drawing_functor.draw_face(*lcc, itv)) + { + if (!m_drawing_functor.volume_wireframe(*lcc, itv) && + !m_drawing_functor.face_wireframe(*lcc, itv)) + { compute_face(itv, it); } + for (typename LCC::template Dart_of_cell_basic_range<2>:: + const_iterator itf=lcc->template darts_of_cell_basic<2>(itv, markfaces).begin(), + itfend=lcc->template darts_of_cell_basic<2>(itv, markfaces).end(); + itf!=itfend; ++itf) + { + if (!m_drawing_functor.volume_wireframe(*lcc, itv) && + !m_drawing_functor.face_wireframe(*lcc, itv)) + { lcc->mark(itf, markfaces); } // To be sure that all darts of the basic iterator will be marked + if ( !lcc->is_marked(itf, markedges) && + m_drawing_functor.draw_edge(*lcc, itf)) + { + compute_edge(itf); + for (typename LCC::template Dart_of_cell_basic_range<1>:: + const_iterator ite=lcc->template darts_of_cell_basic<1>(itf, markedges).begin(), + iteend=lcc->template darts_of_cell_basic<1>(itf, markedges).end(); + ite!=iteend; ++ite) + { + lcc->mark(ite, markedges); // To be sure that all darts of the basic iterator will be marked + if ( !lcc->is_marked(ite, markvertices) && + m_drawing_functor.draw_vertex(*lcc, ite)) + { + compute_vertex(ite); + CGAL::mark_cell(*lcc, ite, markvertices); + } + } + } + } + } + } } } - lcc.free_mark(markfaces); - lcc.free_mark(markedges); - lcc.free_mark(markvertices); - } + for (typename LCC::Dart_range::const_iterator it=lcc->darts().begin(), + itend=lcc->darts().end(); it!=itend; ++it ) + { + lcc->unmark(it, markvertices); + lcc->unmark(it, markedges); + lcc->unmark(it, markfaces); + lcc->unmark(it, markvolumes); + } + + lcc->free_mark(markvolumes); + lcc->free_mark(markfaces); + lcc->free_mark(markedges); + lcc->free_mark(markvertices); + } + + virtual void init() + { + Base::init(); + setKeyDescription(::Qt::Key_C, "Toggles random face colors"); + } + virtual void keyPressEvent(QKeyEvent *e) { - // Test key pressed: - // const ::Qt::KeyboardModifiers modifiers = e->modifiers(); - // if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... } + const ::Qt::KeyboardModifiers modifiers = e->modifiers(); + if ((e->key()==::Qt::Key_C) && (modifiers==::Qt::NoButton)) + { + m_random_face_color=!m_random_face_color; + displayMessage(QString("Random face color=%1.").arg(m_random_face_color?"true":"false")); + compute_elements(); + redraw(); + } + else + { Base::keyPressEvent(e); } // Call the base method to process others/classicals key // Call: * compute_elements() if the model changed, followed by // * redraw() if some viewing parameters changed that implies some // modifications of the buffers // (eg. type of normal, color/mono) // * update() just to update the drawing - - // Call the base method to process others/classicals key - Base::keyPressEvent(e); } protected: - const LCC& lcc; + const LCC* lcc; bool m_nofaces; - const ColorFunctor& m_fcolor; + bool m_random_face_color; + const DrawingFunctorLCC& m_drawing_functor; }; -template +template void draw(const LCC& alcc, const char* title, bool nofill, - const ColorFunctor& fcolor) + const DrawingFunctorLCC& drawing_functor) { #if defined(CGAL_TEST_SUITE) bool cgal_test_suite=true; @@ -216,11 +389,11 @@ void draw(const LCC& alcc, int argc=1; const char* argv[2]={"lccviewer","\0"}; QApplication app(argc,const_cast(argv)); - SimpleLCCViewerQt mainwindow(app.activeWindow(), - alcc, - title, - nofill, - fcolor); + SimpleLCCViewerQt mainwindow(app.activeWindow(), + &alcc, + title, + nofill, + drawing_functor); mainwindow.show(); app.exec(); } @@ -229,8 +402,8 @@ void draw(const LCC& alcc, template void draw(const LCC& alcc, const char* title, bool nofill) { - DefaultColorFunctorLCC c; - draw(alcc, title, nofill, c); + DefaultDrawingFunctorLCC f; + draw(alcc, title, nofill, f); } template