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/Installation/cmake/modules/CGAL_UseLEDA.cmake b/Installation/cmake/modules/CGAL_UseLEDA.cmake
index ead5900736c..70474f24a29 100644
--- a/Installation/cmake/modules/CGAL_UseLEDA.cmake
+++ b/Installation/cmake/modules/CGAL_UseLEDA.cmake
@@ -21,9 +21,6 @@ if ( LEDA_FOUND AND NOT LEDA_SETUP )
link_libraries( ${LEDA_LIBRARIES} )
endif()
- if (LEDA_CGAL_FRIEND_INJECTION)
- message( STATUS "${LEDA_CGAL_FRIEND_INJECTION}" )
- endif()
if (LEDA_CGAL_NO_STRICT_ALIASING)
message( STATUS "${LEDA_CGAL_NO_STRICT_ALIASING}" )
endif()
diff --git a/Installation/cmake/modules/FindLEDA.cmake b/Installation/cmake/modules/FindLEDA.cmake
index 1fc99eeecc3..9c50f51807a 100644
--- a/Installation/cmake/modules/FindLEDA.cmake
+++ b/Installation/cmake/modules/FindLEDA.cmake
@@ -92,11 +92,6 @@ if ( LEDA_INCLUDE_DIR AND LEDA_LIBRARIES)
if ( CMAKE_COMPILER_IS_GNUCXX )
get_dependency_version (GCC)
- if ( NOT "${GCC_VERSION}" VERSION_LESS "4.1" )
- set(LEDA_CGAL_FRIEND_INJECTION TRUE)
- typed_cache_set( INTERNAL "Add -ffriend-injection on gcc >= 4.1" LEDA_CGAL_FRIEND_INJECTION "Using LEDA with gcc version 4.1 or later: Adding -ffriend-injection")
- uniquely_add_flags (LEDA_CXX_FLAGS "-ffriend-injection")
- endif()
if ( NOT "${GCC_VERSION}" VERSION_LESS "4.4" )
set(LEDA_CGAL_NO_STRICT_ALIASING TRUE)
typed_cache_set( INTERNAL "Add -fno-strict-aliasing on gcc >= 4.4" LEDA_CGAL_NO_STRICT_ALIASING "Using LEDA with gcc version 4.4 or later: Adding -fno-strict-aliasing")
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
diff --git a/Mesh_2/test/Mesh_2/test_double_map.cpp b/Mesh_2/test/Mesh_2/test_double_map.cpp
index a8e1597cf75..7d05a3f7cfc 100644
--- a/Mesh_2/test/Mesh_2/test_double_map.cpp
+++ b/Mesh_2/test/Mesh_2/test_double_map.cpp
@@ -71,7 +71,7 @@ int main(int argc, char** argv)
std::cerr << "Assignment f2=f...\n";
f2 = f; // check the assignment
std::cerr << "Auto-assignment f=f...\n";
- f2 = f2; // check the auto-assignment
+ f2 = (Map&)f2; // check the auto-assignment
std::cerr << "Copy-construction...\n";
Map f3(f); // check the copy constructor
diff --git a/Modular_arithmetic/test/Modular_arithmetic/Residue.cpp b/Modular_arithmetic/test/Modular_arithmetic/Residue.cpp
index 2329d54e81e..1fdadfd0888 100644
--- a/Modular_arithmetic/test/Modular_arithmetic/Residue.cpp
+++ b/Modular_arithmetic/test/Modular_arithmetic/Residue.cpp
@@ -102,7 +102,7 @@ int main()
assert(mod_x == CGAL::modular_image(int_x));
int_x -= int_x; int_x = CGAL::mod(int_x, prime);
- mod_x -= mod_x;
+ mod_x -= (CGAL::Residue&)mod_x;
}
{
CGAL::Residue::set_current_prime(67111043);
diff --git a/Number_types/test/Number_types/Interval_nt.cpp b/Number_types/test/Number_types/Interval_nt.cpp
index f2ca4dcf5ab..9d6ff105124 100644
--- a/Number_types/test/Number_types/Interval_nt.cpp
+++ b/Number_types/test/Number_types/Interval_nt.cpp
@@ -211,7 +211,7 @@ bool multiplication_test()
g = d * e;
h = d * f;
i = a * e;
- j = j;
+ j = (IA_nt&)j;
// When CGAL_IA_DEBUG is defined, it'll test the current rounding mode for
// these operations.
diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h
index 1c2ac748d32..078097a4ebf 100644
--- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h
+++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h
@@ -119,34 +119,47 @@ clip_to_bbox(const Plane_3& plane,
int current_id = face_indices[4*i + k];
int next_id = face_indices[4*i + (k+1)%4];
- if ( orientations[ current_id ] != ON_POSITIVE_SIDE )
+ switch(orientations[ current_id ])
{
- all_out=false;
- // point on or on the negative side
- output_faces[i].push_back( current_id );
- in_point_ids.insert( output_faces[i].back() );
- // check for intersection of the edge
- if (orientations[ current_id ] == ON_NEGATIVE_SIDE &&
- orientations[ next_id ] == ON_POSITIVE_SIDE)
+ case ON_NEGATIVE_SIDE:
{
- output_faces[i].push_back(
- inter_pt_index(current_id, next_id, plane, corners, id_map) );
+ all_out=false;
+ // point on or on the negative side
+ output_faces[i].push_back( current_id );
in_point_ids.insert( output_faces[i].back() );
+ // check for intersection of the edge
+ if (orientations[ next_id ] == ON_POSITIVE_SIDE)
+ {
+ output_faces[i].push_back(
+ inter_pt_index(current_id, next_id, plane, corners, id_map) );
+ in_point_ids.insert( output_faces[i].back() );
+ }
+ break;
}
- }
- else
- {
- all_in = false;
- // check for intersection of the edge
- if ( orientations[ next_id ] == ON_NEGATIVE_SIDE )
+ case ON_POSITIVE_SIDE:
{
- output_faces[i].push_back(
- inter_pt_index(current_id, next_id, plane, corners, id_map) );
+ all_in = false;
+ // check for intersection of the edge
+ if ( orientations[ next_id ] == ON_NEGATIVE_SIDE )
+ {
+ output_faces[i].push_back(
+ inter_pt_index(current_id, next_id, plane, corners, id_map) );
+ in_point_ids.insert( output_faces[i].back() );
+ }
+ break;
+ }
+ case ON_ORIENTED_BOUNDARY:
+ {
+ output_faces[i].push_back( current_id );
in_point_ids.insert( output_faces[i].back() );
}
}
}
- CGAL_assertion( output_faces[i].empty() || output_faces[i].size() >= 3 );
+ if (output_faces[i].size() < 3){
+ CGAL_assertion(output_faces[i].empty() ||
+ (output_faces[i].front()<8 && output_faces[i].back()<8) );
+ output_faces[i].clear(); // edge of the bbox included in the plane
+ }
}
// the intersection is the full bbox
diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h
index 5913eb21694..c9eed95cef6 100644
--- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h
+++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h
@@ -103,8 +103,7 @@ class Face_graph_output_builder
// Internal typedefs
typedef std::size_t Node_id;
typedef std::pair Node_id_pair;
- typedef boost::unordered_map Intersection_edge_map;
+ typedef boost::unordered_set Intersection_edge_map;
// to maintain a halfedge on each polyline per TriangleMesh + pair
// with first = "is the key (pair) was reversed?" and
// second is the number of edges -1 in the polyline
@@ -127,6 +126,9 @@ class Face_graph_output_builder
const VpmOutTuple& output_vpms;
EdgeMarkMapTuple& out_edge_mark_maps;
UserVisitor& user_visitor;
+ // mapping vertex to node id
+ Node_id_map vertex_to_node_id1, vertex_to_node_id2;
+
// output meshes
const cpp11::array, 4>& requested_output;
// input meshes closed ?
@@ -310,9 +312,8 @@ class Face_graph_output_builder
{
std::vector edges;
edges.reserve(edge_map.size());
- typedef std::pair Pair;
- BOOST_FOREACH(const Pair& p, edge_map)
- edges.push_back(p.first);
+ BOOST_FOREACH(edge_descriptor ed, edge_map)
+ edges.push_back(ed);
CGAL_assertion(tuple_id < 4 && tuple_id >= 0);
switch (tuple_id)
@@ -427,8 +428,7 @@ public:
//register an intersection halfedge
// It is important here not to use operator[] since a two edges might be
// equals while the indices are reversed
- mesh_to_intersection_edges[&tm].
- insert(std::make_pair(edge(hedge, tm), indices));
+ mesh_to_intersection_edges[&tm].insert(edge(hedge, tm));
if (indices.first>indices.second)
{
@@ -445,6 +445,17 @@ public:
}
}
+ void set_vertex_id(vertex_descriptor v, Node_id node_id, const TriangleMesh& tm)
+ {
+ if (&tm == &tm1)
+ vertex_to_node_id1.insert( std::make_pair(v, node_id) );
+ else
+ {
+ CGAL_assertion(&tm == &tm2);
+ vertex_to_node_id2.insert( std::make_pair(v, node_id) );
+ }
+ }
+
template
void operator()(
const Nodes_vector& nodes,
@@ -452,30 +463,11 @@ public:
const boost::dynamic_bitset<>& is_node_of_degree_one,
const Mesh_to_map_node&)
{
- // first build an unordered_map mapping a vertex to its node id
+ CGAL_assertion( vertex_to_node_id1.size() == vertex_to_node_id2.size());
+ CGAL_assertion( vertex_to_node_id1.size() == nodes.size());
+
Intersection_edge_map& intersection_edges1 = mesh_to_intersection_edges[&tm1];
- Node_id_map vertex_to_node_id1;
-
- for (typename Intersection_edge_map::iterator
- it=intersection_edges1.begin(),
- it_end=intersection_edges1.end(); it!=it_end; ++it)
- {
- vertex_to_node_id1[source(it->first,tm1)]=it->second.first;
- vertex_to_node_id1[target(it->first,tm1)]=it->second.second;
- }
-
Intersection_edge_map& intersection_edges2 = mesh_to_intersection_edges[&tm2];
- Node_id_map vertex_to_node_id2;
-
- for (typename Intersection_edge_map::iterator
- it=intersection_edges2.begin(),
- it_end=intersection_edges2.end(); it!=it_end; ++it)
- {
- vertex_to_node_id2[source(it->first,tm2)]=it->second.first;
- vertex_to_node_id2[target(it->first,tm2)]=it->second.second;
- }
-
- CGAL_assertion(intersection_edges1.size()==intersection_edges2.size());
// this will initialize face indices if the face index map is writable.
helpers::init_face_indices(tm1, fids1);
@@ -504,11 +496,6 @@ public:
halfedge_descriptor h2 = epp_it->second.first[&tm2];
halfedge_descriptor h2_opp = opposite(h2, tm2);
- if (is_border_edge(h1,tm1) || is_border_edge(h2,tm2)){
- ++epp_it;
- continue;
- }
-
//vertices from tm1
vertex_descriptor p1 = target(next(h1_opp, tm1), tm1);
vertex_descriptor p2 = target(next(h1, tm1), tm1);
@@ -521,41 +508,53 @@ public:
Node_id index_q2 = get_node_id(q2, vertex_to_node_id2);
// set boolean for the position of p1 wrt to q1 and q2
- bool p1_eq_q1=false, p1_eq_q2=false;
+ bool p1_eq_q1=is_border(h1_opp, tm1), p1_eq_q2=p1_eq_q1;
if (!is_border(h1_opp, tm1) && index_p1!=NID)
{
if (!is_border(h2_opp, tm2))
+ {
p1_eq_q1 = index_p1 == index_q1;
+ if (p1_eq_q1)
+ {
+ //mark coplanar facets if any
+ tm1_coplanar_faces.set(get(fids1, face(h1_opp, tm1)));
+ tm2_coplanar_faces.set(get(fids2, face(h2_opp, tm2)));
+ }
+ }
if (!is_border(h2, tm2))
+ {
p1_eq_q2 = index_p1 == index_q2;
+ if (p1_eq_q2)
+ {
+ //mark coplanar facets if any
+ tm1_coplanar_faces.set(get(fids1, face(h1_opp, tm1)));
+ tm2_coplanar_faces.set(get(fids2, face(h2, tm2)));
+ }
+ }
}
// set boolean for the position of p2 wrt to q1 and q2
- bool p2_eq_q1=false, p2_eq_q2=false;
+ bool p2_eq_q1=is_border(h1, tm1), p2_eq_q2=p2_eq_q1;
if (!is_border(h1, tm1) && index_p2!=NID)
{
if (!is_border(h2_opp, tm2))
+ {
p2_eq_q1 = index_p2 == index_q1;
+ if (p2_eq_q1){
+ //mark coplanar facets if any
+ tm1_coplanar_faces.set(get(fids1, face(h1, tm1)));
+ tm2_coplanar_faces.set(get(fids2, face(h2_opp, tm2)));
+ }
+ }
if (!is_border(h2, tm2))
+ {
p2_eq_q2 = index_p2 == index_q2;
- }
-
- //mark coplanar facets if any
- if (p1_eq_q1){
- tm1_coplanar_faces.set(get(fids1, face(h1_opp, tm1)));
- tm2_coplanar_faces.set(get(fids2, face(h2_opp, tm2)));
- }
- if (p1_eq_q2){
- tm1_coplanar_faces.set(get(fids1, face(h1_opp, tm1)));
- tm2_coplanar_faces.set(get(fids2, face(h2, tm2)));
- }
- if (p2_eq_q1){
- tm1_coplanar_faces.set(get(fids1, face(h1, tm1)));
- tm2_coplanar_faces.set(get(fids2, face(h2_opp, tm2)));
- }
- if (p2_eq_q2){
- tm1_coplanar_faces.set(get(fids1, face(h1, tm1)));
- tm2_coplanar_faces.set(get(fids2, face(h2, tm2)));
+ if (p2_eq_q2){
+ //mark coplanar facets if any
+ tm1_coplanar_faces.set(get(fids1, face(h1, tm1)));
+ tm2_coplanar_faces.set(get(fids2, face(h2, tm2)));
+ }
+ }
}
if ( (p1_eq_q1 || p1_eq_q2) && (p2_eq_q1 || p2_eq_q2) )
@@ -565,6 +564,48 @@ public:
an_edge_per_polyline.erase(it_to_rm);
inter_edges_to_remove1.insert(edge(h1,tm1));
inter_edges_to_remove2.insert(edge(h2,tm2));
+
+ // on the border, we can have a degree 2 node so prev/next
+ // halfedge should be also considered for removal
+ // (as the coplanar edge will not be reported in an_edge_per_polyline
+ // and thus not removed from intersection_edges[12])
+ if ( !is_border(h1, tm1) )
+ {
+ h1 = opposite(h1, tm1);
+ h2 = opposite(h2, tm2);
+ }
+ if ( is_border(h1, tm1) )
+ {
+ if ( opposite(next(h1, tm1), tm1) == prev(opposite(h1, tm1), tm1) )
+ {
+ inter_edges_to_remove1.insert(edge(next(h1, tm1),tm1));
+ inter_edges_to_remove1.insert(edge(next(h2, tm2),tm2));
+ }
+ if ( opposite(prev(h1, tm1), tm1) == next(opposite(h1, tm1), tm1) )
+ {
+ inter_edges_to_remove1.insert(edge(prev(h1, tm1), tm1));
+ inter_edges_to_remove1.insert(edge(prev(h2, tm2), tm2));
+ }
+ }
+ // same but for h2
+ if ( !is_border(h2, tm2) )
+ {
+ h1 = opposite(h1, tm1);
+ h2 = opposite(h2, tm2);
+ }
+ if ( is_border(h2, tm2) )
+ {
+ if ( opposite(next(h2, tm2), tm2) == prev(opposite(h2, tm2), tm2) )
+ {
+ inter_edges_to_remove1.insert(edge(next(h1, tm1),tm1));
+ inter_edges_to_remove1.insert(edge(next(h2, tm2),tm2));
+ }
+ if ( opposite(prev(h2, tm2), tm2) == next(opposite(h2, tm2), tm2) )
+ {
+ inter_edges_to_remove1.insert(edge(prev(h1, tm1), tm1));
+ inter_edges_to_remove1.insert(edge(prev(h2, tm2), tm2));
+ }
+ }
}
else
++epp_it;
@@ -601,7 +642,7 @@ public:
.face_index_map(fids2));
std::vector tm2_patch_sizes(nb_patches_tm2, 0);
- BOOST_FOREACH(std::size_t i, tm2_patch_ids)
+ BOOST_FOREACH(Node_id i, tm2_patch_ids)
if(i!=NID)
++tm2_patch_sizes[i];
@@ -677,11 +718,55 @@ public:
impossible_operation.set();
return;
}
+ else
+ {
+ //Sort the three triangle faces around their common edge
+ // we assume that the exterior of the volume is indicated by
+ // counterclockwise oriented faces
+ // (corrected by is_tmi_inside_tmi).
+ halfedge_descriptor h = is_border(h1, tm1) ? opposite(h1, tm1) : h1;
+ vertex_descriptor p = target(next(h,tm1),tm1);
+ // when looking from the side of indices.second,
+ // the interior of the first triangle mesh is described
+ // by turning counterclockwise from p1 to p2
+ vertex_descriptor q1=target(next(opposite(h2,tm2),tm2),tm2);
+ vertex_descriptor q2=target(next(h2,tm2),tm2);
+ // when looking from the side of indices.second,
+ // the interior of the second volume is described
+ // by turning from q1 to q2
+
+ //check if the third point of each triangular face is an original point (stay NID)
+ //or a intersection point (in that case we need the index of the corresponding node to
+ //have the exact value of the point)
+ Node_id index_p = get_node_id(p, vertex_to_node_id1);
+ Node_id index_q1 = get_node_id(q1, vertex_to_node_id2);
+ Node_id index_q2 = get_node_id(q2, vertex_to_node_id2);
+
+ std::size_t patch_id_p=tm1_patch_ids[ get(fids1, face(h,tm1)) ];
+ std::size_t patch_id_q1=tm2_patch_ids[ get(fids2, face(opposite(h2,tm2),tm2)) ];
+ std::size_t patch_id_q2=tm2_patch_ids[ get(fids2, face(h2,tm2)) ];
+
+ //indicates that patch status will be updated
+ patch_status_not_set_tm1.reset(patch_id_p);
+ patch_status_not_set_tm2.reset(patch_id_q1);
+ patch_status_not_set_tm2.reset(patch_id_q2);
+
+ bool p_is_between_q1q2 = sorted_around_edge(
+ ids.first, ids.second,
+ index_q1, index_q2, index_p,
+ q1, q2, p,
+ vpm2, vpm1,
+ nodes);
+
+ if (p_is_between_q1q2)
+ is_patch_inside_tm2.set(patch_id_p);
+ }
}
}
else
if ( is_border_edge(h2,tm2) )
{
+ CGAL_assertion(!used_to_clip_a_surface);
//Ambiguous, we do nothing
impossible_operation.set();
return;
@@ -989,37 +1074,51 @@ public:
BOOST_FOREACH(face_descriptor f, faces(tm1))
{
- std::size_t patch_id=tm1_patch_ids[ get(fids1, f) ];
+ const std::size_t f_id = get(fids1, f);
+ const std::size_t patch_id = tm1_patch_ids[ f_id ];
if ( patch_status_not_set_tm1.test( patch_id ) )
{
patch_status_not_set_tm1.reset( patch_id );
- vertex_descriptor v = target(halfedge(f, tm1), tm1);
- Bounded_side position = inside_tm2( get(vpm1, v));
- if ( position == in_tm2 )
- is_patch_inside_tm2.set(patch_id);
- else
- if( position == ON_BOUNDARY)
+ halfedge_descriptor h = halfedge(f, tm1);
+ Node_id index_p1 = get_node_id(target(h, tm1), vertex_to_node_id1);
+ if (index_p1 != NID)
+ {
+ h=next(h, tm1);
+ index_p1 = get_node_id(target(h, tm1), vertex_to_node_id1);
+ if (index_p1 != NID)
{
- if (tm1_coplanar_faces.test(get(fids1, f)))
- {
- coplanar_patches_of_tm1.set(patch_id);
- coplanar_patches_of_tm1_for_union_and_intersection.set(patch_id);
- }
- else
- {
- vertex_descriptor vn = source(halfedge(f, tm1), tm1);
- Bounded_side other_position = inside_tm2( get(vpm1, vn) );
- if (other_position==ON_BOUNDARY)
- {
- // \todo improve this part which is not robust with a kernel
- // with inexact constructions.
- other_position = inside_tm2(midpoint(get(vpm1, vn),
- get(vpm1, v) ));
- }
- if ( other_position == in_tm2 )
- is_patch_inside_tm2.set(patch_id);
- }
+ h=next(h, tm1);
+ index_p1 = get_node_id(target(h, tm1), vertex_to_node_id1);
}
+ }
+ if (index_p1 != NID)
+ {
+ if (tm1_coplanar_faces.test(f_id))
+ {
+ coplanar_patches_of_tm1.set(patch_id);
+ coplanar_patches_of_tm1_for_union_and_intersection.set(patch_id);
+ }
+ else
+ {
+ // triangle which is tangent at its 3 vertices
+ // \todo improve this part which is not robust with a kernel
+ // with inexact constructions.
+ Bounded_side position = inside_tm2(midpoint(get(vpm1, source(h, tm1)),
+ get(vpm1, target(h, tm1)) ));
+ CGAL_assertion( position != ON_BOUNDARY);
+ if ( position == in_tm2 )
+ is_patch_inside_tm2.set(patch_id);
+ }
+ }
+ else
+ {
+ // TODO: tm2 might have been modified and an inexact vpm will
+ // provide a non-robust result.
+ Bounded_side position = inside_tm2( get(vpm1, target(h, tm1)));
+ CGAL_assertion( position != ON_BOUNDARY);
+ if ( position == in_tm2 )
+ is_patch_inside_tm2.set(patch_id);
+ }
if ( patch_status_not_set_tm1.none() ) break;
}
}
@@ -1035,37 +1134,51 @@ public:
Inside_poly_test inside_tm1(tm1, vpm1);
BOOST_FOREACH(face_descriptor f, faces(tm2))
{
- std::size_t patch_id=tm2_patch_ids[ get(fids2, f) ];
+ const std::size_t f_id = get(fids2, f);
+ std::size_t patch_id=tm2_patch_ids[ f_id ];
if ( patch_status_not_set_tm2.test( patch_id ) )
{
patch_status_not_set_tm2.reset( patch_id );
- vertex_descriptor v = target(halfedge(f, tm2), tm2);
- Bounded_side position = inside_tm1( get(vpm2, v));
- if ( position == in_tm1 )
- is_patch_inside_tm1.set(patch_id);
- else
- if( position == ON_BOUNDARY)
+ halfedge_descriptor h = halfedge(f, tm2);
+ Node_id index_p2 = get_node_id(target(h, tm2), vertex_to_node_id2);
+ if (index_p2 != NID)
+ {
+ h=next(h, tm2);
+ index_p2 = get_node_id(target(h, tm2), vertex_to_node_id2);
+ if (index_p2 != NID)
{
- if (tm2_coplanar_faces.test(get(fids2, f)))
- {
- coplanar_patches_of_tm2.set(patch_id);
- coplanar_patches_of_tm2_for_union_and_intersection.set(patch_id);
- }
- else
- {
- vertex_descriptor vn = source(halfedge(f, tm2), tm2);
- Bounded_side other_position = inside_tm1( get(vpm2, vn) );
- if (other_position==ON_BOUNDARY)
- {
- // \todo improve this part which is not robust with a kernel
- // with inexact constructions.
- other_position = inside_tm1(midpoint(get(vpm2, vn),
- get(vpm2, v) ));
- }
- if ( other_position == in_tm1 )
- is_patch_inside_tm1.set(patch_id);
- }
+ h=next(h, tm2);
+ index_p2 = get_node_id(target(h, tm2), vertex_to_node_id2);
}
+ }
+ if (index_p2 != NID)
+ {
+ if (tm2_coplanar_faces.test(f_id))
+ {
+ coplanar_patches_of_tm2.set(patch_id);
+ coplanar_patches_of_tm2_for_union_and_intersection.set(patch_id);
+ }
+ else
+ {
+ // triangle which is tangent at its 3 vertices
+ // \todo improve this part which is not robust with a kernel
+ // with inexact constructions.
+ Bounded_side position = inside_tm1(midpoint(get(vpm2, source(h, tm2)),
+ get(vpm2, target(h, tm2)) ));
+ CGAL_assertion( position != ON_BOUNDARY);
+ if ( position == in_tm1 )
+ is_patch_inside_tm1.set(patch_id);
+ }
+ }
+ else
+ {
+ // TODO: tm1 might have been modified and an inexact vpm will
+ // provide a non-robust result.
+ Bounded_side position = inside_tm1( get(vpm2, target(h, tm2)));
+ CGAL_assertion( position != ON_BOUNDARY);
+ if ( position == in_tm1 )
+ is_patch_inside_tm1.set(patch_id);
+ }
if ( patch_status_not_set_tm2.none() ) break;
}
}
@@ -1436,6 +1549,59 @@ public:
patches_of_tm1_used[inplace_operation_tm1],
patches_of_tm2_used[inplace_operation_tm1],
fids1, fids2, tm1, tm2);
+
+ if (used_to_clip_a_surface)
+ {
+ // The following code is here to handle the case when an intersection polyline
+ // contains some border edges of tm1 that should be considered as an independant polyline.
+ // This polyline removal should be handled by remove_unused_polylines.
+ // However, since all nodes are of degree 2 the polyline is not split at
+ // the correct point and trouble happen. Here the workaround consists in
+ // removing border edges of patches to be removed that are not in a
+ // polyline schedule for removal.
+ boost::dynamic_bitset<> patches_to_remove = ~patches_of_tm1_used[inplace_operation_tm1];
+ for (std::size_t i = patches_to_remove.find_first();
+ i < patches_to_remove.npos;
+ i = patches_to_remove.find_next(i))
+ {
+ typedef typename std::vector::iterator Hedge_iterator;
+ std::vector< Hedge_iterator > to_rm;
+ for (Hedge_iterator it = patches_of_tm1[i].shared_edges.begin();
+ it!= patches_of_tm1[i].shared_edges.end();
+ ++it)
+ {
+ if ( is_border(opposite(*it, tm1), tm1) )
+ to_rm.push_back(it);
+ }
+ if (!to_rm.empty())
+ {
+ std::reverse(to_rm.begin(), to_rm.end());
+ BOOST_FOREACH(Hedge_iterator it, to_rm)
+ {
+ patches_of_tm1[i].interior_edges.push_back(*it);
+ if (it!=cpp11::prev(patches_of_tm1[i].shared_edges.end()))
+ std::swap(patches_of_tm1[i].shared_edges.back(), *it);
+ patches_of_tm1[i].shared_edges.pop_back();
+ }
+ //now update interior vertices
+ std::set border_vertices;
+ BOOST_FOREACH(halfedge_descriptor h, patches_of_tm1[i].shared_edges)
+ {
+ border_vertices.insert( target(h,tm1) );
+ border_vertices.insert( source(h,tm1) );
+ }
+
+ BOOST_FOREACH(halfedge_descriptor h, patches_of_tm1[i].interior_edges)
+ {
+ if ( !border_vertices.count( target(h,tm1) ) )
+ patches_of_tm1[i].interior_vertices.insert( target(h,tm1) );
+ if ( !border_vertices.count( source(h,tm1) ) )
+ patches_of_tm1[i].interior_vertices.insert( source(h,tm1) );
+ }
+ }
+ }
+ }
+
#define CGAL_COREF_FUNCTION_CALL_DEF(BO_type) \
compute_inplace_operation( \
tm1, tm2, \
diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h
index ba32b8948f2..0b04ec00e8b 100644
--- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h
+++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Output_builder_for_autorefinement.h
@@ -110,6 +110,7 @@ class Output_builder_for_autorefinement
const VertexPointMap &vpm;
const FaceIdMap &fids;
Ecm& ecm;
+ Node_id_map vertex_to_node_id;
// input meshes closed ?
bool is_tm_closed;
// orientation of input surface mesh
@@ -208,6 +209,13 @@ public:
all_intersection_edges_map[indices].add(hedge);
}
+ void set_vertex_id(vertex_descriptor v, Node_id node_id, const TriangleMesh& tm_)
+ {
+ CGAL_USE(tm_);
+ CGAL_assertion(&tm_==&tm);
+ vertex_to_node_id.insert( std::make_pair(v, node_id) );
+ }
+
template
void operator()(
const Nodes_vector& nodes,
@@ -220,7 +228,6 @@ public:
// first build an unordered_map mapping a vertex to its node id + a set
// of all intersection edges
- Node_id_map vertex_to_node_id;
typedef boost::unordered_set Intersection_edge_map;
Intersection_edge_map intersection_edges;
@@ -233,10 +240,10 @@ public:
// and will be discarded later
if (p.second.h2==boost::graph_traits::null_halfedge())
continue;
- vertex_to_node_id[source(p.second.h1, tm)] = p.first.first;
- vertex_to_node_id[target(p.second.h1, tm)] = p.first.second;
- vertex_to_node_id[source(p.second.h2, tm)] = p.first.first;
- vertex_to_node_id[target(p.second.h2, tm)] = p.first.second;
+ CGAL_assertion( vertex_to_node_id[source(p.second.h1, tm)] == p.first.first);
+ CGAL_assertion( vertex_to_node_id[target(p.second.h1, tm)] == p.first.second);
+ CGAL_assertion( vertex_to_node_id[source(p.second.h2, tm)] == p.first.first);
+ CGAL_assertion( vertex_to_node_id[target(p.second.h2, tm)] == p.first.second);
intersection_edges.insert(edge(p.second.h1, tm));
intersection_edges.insert(edge(p.second.h2, tm));
}
diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Visitor.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Visitor.h
index 3ca6e2d833c..ade1e28dd0c 100644
--- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Visitor.h
+++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Visitor.h
@@ -96,6 +96,8 @@ struct No_extra_output_from_corefinement
void set_edge_per_polyline(G& /*tm*/,
Node_id_pair /*indices*/,
halfedge_descriptor /*hedge*/){}
+ template
+ void set_vertex_id(vertex_descriptor, Node_id, const G&){}
template
void operator()(
@@ -360,6 +362,7 @@ public:
node_id_to_vertex[node_id]=target(h_2,tm2);
all_incident_faces_got_a_node_as_vertex(h_2,node_id,*tm2_ptr);
// check_node_on_non_manifold_vertex(node_id,h_2,tm2);
+ output_builder.set_vertex_id(target(h_2, tm2), node_id, tm2);
}
break;
default:
@@ -377,6 +380,8 @@ public:
node_id_to_vertex.resize(node_id+1,Graph_traits::null_vertex());
node_id_to_vertex[node_id]=target(h_1,tm1);
all_incident_faces_got_a_node_as_vertex(h_1,node_id, *tm1_ptr);
+ // register the vertex in the output builder
+ output_builder.set_vertex_id(target(h_1, tm1), node_id, tm1);
// check_node_on_non_manifold_vertex(node_id,h_1,tm1);
}
else{
@@ -389,6 +394,8 @@ public:
node_id_to_vertex.resize(node_id+1,Graph_traits::null_vertex());
node_id_to_vertex[node_id]=source(h_1,tm1);
all_incident_faces_got_a_node_as_vertex(h_1_opp,node_id, *tm1_ptr);
+ // register the vertex in the output builder
+ output_builder.set_vertex_id(source(h_1, tm1), node_id, tm1);
// check_node_on_non_manifold_vertex(node_id,h_1_opp,tm1);
}
else{
@@ -753,7 +760,8 @@ public:
vertex_descriptor vnew=target(hnew,tm);
// user_visitor.new_vertex_added(node_id, vnew, tm); // NODE_VISITOR_TAG
nodes.call_put(vpm, vnew, node_id, tm);
-
+ // register the new vertex in the output builder
+ output_builder.set_vertex_id(vnew, node_id, tm);
node_id_to_vertex[node_id]=vnew;
if (first){
first=false;
@@ -997,7 +1005,7 @@ public:
// import the triangle in `cdt` in the face `f` of `tm`
triangulate_a_face(f, tm, nodes, node_ids, node_id_to_vertex,
- edge_to_hedge, cdt, vpm, user_visitor);
+ edge_to_hedge, cdt, vpm, output_builder, user_visitor);
// TODO Here we do the update only for internal edges.
// Update for border halfedges could be done during the split
diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h
index be442040d31..22e785a8246 100644
--- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h
+++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h
@@ -263,6 +263,7 @@ template < class TriangleMesh,
class Node_id,
class Node_vector,
class CDT,
+ class OutputBuilder,
class UserVisitor>
void
triangulate_a_face(
@@ -277,6 +278,7 @@ triangulate_a_face(
::halfedge_descriptor>& edge_to_hedge,
const CDT& cdt,
const VertexPointMap& vpm,
+ OutputBuilder& output_builder,
UserVisitor& user_visitor)
{
typedef boost::graph_traits GT;
@@ -292,6 +294,9 @@ triangulate_a_face(
vertex_descriptor v=add_vertex(tm);
// user_visitor.new_vertex_added(node_id, v, tm); // NODE_VISITOR_TAG
nodes.call_put(vpm, v, node_id, tm);
+ // register the new vertex in the output builder
+ output_builder.set_vertex_id(v, node_id, tm);
+
CGAL_assertion(node_id_to_vertex.size()>node_id);
node_id_to_vertex[node_id]=v;
}
@@ -378,12 +383,10 @@ triangulate_a_face(
template
class Border_edge_map {
- typedef std::size_t Node_id;
typedef boost::graph_traits GT;
typedef typename GT::halfedge_descriptor halfedge_descriptor;
typedef typename GT::edge_descriptor edge_descriptor;
- typedef boost::unordered_map > Intersection_edge_map;
+ typedef boost::unordered_set Intersection_edge_map;
const Intersection_edge_map* intersection_edges;
const PolygonMesh* tm;
public:
diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h
index 55e0b845bcb..dff16c5ea0b 100644
--- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h
+++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair.h
@@ -900,9 +900,53 @@ bool remove_degenerate_faces( TriangleMesh& tmesh,
}
#endif
+
// Then, remove triangles made of 3 collinear points
std::set degenerate_face_set;
degenerate_faces(tmesh, std::inserter(degenerate_face_set, degenerate_face_set.begin()), np);
+
+// start by filtering out border faces
+ std::set border_deg_faces;
+ BOOST_FOREACH(face_descriptor f, degenerate_face_set)
+ {
+ halfedge_descriptor h = halfedge(f, tmesh);
+ for (int i=0; i<3; ++i)
+ {
+ if ( is_border( opposite(h, tmesh), tmesh) )
+ {
+ border_deg_faces.insert(f);
+ break;
+ }
+ h = next(h, tmesh);
+ }
+ }
+
+ while( !border_deg_faces.empty() )
+ {
+ face_descriptor f_to_rm = *border_deg_faces.begin();
+ border_deg_faces.erase(border_deg_faces.begin());
+
+ halfedge_descriptor h = halfedge(f_to_rm, tmesh);
+ for (int i=0; i<3; ++i)
+ {
+ if (is_border(h, tmesh) )
+ {
+ face_descriptor f = face(opposite(h, tmesh), tmesh);
+ if (is_degenerate_triangle_face(f, tmesh, np) )
+ border_deg_faces.insert(f);
+ }
+ h = next(h, tmesh);
+ }
+
+ while( !is_border(opposite(h, tmesh), tmesh) )
+ {
+ h = next(h, tmesh);
+ }
+
+ degenerate_face_set .erase(f_to_rm);
+ Euler::remove_face(h, tmesh);
+ }
+
// Ignore faces with null edges
if (!all_removed)
{
diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/data-clip/clipper_1.off b/Polygon_mesh_processing/test/Polygon_mesh_processing/data-clip/clipper_1.off
new file mode 100644
index 00000000000..9cb3aa719fb
--- /dev/null
+++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/data-clip/clipper_1.off
@@ -0,0 +1,16 @@
+OFF
+6 8 0
+-0.98999999999999977 10 0.99999999999999978
+-0.98999999999999999 -2.4671622769447923e-19 2.4671622769447923e-19
+-0.98999999999999999 10 10
+-0.99999999999999978 10 0.99999999999999978
+-1 0 0
+-1 10 10
+3 2 0 1
+3 4 3 5
+3 5 3 0
+3 0 2 5
+3 3 4 1
+3 1 0 3
+3 4 5 2
+3 2 1 4
diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/data-clip/tm_1.off b/Polygon_mesh_processing/test/Polygon_mesh_processing/data-clip/tm_1.off
new file mode 100644
index 00000000000..be60022538b
--- /dev/null
+++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/data-clip/tm_1.off
@@ -0,0 +1,19 @@
+OFF
+9 8 0
+-0.99999999999999978 10 0.99999999999999978
+-10 0 1
+0 0 1
+-1 0 1
+-0.98999999999999999 1 1
+-0.98999999999999999 1.1102230246251566e-19 1
+-0.99899999999999989 1.1102230246251564e-20 1
+-0.99099999999999988 1 1
+-1 1 1
+3 0 8 7
+3 0 1 8
+3 8 1 3
+3 0 4 2
+3 5 6 2
+3 4 5 2
+3 6 3 2
+3 0 7 4
diff --git a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_clip.cpp b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_clip.cpp
index 3dae87fb73c..d1c11f037dd 100644
--- a/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_clip.cpp
+++ b/Polygon_mesh_processing/test/Polygon_mesh_processing/test_pmp_clip.cpp
@@ -216,6 +216,73 @@ void test()
PMP::clip(tm1, K::Plane_3(-1, 0, 0, 2));
assert(vertices(tm1).size()==3);
CGAL::clear(tm1);
+
+ // test with clipper on border edge
+ make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 1, 0), K::Point_3(1, 0, 0), tm1 );
+ PMP::clip(tm1, K::Plane_3(0, 1, 0 , 0));
+ assert(vertices(tm1).size()==0);
+ CGAL::clear(tm1);
+
+ make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 1, 0), K::Point_3(1, 0, 0), tm1 );
+ PMP::clip(tm1, K::Plane_3(0, -1, 0 , 0));
+ assert(vertices(tm1).size()==4);
+ CGAL::clear(tm1);
+
+ // test with clipper on border edge: full triangle
+ make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 4, 0), K::Point_3(4, 0, 0), tm1 );
+ PMP::clip(tm1, K::Plane_3(0, 0, 1, 0), params::use_compact_clipper(true));
+ assert(vertices(tm1).size()!=0);
+ CGAL::clear(tm1);
+
+ make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 4, 0), K::Point_3(4, 0, 0), tm1 );
+ PMP::clip(tm1, K::Plane_3(0, 0, 1, 0), params::use_compact_clipper(false));
+ assert(vertices(tm1).size()==0);
+ CGAL::clear(tm1);
+
+ // test tangencies
+ make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 2, 0), K::Point_3(1, 1, 0), tm1 );
+ PMP::clip(tm1, K::Plane_3(1, 0, 0, -1));
+ assert(vertices(tm1).size()==3);
+ CGAL::clear(tm1);
+
+ make_triangle( K::Point_3(0, 0, 0), K::Point_3(0, 2, 0), K::Point_3(1, 1, 0), tm1 );
+ PMP::clip(tm1, K::Plane_3(-1, 0, 0, 1));
+ assert(vertices(tm1).size()==0);
+ CGAL::clear(tm1);
+
+ make_triangle( K::Point_3(0.5, 0, 0.5), K::Point_3(1, 0.5, 0.5), K::Point_3(0.5, 1, 0.5), tm1 );
+ input.open("data-coref/cube.off");
+ input >> tm2;
+ input.close();
+ PMP::clip(tm1, tm2, params::face_index_map(get(CGAL::dynamic_face_property_t(), tm1)),
+ params::face_index_map(get(CGAL::dynamic_face_property_t(), tm2)));
+ assert(vertices(tm1).size()==3);
+ CGAL::clear(tm1);
+ CGAL::clear(tm2);
+
+ make_triangle( K::Point_3(0.5, 0, 0.5), K::Point_3(1, 0.5, 0.5), K::Point_3(0.5, 1, 0.5), tm1 );
+ input.open("data-coref/cube.off");
+ input >> tm2;
+ input.close();
+ PMP::reverse_face_orientations(tm2);
+ PMP::clip(tm1, tm2, params::face_index_map(get(CGAL::dynamic_face_property_t(), tm1)),
+ params::face_index_map(get(CGAL::dynamic_face_property_t(), tm2)));
+ assert(vertices(tm1).size()==0);
+ CGAL::clear(tm1);
+ CGAL::clear(tm2);
+
+ // test special case
+ input.open("data-clip/tm_1.off");
+ input >> tm1;
+ input.close();
+ input.open("data-clip/clipper_1.off");
+ input >> tm2;
+ input.close();
+ PMP::clip(tm1, tm2, params::face_index_map(get(CGAL::dynamic_face_property_t(), tm1)),
+ params::face_index_map(get(CGAL::dynamic_face_property_t(), tm2)));
+ assert(is_valid_polygon_mesh(tm1));
+ CGAL::clear(tm1);
+ CGAL::clear(tm2);
}
int main()
diff --git a/Polyhedron/demo/Polyhedron/MainWindow.cpp b/Polyhedron/demo/Polyhedron/MainWindow.cpp
index 4598e8cb2ae..178c1989050 100644
--- a/Polyhedron/demo/Polyhedron/MainWindow.cpp
+++ b/Polyhedron/demo/Polyhedron/MainWindow.cpp
@@ -8,10 +8,10 @@
#include
#include
+#include
#include
#include
#include
-#include
#include
#include
#include
@@ -37,9 +37,11 @@
#include
#include
#include
+#include
#include
#include
#include
+
#ifdef QT_SCRIPT_LIB
# include
# ifdef QT_SCRIPTTOOLS_LIB
@@ -137,6 +139,7 @@ MainWindow::MainWindow(const QStringList &keywords, bool verbose, QWidget* paren
: CGAL::Qt::DemosMainWindow(parent),
accepted_keywords(keywords)
{
+ bbox_need_update = true;
ui = new Ui::MainWindow;
ui->setupUi(this);
menuBar()->setNativeMenuBar(false);
@@ -212,7 +215,7 @@ MainWindow::MainWindow(const QStringList &keywords, bool verbose, QWidget* paren
this, SLOT(removeManipulatedFrame(CGAL::Three::Scene_item*)));
connect(scene, SIGNAL(updated_bbox(bool)),
- this, SLOT(updateViewersBboxes(bool)));
+ this, SLOT(invalidate_bbox(bool)));
connect(scene, SIGNAL(selectionChanged(int)),
this, SLOT(selectSceneItem(int)));
@@ -915,6 +918,8 @@ void MainWindow::error(QString text) {
void MainWindow::updateViewersBboxes(bool recenter)
{
+ if(bbox_need_update)
+ {
CGAL::qglviewer::Vec min, max;
computeViewerBBox(min, max);
Q_FOREACH(CGAL::QGLViewer* v, CGAL::QGLViewer::QGLViewerPool())
@@ -924,6 +929,8 @@ void MainWindow::updateViewersBboxes(bool recenter)
Viewer* vi = static_cast(v);
updateViewerBbox(vi, recenter, min, max);
}
+ bbox_need_update = false;
+}
}
@@ -936,24 +943,28 @@ void MainWindow::computeViewerBBox(CGAL::qglviewer::Vec& min, CGAL::qglviewer::V
const double xmax = bbox.xmax();
const double ymax = bbox.ymax();
const double zmax = bbox.zmax();
-
-
-
+
+
+
min = CGAL::qglviewer::Vec(xmin, ymin, zmin);
max= CGAL::qglviewer::Vec(xmax, ymax, zmax);
-
+
CGAL::qglviewer::Vec bbox_center((xmin+xmax)/2, (ymin+ymax)/2, (zmin+zmax)/2);
-
+
CGAL::qglviewer::Vec offset(0,0,0);
-
+
double l_dist = (std::max)((std::abs)(bbox_center.x - viewer->offset().x),
(std::max)((std::abs)(bbox_center.y - viewer->offset().y),
(std::abs)(bbox_center.z - viewer->offset().z)));
if((std::log2)(l_dist) > 13.0 )
for(int i=0; i<3; ++i)
{
- offset[i] = -bbox_center[i];
-
+ viewer->setOffset(offset);
+ for(int i=0; inumberOfEntries(); ++i)
+ {
+ scene->item(i)->invalidateOpenGLBuffers();
+ scene->item(i)->itemChanged();
+ }
}
if(offset != viewer->offset())
{
@@ -1147,6 +1158,7 @@ void MainWindow::open(QString filename)
qobject_cast(scene_item);
if(group)
scene->redraw_model();
+ updateViewersBboxes(true);
}
bool MainWindow::open(QString filename, QString loader_name) {
@@ -1645,7 +1657,6 @@ void MainWindow::updateDisplayInfo() {
void MainWindow::readSettings()
{
- QSettings settings;
viewer->setAntiAliasing(settings.value("antialiasing", false).toBool());
viewer->setFastDrawing(settings.value("quick_camera_mode", true).toBool());
scene->enableVisibilityRecentering(settings.value("offset_update", true).toBool());
@@ -1668,7 +1679,6 @@ void MainWindow::writeSettings()
{
this->writeState("MainWindow");
{
- QSettings settings;
//setting plugin blacklist
QStringList blacklist;
Q_FOREACH(QString name,plugin_blacklist){ blacklist << name; }
@@ -1996,13 +2006,16 @@ void MainWindow::on_actionDuplicate_triggered()
void MainWindow::on_actionShowHide_triggered()
{
+ scene->setUpdatesEnabled(false);
Q_FOREACH(QModelIndex index, sceneView->selectionModel()->selectedRows())
{
int i = scene->getIdFromModelIndex(proxyModel->mapToSource(index));
CGAL::Three::Scene_item* item = scene->item(i);
item->setVisible(!item->visible());
- scene->itemChanged(i);
+ item->redraw();
}
+ scene->setUpdatesEnabled(true);
+ updateViewersBboxes(false);
}
void MainWindow::on_actionSetPolyhedronA_triggered()
@@ -2021,7 +2034,6 @@ void MainWindow::on_actionPreferences_triggered()
{
QDialog dialog(this);
Ui::PreferencesDialog prefdiag;
- QSettings settings;
prefdiag.setupUi(&dialog);
float lineWidth[2];
@@ -2276,6 +2288,8 @@ void MainWindow::setAddKeyFrameKeyboardModifiers(::Qt::KeyboardModifiers m)
void MainWindow::on_actionRecenterScene_triggered()
{
+ //force the recomputaion of the bbox
+ bbox_need_update = true;
CGAL::qglviewer::Vec min, max;
computeViewerBBox(min, max);
Q_FOREACH(CGAL::QGLViewer* v, CGAL::QGLViewer::QGLViewerPool())
@@ -2600,6 +2614,86 @@ void MainWindow::propagate_action()
}
}
+void MainWindow::on_actionSa_ve_Scene_as_Script_triggered()
+{
+ QString filename =
+ QFileDialog::getSaveFileName(this,
+ "Save the Scene as a Script File",
+ last_saved_dir,
+ "Qt Script files (*.js)");
+ std::ofstream os(filename.toUtf8());
+ if(!os)
+ return;
+ std::vector names;
+ std::vector loaders;
+ std::vector colors;
+ std::vector rendering_modes;
+ QStringList not_saved;
+ for(int i = 0; i < scene->numberOfEntries(); ++i)
+ {
+ Scene_item* item = scene->item(i);
+ QString loader = item->property("loader_name").toString();
+ QString source = item->property("source filename").toString();
+ if(loader.isEmpty())
+ {
+ not_saved.push_back(item->name());
+ continue;
+ }
+ names.push_back(source);
+ loaders.push_back(loader);
+ colors.push_back(item->color());
+ rendering_modes.push_back(item->renderingMode());
+ }
+ //path
+ os << "var camera = \""<dumpCameraCoordinates().toStdString()<<"\";\n";
+ os << "var items = [";
+ for(std::size_t i = 0; i< names.size() -1; ++i)
+ {
+ os << "\'" << names[i].toStdString() << "\', ";
+ }
+ os<<"\'"<setTotalPass(val);
@@ -2635,9 +2729,10 @@ void MainWindow::setDefaultSaveDir()
QString dirpath = QFileDialog::getExistingDirectory(this, "Set Default Save as Directory", def_save_dir);
if(!dirpath.isEmpty())
def_save_dir = dirpath;
- QSettings settings;
settings.setValue("default_saveas_dir", def_save_dir);
}
+
+
void MainWindow::setupViewer(Viewer* viewer, SubViewer* subviewer)
{
// do not save the state of the viewer (anoying)
@@ -2765,7 +2860,6 @@ void MainWindow::recenterViewer()
void MainWindow::updateViewerBbox(Viewer *vi, bool recenter,
CGAL::qglviewer::Vec min,
CGAL::qglviewer::Vec max){
-
CGAL::qglviewer::Vec center = viewer->camera()->pivotPoint();
vi->setSceneBoundingBox(min,
max);
@@ -2962,3 +3056,10 @@ void SubViewer::changeEvent(QEvent *event)
}
}
}
+
+void MainWindow::invalidate_bbox(bool do_recenter)
+{
+ bbox_need_update = true;
+ if(do_recenter)
+ updateViewersBboxes(true);
+}
diff --git a/Polyhedron/demo/Polyhedron/MainWindow.h b/Polyhedron/demo/Polyhedron/MainWindow.h
index 41983109338..0fa0a1aa590 100644
--- a/Polyhedron/demo/Polyhedron/MainWindow.h
+++ b/Polyhedron/demo/Polyhedron/MainWindow.h
@@ -446,14 +446,17 @@ public:
const QString & fileName = QString());
#endif
public Q_SLOTS:
+ void on_actionSa_ve_Scene_as_Script_triggered();
void toggleFullScreen();
void setDefaultSaveDir();
+ void invalidate_bbox(bool do_recenter);
private:
SubViewer* viewer_window;
QList visibleDockWidgets;
QLineEdit operationSearchBar;
QWidgetAction* searchAction;
QString def_save_dir;
+ bool bbox_need_update;
QMap >plugin_metadata_map;
QMap ignored_map;
const QStringList& accepted_keywords;
diff --git a/Polyhedron/demo/Polyhedron/MainWindow.ui b/Polyhedron/demo/Polyhedron/MainWindow.ui
index 913702682dd..c8cb1728426 100644
--- a/Polyhedron/demo/Polyhedron/MainWindow.ui
+++ b/Polyhedron/demo/Polyhedron/MainWindow.ui
@@ -56,6 +56,7 @@
+
@@ -460,6 +461,11 @@
Ctrl+R
+
+
+ Sa&ve the Scene as a Script File...
+
+
diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp
index c8933c14668..f905a2ecfbe 100644
--- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp
+++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin.cpp
@@ -500,7 +500,8 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults)
tet_sizing,
edge_size,
radius_edge,
- manifold);
+ manifold,
+ surface_only);
}
#endif
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES
@@ -525,6 +526,7 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults)
radius_edge,
protect_features,
manifold,
+ surface_only,
detect_connected_components,
image_item->isGray(),
iso_value,
diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp
index 5d1b055b3ae..ba91f1a93b0 100644
--- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp
+++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.cpp
@@ -176,7 +176,8 @@ Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction,
const double tet_sizing,
const double edge_size,
const double tet_shape,
- const int manifold)
+ const int manifold,
+ const bool surface_only)
{
if (pfunction == NULL) { return NULL; }
@@ -193,7 +194,8 @@ Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction,
[](int i, int j) { return (i * 1000 + j); }
);
- Scene_c3t3_item* p_new_item = new Scene_c3t3_item;
+ Scene_c3t3_item* p_new_item = new Scene_c3t3_item(surface_only);
+
Mesh_parameters param;
param.protect_features = false;
param.facet_angle = facet_angle;
@@ -229,6 +231,7 @@ Meshing_thread* cgal_code_mesh_3(const Image* pImage,
const double tet_shape,
bool protect_features,
const int manifold,
+ const bool surface_only,
bool detect_connected_components,
bool is_gray,
float iso_value,
@@ -251,7 +254,7 @@ Meshing_thread* cgal_code_mesh_3(const Image* pImage,
param.tet_shape = tet_shape;
param.manifold = manifold;
param.image_3_ptr = pImage;
- Scene_c3t3_item* p_new_item = new Scene_c3t3_item;
+ Scene_c3t3_item* p_new_item = new Scene_c3t3_item(surface_only);
if(!is_gray)
{
namespace p = CGAL::parameters;
diff --git a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.h b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.h
index b9e1f75f836..6cae306aea5 100644
--- a/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.h
+++ b/Polyhedron/demo/Polyhedron/Plugins/Mesh_3/Mesh_3_plugin_cgal_code.h
@@ -42,7 +42,8 @@ Meshing_thread* cgal_code_mesh_3(const Implicit_function_interface* pfunction,
const double tet_sizing,
const double edge_size,
const double tet_shape,
- const int manifold);
+ const int manifold,
+ const bool surface_only);
#endif
#ifdef CGAL_MESH_3_DEMO_ACTIVATE_SEGMENTED_IMAGES
@@ -56,6 +57,7 @@ Meshing_thread* cgal_code_mesh_3(const CGAL::Image_3* pImage,
const double tet_shape,
bool protect_features,
const int manifold,
+ const bool surface_only,
bool detect_connected_components,
bool is_gray = false,
float iso_value = 3.f,
diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp
index d363f65d282..547a4a2e06c 100644
--- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp
+++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Hole_filling_plugin.cpp
@@ -130,9 +130,9 @@ public:
else { it->polyline->setWidth(3); }
if(selected_holes.find(it) != selected_holes.end())
- { it->polyline->setRbgColor(255, 0, 0); }
+ { it->polyline->setRgbColor(255, 0, 0); }
else
- { it->polyline->setRbgColor(0, 0, 255); }
+ { it->polyline->setRgbColor(0, 0, 255); }
it->polyline->drawEdges(viewer);
}
diff --git a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_shape_detection_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_shape_detection_plugin.cpp
index df68d2a5bf1..dc769eba0b6 100644
--- a/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_shape_detection_plugin.cpp
+++ b/Polyhedron/demo/Polyhedron/Plugins/Point_set/Point_set_shape_detection_plugin.cpp
@@ -346,7 +346,7 @@ private:
g = static_cast(64 + rand.get_int(0, 192));
b = static_cast(64 + rand.get_int(0, 192));
- point_item->setRbgColor(r, g, b);
+ point_item->setRgbColor(r, g, b);
std::size_t nb_colored_pts = 0;
if (dialog.generate_colored_point_set())
diff --git a/Polyhedron/demo/Polyhedron/Scene.cpp b/Polyhedron/demo/Polyhedron/Scene.cpp
index ebdf9f4248c..94e6ae51c5a 100644
--- a/Polyhedron/demo/Polyhedron/Scene.cpp
+++ b/Polyhedron/demo/Polyhedron/Scene.cpp
@@ -42,6 +42,7 @@ Scene::Scene(QObject* parent)
this, SLOT(adjustIds(Scene_interface::Item_id)));
picked = false;
gl_init = false;
+ dont_emit_changes = false;
}
Scene::Item_id
@@ -1298,14 +1299,23 @@ void Scene::itemChanged()
void Scene::itemChanged(Item_id i)
{
- if(i < 0 || i >= m_entries.size())
- return;
+ if(dont_emit_changes)
+ return;
+ if(i < 0 || i >= m_entries.size())
+ return;
Q_EMIT dataChanged(this->createIndex(i, 0),
this->createIndex(i, LastColumn));
}
-void Scene::itemChanged(CGAL::Three::Scene_item*)
+void Scene::itemChanged(CGAL::Three::Scene_item*item )
+{
+ if(dont_emit_changes)
+ return;
+ itemChanged(item_id(item));
+}
+
+void Scene::allItemsChanged()
{
Q_EMIT dataChanged(this->createIndex(0, 0),
this->createIndex(m_entries.size() - 1, LastColumn));
@@ -1324,8 +1334,10 @@ void Scene::itemVisibilityChanged(CGAL::Three::Scene_item* item)
&& !item->isEmpty())
{
//does not recenter
- if(visibility_recentering_enabled)
- Q_EMIT updated_bbox(false);
+ if(visibility_recentering_enabled){
+ Q_EMIT updated_bbox(true);
+
+ }
}
}
diff --git a/Polyhedron/demo/Polyhedron/Scene.h b/Polyhedron/demo/Polyhedron/Scene.h
index 8730cced530..c8b5fd7cde7 100644
--- a/Polyhedron/demo/Polyhedron/Scene.h
+++ b/Polyhedron/demo/Polyhedron/Scene.h
@@ -141,7 +141,13 @@ public:
void zoomToPosition(QPoint point,
CGAL::Three::Viewer_interface*) Q_DECL_OVERRIDE;
-
+ void setUpdatesEnabled(bool b) Q_DECL_OVERRIDE
+ {
+ dont_emit_changes = b;
+ if(b)
+ allItemsChanged();
+ }
+
public Q_SLOTS:
//!Specifies a group as Expanded for the Geometric Objects view
void setExpanded(QModelIndex);
@@ -151,6 +157,7 @@ public Q_SLOTS:
void itemChanged();
void itemChanged(int i) Q_DECL_OVERRIDE;
void itemChanged(CGAL::Three::Scene_item*) Q_DECL_OVERRIDE;
+ void allItemsChanged() Q_DECL_OVERRIDE;
//!Transmits a CGAL::Three::Scene_item::itemVisibilityChanged() signal to the scene.
void itemVisibilityChanged();
void itemVisibilityChanged(CGAL::Three::Scene_item*) Q_DECL_OVERRIDE;
@@ -291,6 +298,8 @@ private:
QMap vaos;
mutable QOpenGLBuffer vbo[2];
Bbox last_bbox;
+ //the scene will ignore the itemChanged() signals while this is true.
+ bool dont_emit_changes;
bool visibility_recentering_enabled;
bool sort_lists(QVector >&sorted_lists, bool up);
}; // end class Scene
diff --git a/STL_Extension/test/STL_Extension/test_dispatch_output.cpp b/STL_Extension/test/STL_Extension/test_dispatch_output.cpp
index 8036587fc81..b8df6175cdc 100644
--- a/STL_Extension/test/STL_Extension/test_dispatch_output.cpp
+++ b/STL_Extension/test/STL_Extension/test_dispatch_output.cpp
@@ -23,7 +23,7 @@ void check_types(output out){
CGAL_USE_TYPE(typename output::pointer);
CGAL_USE_TYPE(typename output::reference);
T1 tmp=out.get_iterator_tuple();
- tmp=tmp;
+ tmp=(T1&)tmp;
}
template
@@ -69,8 +69,8 @@ void complete_test(std::vector data1,std::list data2){
check_types(disp);
check_types(drop);
- disp = disp;
- drop = drop;
+ disp = (Dispatcher&)disp;
+ drop = (Dropper&)drop;
std::back_insert_iterator > bck_ins(cont_2);
diff --git a/Scripts/developer_scripts/git-show-content b/Scripts/developer_scripts/git-show-content
index 5ccd986a7ac..b72e089e828 100755
--- a/Scripts/developer_scripts/git-show-content
+++ b/Scripts/developer_scripts/git-show-content
@@ -14,17 +14,17 @@ function reset() {
trap reset ERR EXIT KILL TERM INT
-for c in $(git log --pretty='%h' --first-parent cgal/master..$base); do
+for c in $(git --no-pager log --pretty='%h' --first-parent cgal/master..$base); do
git update-ref refs/cgal/git-show-content $c
git bundle create bundle ${c}^..refs/cgal/git-show-content > /dev/null 2>&1
gzip -f bundle
size=${(l:4:)$(( $(zstat +size bundle.gz) / 1024 ))}
- git show --no-patch --pretty='%C(auto)%h (SIZE: %C(auto)'"${size}kB)"' %s <%an> %cD' $c
+ git --no-pager show --no-patch --pretty='%C(auto)%h (SIZE: %C(auto)'"${size}kB)"' %s <%an> %cD' $c
parents=(${(@)$(git rev-parse $c^@)})
if ! [ ${#${parents:1}[@]} -eq 0 ]; then
- git show --no-patch --pretty=' merge: %h%C(auto)% d' ${parents:1}
+ git --no-pager show --no-patch --pretty=' merge: %h%C(auto)% d' ${parents:1}
fi
done
last=$c
-[ -n "$last" ] && git log -1 --pretty='Base commit: %C(auto)%h %d' ${last}'~'
+[ -n "$last" ] && git --no-pager log -1 --pretty='Base commit: %C(auto)%h %d' ${last}'~'
diff --git a/Segment_Delaunay_graph_2/test/Segment_Delaunay_graph_2/include/test_types.h b/Segment_Delaunay_graph_2/test/Segment_Delaunay_graph_2/include/test_types.h
index 630d7411361..612bcffa80b 100644
--- a/Segment_Delaunay_graph_2/test/Segment_Delaunay_graph_2/include/test_types.h
+++ b/Segment_Delaunay_graph_2/test/Segment_Delaunay_graph_2/include/test_types.h
@@ -167,7 +167,7 @@ bool test_sdg(InputStream&, const SDG&, const char* ifname, const char* ofname,
start_testing("assignment operator");
sdg.insert(site_list.begin(), site_list.end());
- sdg = sdg;
+ sdg = (Segment_Delaunay_graph_2&)sdg;
sdg2 = sdg;
assert( sdg.is_valid() );
diff --git a/Segment_Delaunay_graph_Linf_2/test/Segment_Delaunay_graph_Linf_2/include/test_types.h b/Segment_Delaunay_graph_Linf_2/test/Segment_Delaunay_graph_Linf_2/include/test_types.h
index b28f452f0a3..a2e414a691c 100644
--- a/Segment_Delaunay_graph_Linf_2/test/Segment_Delaunay_graph_Linf_2/include/test_types.h
+++ b/Segment_Delaunay_graph_Linf_2/test/Segment_Delaunay_graph_Linf_2/include/test_types.h
@@ -167,7 +167,7 @@ bool test_sdg(InputStream&, const SDG&, const char* ifname, const char* ofname,
start_testing("assignment operator");
sdg.insert(site_list.begin(), site_list.end());
- sdg = sdg;
+ sdg = (Segment_Delaunay_graph_2&)sdg;
sdg2 = sdg;
assert( sdg.is_valid() );
diff --git a/Three/include/CGAL/Three/Scene_interface.h b/Three/include/CGAL/Three/Scene_interface.h
index b6e39f9feb6..71d772a3263 100644
--- a/Three/include/CGAL/Three/Scene_interface.h
+++ b/Three/include/CGAL/Three/Scene_interface.h
@@ -148,7 +148,17 @@ public:
virtual void itemVisibilityChanged(CGAL::Three::Scene_item*) = 0;
//! Clears the current selection then sets the selected item to the target index.
//! Used to update the selection in the Geometric Objects view.
- virtual void setSelectedItem(Item_id) = 0;
+ virtual void setSelectedItem(Item_id) = 0;
+ //! \brief ignore data updating.
+ //!
+ //! This will ignore all the individual calls to `itemChanged()` until
+ //! `setUpdatesEnabled()` is called whith `b` being `true`.
+ //!
+ virtual void setUpdatesEnabled(bool b) =0;
+ //!
+ //! \brief Updates all the items in the SceneView.
+ //!
+ virtual void allItemsChanged() = 0;
}; // end interface Scene_interface
}
}
diff --git a/Three/include/CGAL/Three/Scene_item.h b/Three/include/CGAL/Three/Scene_item.h
index 65cefc51816..465fe18ddd3 100644
--- a/Three/include/CGAL/Three/Scene_item.h
+++ b/Three/include/CGAL/Three/Scene_item.h
@@ -330,7 +330,7 @@ public Q_SLOTS:
virtual void setColor(QColor c) { color_ = c;}
//!Setter for the RGB color of the item. Calls setColor(QColor).
//!@see setColor(QColor c)
- void setRbgColor(int r, int g, int b) { setColor(QColor(r, g, b)); }
+ void setRgbColor(int r, int g, int b) { setColor(QColor(r, g, b)); }
//!Sets the name of the item.
virtual void setName(QString n) { name_ = n; }
//!Sets the visibility of the item.
@@ -339,6 +339,7 @@ public Q_SLOTS:
//!This function is called by `Scene::changeGroup` and should not be
//!called manually.
virtual void moveToGroup(Scene_group_item* group);
+ void setRenderingMode(int m) { setRenderingMode((RenderingMode)m);}
//!Sets the rendering mode of the item.
//!@see RenderingMode
virtual void setRenderingMode(RenderingMode m) {
diff --git a/Triangulation/examples/Triangulation/delaunay_triangulation.cpp b/Triangulation/examples/Triangulation/delaunay_triangulation.cpp
index 73fafb3d1c7..036c0de6d50 100644
--- a/Triangulation/examples/Triangulation/delaunay_triangulation.cpp
+++ b/Triangulation/examples/Triangulation/delaunay_triangulation.cpp
@@ -24,7 +24,7 @@ int main()
{ 100, 100, 100, 100, 100, 100, 100 }
};
- typedef CGAL::Triangulation > > T;
+ typedef CGAL::Delaunay_triangulation > > T;
T dt(7);
std::vector points;