From 566149c0cca8a70bd3153a620e8eac64dfdbc7ec Mon Sep 17 00:00:00 2001 From: Sven Oesau Date: Wed, 29 Nov 2023 08:22:24 +0100 Subject: [PATCH 1/7] FacetTriangulator: removing ghost edges from cdt and using mark_domain_in_triangulation --- .../Polyhedron/Plugins/IO/PLY_io_plugin.cpp | 2 +- .../Polyhedron/Scene_polygon_soup_item.cpp | 3 +- .../Polyhedron/Scene_surface_mesh_item.cpp | 1 + .../demo/Polyhedron/triangulate_primitive.h | 65 +++++++++++++++++-- .../include/CGAL/IO/PLY/PLY_reader.h | 6 ++ 5 files changed, 70 insertions(+), 7 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp index fe4120c59191..e7d371e08918 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp @@ -132,7 +132,7 @@ load(QFileInfo fileinfo, bool& ok, bool add_to_scene) { std::vector fcolors; std::vector vcolors; - if (!(CGAL::IO::read_PLY (in, points, polygons, fcolors, vcolors))) + if (!(CGAL::IO::read_PLY (in, points, polygons, fcolors, vcolors, true))) { QApplication::restoreOverrideCursor(); ok = false; diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 8ba8813f3494..a7e32dc0d266 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -150,6 +150,7 @@ Scene_polygon_soup_item_priv::triangulate_polygon(Polygons_iterator pit, int pol pointIds.push_back(pointId); } while( ++it != it_end ); //detect degenerated faces +/* std::vector pid_stack = pointIds; for(std::size_t i = 0; i< pointIds.size(); ++i) { @@ -162,7 +163,7 @@ Scene_polygon_soup_item_priv::triangulate_polygon(Polygons_iterator pit, int pol return; } } - } + }*/ FT triangulation(pointIds,normal); //iterates on the internal faces to add the vertices to the positions //and the normals to the appropriate vectors diff --git a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp index 49e2da75e659..3dce2285c44e 100644 --- a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp @@ -1040,6 +1040,7 @@ Scene_surface_mesh_item_priv::triangulate_facet(face_descriptor fd, } } + void delete_aabb_tree(Scene_surface_mesh_item* item) { QVariant aabb_tree_property = item->property(aabb_property_name); diff --git a/Polyhedron/demo/Polyhedron/triangulate_primitive.h b/Polyhedron/demo/Polyhedron/triangulate_primitive.h index cf7aa8a457bb..fd154ad05144 100644 --- a/Polyhedron/demo/Polyhedron/triangulate_primitive.h +++ b/Polyhedron/demo/Polyhedron/triangulate_primitive.h @@ -6,6 +6,7 @@ #include #include #include +#include #include @@ -45,7 +46,7 @@ class FacetTriangulator using Fbb = CGAL::Triangulation_face_base_with_info_2; using Fb = CGAL::Constrained_triangulation_face_base_2; using TDS = CGAL::Triangulation_data_structure_2; - using Itag = CGAL::Exact_predicates_tag; + using Itag = CGAL::Exact_predicates_tag;//Exact_intersections_tag using CDT = CGAL::Constrained_Delaunay_triangulation_2; using Vertex_handle = typename CDT::Vertex_handle; @@ -121,13 +122,40 @@ class FacetTriangulator P_traits cdt_traits(normal); cdt = new CDT(cdt_traits); + std::map, std::size_t> edge_map; + std::vector skip(idPoints.size(), false); + bool has_ghost_edges = false; + +/* + for (std::size_t i = 0; i < idPoints.size(); i++) { + int prev = (i - 1 + idPoints.size()) % idPoints.size(); + if (idPoints[i].point < idPoints[prev].point) { + auto it = edge_map.emplace(std::make_pair(idPoints[i].point, idPoints[prev].point), i); + if (!it.second) { + skip[i] = true; + skip[it.first->second] = true; + has_ghost_edges = true; + } + } + else { + auto it = edge_map.emplace(std::make_pair(idPoints[prev].point, idPoints[i].point), i); + if (!it.second) { + skip[i] = true; + skip[it.first->second] = true; + has_ghost_edges = true; + } + } + }*/ + Vertex_handle previous, first, last_inserted; + std::size_t previd, firstid, lastid; // Iterate the points of the facet and decide if they must be inserted in the CDT typename Kernel::FT x(0), y(0), z(0); - for(const PointAndId& idPoint : idPoints) + for(std::size_t i = 0;iinsert(idPoint.point); v2v[vh] = idPoint.id; - if(first == Vertex_handle()) + if (first == Vertex_handle()) { first = vh; + firstid = idPoint.id; + } if(previous != nullptr && previous != vh) { - cdt->insert_constraint(previous, vh); + if (!skip[i]) + cdt->insert_constraint(previous, vh); last_inserted = previous; + lastid = previd; } previous = vh; + previd = idPoint.id; } } if(last_inserted == Vertex_handle()) return false; - if(previous != first) + if(previous != first && !skip[0]) cdt->insert_constraint(previous, first); +/* + std::vector pts; + std::ofstream vout("test.polylines.txt"); + for (auto& e : cdt->constrained_edges()) { + // edge is a pair of Face_handle and index + auto v1 = e.first->vertex((e.second + 1) % 3); + auto v2 = e.first->vertex((e.second + 2) % 3); + pts.push_back(v1->point()); + pts.push_back(v2->point()); + vout << "2 " << v1->point() << " " << v2->point() << std::endl; + } + vout.close();*/ + // sets mark is_external for(Face_handle f2 : cdt->all_face_handles()) f2->info().is_external = false; + std::unordered_map in_domain_map; + boost::associative_property_map< std::unordered_map > in_domain(in_domain_map); + CGAL::mark_domain_in_triangulation(*cdt, in_domain); + // check if the facet is external or internal +/* std::queue face_queue; face_queue.push(cdt->infinite_vertex()->face()); while(! face_queue.empty()) @@ -176,6 +227,10 @@ class FacetTriangulator if(!cdt->is_constrained(std::make_pair(fh, i))) face_queue.push(fh->neighbor(i)); } + }*/ + + for (const Face_handle& fh : cdt->all_face_handles()) { + fh->info().is_external = !get(in_domain, fh); } return true; diff --git a/Stream_support/include/CGAL/IO/PLY/PLY_reader.h b/Stream_support/include/CGAL/IO/PLY/PLY_reader.h index ee8b18ef59c0..c1a0ab4e580a 100644 --- a/Stream_support/include/CGAL/IO/PLY/PLY_reader.h +++ b/Stream_support/include/CGAL/IO/PLY/PLY_reader.h @@ -726,6 +726,9 @@ bool read_PLY_faces(std::istream& in, for(std::size_t j = 0; j < element.number_of_items(); ++ j) { + if (j == 228) + std::cout << std::endl; + for(std::size_t k = 0; k < element.number_of_properties(); ++ k) { PLY_read_number* property = element.property(k); @@ -758,6 +761,9 @@ bool read_PLY_faces(std::istream& in, PLY_property >(vertex_indices_tag))); } + if (get<0>(new_face).size() == 0) + std::cout << "empty face encountered" << std::endl; + polygons.emplace_back(); ::CGAL::internal::resize(polygons.back(), get<0>(new_face).size()); for(std::size_t i = 0; i < get<0>(new_face).size(); ++ i) From 9115847ed4c7f95b9cf727cd1af896cc74759747 Mon Sep 17 00:00:00 2001 From: Sven Oesau Date: Thu, 30 Nov 2023 16:03:28 +0100 Subject: [PATCH 2/7] added handling for rendering of non-triangular faces with ghost edges ghost edges are not added to cdt in FacetTriangulator mark_domain_in_triangulation is used to mark holes as external --- .../Plugins/PMP/Distance_plugin.cpp | 57 +++--- .../Polyhedron/Scene_polygon_soup_item.cpp | 106 +++++------ .../Scene_polyhedron_selection_item.cpp | 39 ++-- .../Polyhedron/Scene_surface_mesh_item.cpp | 125 +++++++------ .../demo/Polyhedron/triangulate_primitive.h | 169 ++++++++---------- 5 files changed, 239 insertions(+), 257 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Distance_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Distance_plugin.cpp index d6d3c6a1a45b..72e1475f82ff 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Distance_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Distance_plugin.cpp @@ -190,13 +190,10 @@ class Scene_distance_polyhedron_item: public Scene_item_rendering_helper for(boost::graph_traits::face_descriptor f : faces(*poly)) { Vector nf = get(nf_pmap, f); - typedef FacetTriangulator::vertex_descriptor> FT; - //compute distance with other polyhedron //sample facet std::vector sampled_points; - std::size_t nb_points = (std::max)((int)std::ceil(nb_pts_per_face * PMP::face_area(f,*poly,CGAL::parameters::geom_traits(Kernel()))), - 1); + std::size_t nb_points = (std::max)((int)std::ceil(nb_pts_per_face * PMP::face_area(f,*poly,CGAL::parameters::geom_traits(Kernel()))), 1); Kernel::Point_3 &p = get(vpmap,target(halfedge(f,*poly),*poly)); Kernel::Point_3 &q = get(vpmap,target(next(halfedge(f,*poly),*poly),*poly)); Kernel::Point_3 &r = get(vpmap,target(next(next(halfedge(f,*poly),*poly),*poly),*poly)); @@ -207,36 +204,42 @@ class Scene_distance_polyhedron_item: public Scene_item_rendering_helper sampled_points.push_back(r); //triangle facets with sample points for color display - FT triangulation(f,sampled_points,nf,poly); - - if(triangulation.cdt->dimension() != 2 ) - { - qDebug()<<"Error : cdt not right (dimension != 2). Facet not displayed"; - continue; - } - - //iterates on the internal faces to add the vertices to the positions - //and the normals to the appropriate vectors + auto func = [&](auto& ffit, auto& v2v) { + if (ffit.info().is_external) + return; - for(FT::CDT::Finite_faces_iterator - ffit = triangulation.cdt->finite_faces_begin(), - end = triangulation.cdt->finite_faces_end(); - ffit != end; ++ffit) - { - if(ffit->info().is_external) - continue; - - for (int i = 0; i<3; ++i) + for (int i = 0; i < 3; ++i) { - total_points.push_back(ffit->vertex(i)->point()); - m_vertices.push_back(ffit->vertex(i)->point().x()); - m_vertices.push_back(ffit->vertex(i)->point().y()); - m_vertices.push_back(ffit->vertex(i)->point().z()); + total_points.push_back(ffit.vertex(i)->point()); + m_vertices.push_back(ffit.vertex(i)->point().x()); + m_vertices.push_back(ffit.vertex(i)->point().y()); + m_vertices.push_back(ffit.vertex(i)->point().z()); normals.push_back(nf.x()); normals.push_back(nf.y()); normals.push_back(nf.z()); } + }; + + try { + FacetTriangulator::vertex_descriptor> triangulation(f, sampled_points, nf, poly); + + if (triangulation.cdt->dimension() != 2) + { + qDebug() << "Error : cdt not right (dimension != 2). Facet not displayed"; + continue; + } + triangulation.per_face(func); + } + catch (...) { + FacetTriangulator::vertex_descriptor, CGAL::Exact_intersections_tag> triangulation(f, sampled_points, nf, poly); + + if (triangulation.cdt->dimension() != 2) + { + qDebug() << "Error : cdt not right (dimension != 2). Facet not displayed"; + continue; + } + triangulation.per_face(func); } } //compute the distances diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index a7e32dc0d266..7bdc0f69a0c0 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -137,81 +137,71 @@ Scene_polygon_soup_item_priv::triangulate_polygon(Polygons_iterator pit, int pol if (normal == CGAL::NULL_VECTOR) // No normal could be computed, return return; - typedef FacetTriangulator FT; + typedef std::pair PointAndId; std::size_t it = 0; std::size_t it_end =pit->size(); - std::vector pointIds; + std::vector pointIds; do { - FT::PointAndId pointId; + PointAndId pointId; - pointId.point = soup->points[pit->at(it)]+offset; - pointId.id = pit->at(it); + pointId.first = soup->points[pit->at(it)]+offset; + pointId.second = pit->at(it); pointIds.push_back(pointId); } while( ++it != it_end ); - //detect degenerated faces -/* - std::vector pid_stack = pointIds; - for(std::size_t i = 0; i< pointIds.size(); ++i) - { - FT::PointAndId pid = pid_stack.back(); - pid_stack.pop_back(); - for(FT::PointAndId poai : pid_stack) - { - if (pid.point== poai.point) - { - return; - } - } - }*/ - FT triangulation(pointIds,normal); + //iterates on the internal faces to add the vertices to the positions //and the normals to the appropriate vectors - for(FT::CDT::Finite_faces_iterator - ffit = triangulation.cdt->finite_faces_begin(), - end = triangulation.cdt->finite_faces_end(); - ffit != end; ++ffit) - { - if(ffit->info().is_external) - continue; - - positions_poly.push_back(ffit->vertex(0)->point().x()); - positions_poly.push_back(ffit->vertex(0)->point().y()); - positions_poly.push_back(ffit->vertex(0)->point().z()); + auto f = [&](auto& ffit, auto& v2v) { + if (ffit.info().is_external) + return; + positions_poly.push_back(ffit.vertex(0)->point().x()); + positions_poly.push_back(ffit.vertex(0)->point().y()); + positions_poly.push_back(ffit.vertex(0)->point().z()); - positions_poly.push_back(ffit->vertex(1)->point().x()); - positions_poly.push_back(ffit->vertex(1)->point().y()); - positions_poly.push_back(ffit->vertex(1)->point().z()); + positions_poly.push_back(ffit.vertex(1)->point().x()); + positions_poly.push_back(ffit.vertex(1)->point().y()); + positions_poly.push_back(ffit.vertex(1)->point().z()); - positions_poly.push_back(ffit->vertex(2)->point().x()); - positions_poly.push_back(ffit->vertex(2)->point().y()); - positions_poly.push_back(ffit->vertex(2)->point().z()); + positions_poly.push_back(ffit.vertex(2)->point().x()); + positions_poly.push_back(ffit.vertex(2)->point().y()); + positions_poly.push_back(ffit.vertex(2)->point().z()); - CGAL::IO::Color color; - if(!soup->fcolors.empty()) - color = soup->fcolors[polygon_id]; - for(int i=0; i<3; i++) + CGAL::IO::Color color; + if (!soup->fcolors.empty()) + color = soup->fcolors[polygon_id]; + for (int i = 0; i < 3; i++) + { + normals.push_back(normal.x()); + normals.push_back(normal.y()); + normals.push_back(normal.z()); + if (!soup->fcolors.empty()) { - normals.push_back(normal.x()); - normals.push_back(normal.y()); - normals.push_back(normal.z()); - if(!soup->fcolors.empty()) - { - f_colors.push_back(static_cast(color.red())/255); - f_colors.push_back(static_cast(color.green())/255); - f_colors.push_back(static_cast(color.blue())/255); - } - if(!soup->vcolors.empty()) - { - CGAL::IO::Color vcolor = soup->vcolors[triangulation.v2v[ffit->vertex(i)]]; - v_colors.push_back(static_cast(vcolor.red())/255); - v_colors.push_back(static_cast(vcolor.green())/255); - v_colors.push_back(static_cast(vcolor.blue())/255); - } + f_colors.push_back(static_cast(color.red()) / 255); + f_colors.push_back(static_cast(color.green()) / 255); + f_colors.push_back(static_cast(color.blue()) / 255); + } + if (!soup->vcolors.empty()) + { + CGAL::IO::Color vcolor = soup->vcolors[v2v[ffit.vertex(i)]]; + v_colors.push_back(static_cast(vcolor.red()) / 255); + v_colors.push_back(static_cast(vcolor.green()) / 255); + v_colors.push_back(static_cast(vcolor.blue()) / 255); } + } + }; + + try { + FacetTriangulator triangulation(pointIds, normal); + triangulation.per_face(f); + } + catch (...) { + FacetTriangulator triangulation(pointIds, normal); + triangulation.per_face(f); } } + void Scene_polygon_soup_item_priv::compute_normals_and_vertices() const{ diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp index 893b6bac7196..70cda242d019 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp @@ -282,26 +282,29 @@ Scene_polyhedron_selection_item_priv::triangulate_facet(fg_face_descriptor fit,c const CGAL::qglviewer::Vec off = Three::mainViewer()->offset(); EPICK::Vector_3 offset(off.x,off.y,off.z); - typedef FacetTriangulator FT; - FT triangulation(fit,normal,poly, offset); - //iterates on the internal faces to add the vertices to the positions - //and the normals to the appropriate vectors - for(FT::CDT::Finite_faces_iterator - ffit = triangulation.cdt->finite_faces_begin(), - end = triangulation.cdt->finite_faces_end(); - ffit != end; ++ffit) - { - if(ffit->info().is_external) - continue; + //iterates on the internal faces to add the vertices to the positions + //and the normals to the appropriate vectors + auto f = [&](auto& ffit, auto& v2v) { + if (ffit.info().is_external) + return; - push_back_xyz(ffit->vertex(0)->point(), p_facets); - push_back_xyz(ffit->vertex(1)->point(), p_facets); - push_back_xyz(ffit->vertex(2)->point(), p_facets); + push_back_xyz(ffit.vertex(0)->point(), p_facets); + push_back_xyz(ffit.vertex(1)->point(), p_facets); + push_back_xyz(ffit.vertex(2)->point(), p_facets); - push_back_xyz(normal, p_normals); - push_back_xyz(normal, p_normals); - push_back_xyz(normal, p_normals); - } + push_back_xyz(normal, p_normals); + push_back_xyz(normal, p_normals); + push_back_xyz(normal, p_normals); + }; + + try { + FacetTriangulator triangulation(fit, normal, poly, offset); + triangulation.per_face(f); + } + catch (...) { + FacetTriangulator triangulation(fit, normal, poly, offset); + triangulation.per_face(f); + } } diff --git a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp index 3dce2285c44e..688cf8587459 100644 --- a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp @@ -984,60 +984,63 @@ Scene_surface_mesh_item_priv::triangulate_facet(face_descriptor fd, return; } - typedef FacetTriangulator::vertex_descriptor> FT; const CGAL::qglviewer::Vec off = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); EPICK::Vector_3 offset(off.x,off.y,off.z); - FT triangulation(fd,normal,smesh_, offset); + //iterates on the internal faces - for(FT::CDT::Finite_faces_iterator - ffit = triangulation.cdt->finite_faces_begin(), - end = triangulation.cdt->finite_faces_end(); - ffit != end; ++ffit) - { - if(ffit->info().is_external) - continue; + auto f = [&](auto& ffit, auto& v2v) { + if (ffit.info().is_external) + return; //add the vertices to the positions //adds the vertices, normals and colors to the appropriate vectors - if(!index) + if (!index) { CGAL::IO::Color* color; - if(has_fpatch_id) + if (has_fpatch_id) { - QColor c= item->color_vector()[fpatch_id_map[fd] - min_patch_id]; - color = new CGAL::IO::Color(c.red(),c.green(),c.blue()); + QColor c = item->color_vector()[fpatch_id_map[fd] - min_patch_id]; + color = new CGAL::IO::Color(c.red(), c.green(), c.blue()); } - else if(has_fcolors) + else if (has_fcolors) color = &(*fcolors)[fd]; else color = nullptr; - addFlatData(ffit->vertex(0)->point()-offset, - (*fnormals)[fd], - color, - name); - addFlatData(ffit->vertex(1)->point()-offset, - (*fnormals)[fd], - color, - name); - - addFlatData(ffit->vertex(2)->point()-offset, - (*fnormals)[fd], - color, - name); - if(has_fpatch_id) + addFlatData(ffit.vertex(0)->point() - offset, + (*fnormals)[fd], + color, + name); + addFlatData(ffit.vertex(1)->point() - offset, + (*fnormals)[fd], + color, + name); + + addFlatData(ffit.vertex(2)->point() - offset, + (*fnormals)[fd], + color, + name); + if (has_fpatch_id) delete color; } //adds the indices to the appropriate vector else { - if(name.testFlag(Scene_item_rendering_helper::GEOMETRY)) + if (name.testFlag(Scene_item_rendering_helper::GEOMETRY)) { - idx_data_.push_back((*im)[triangulation.v2v[ffit->vertex(0)]]); - idx_data_.push_back((*im)[triangulation.v2v[ffit->vertex(1)]]); - idx_data_.push_back((*im)[triangulation.v2v[ffit->vertex(2)]]); + idx_data_.push_back((*im)[v2v[ffit.vertex(0)]]); + idx_data_.push_back((*im)[v2v[ffit.vertex(1)]]); + idx_data_.push_back((*im)[v2v[ffit.vertex(2)]]); } } + }; + try { + FacetTriangulator::vertex_descriptor> triangulation(fd, normal, smesh_, offset); + triangulation.per_face(f); + } + catch (...) { + FacetTriangulator::vertex_descriptor, CGAL::Exact_intersections_tag> triangulation(fd, normal, smesh_, offset); + triangulation.per_face(f); } } @@ -1357,7 +1360,6 @@ void Scene_surface_mesh_item::invalidate(Gl_data_names name) QList Scene_surface_mesh_item_priv::triangulate_primitive(face_descriptor fit, EPICK::Vector_3 normal) { - typedef FacetTriangulator::vertex_descriptor> FT; //The output list QList res; //check if normal contains NaN values @@ -1366,23 +1368,27 @@ QList Scene_surface_mesh_item_priv::triangulate_primitive(fac qDebug()<<"Warning in triangulation of the selection item: normal contains NaN values and is not valid."; return QList(); } - FT triangulation(fit,normal,smesh_); + //iterates on the internal faces to add the vertices to the positions //and the normals to the appropriate vectors - for( FT::CDT::Finite_faces_iterator - ffit = triangulation.cdt->finite_faces_begin(), - end = triangulation.cdt->finite_faces_end(); - ffit != end; ++ffit) - { - if(ffit->info().is_external) - continue; - + auto f = [&](auto &ffit, auto& v2v) { + if (ffit.info().is_external) + return; - res << EPICK::Triangle_3(ffit->vertex(0)->point(), - ffit->vertex(1)->point(), - ffit->vertex(2)->point()); + res << EPICK::Triangle_3(ffit.vertex(0)->point(), + ffit.vertex(1)->point(), + ffit.vertex(2)->point()); + }; + try { + FacetTriangulator::vertex_descriptor> triangulation(fit, normal, smesh_); + triangulation.per_face(f); } + catch (...) { + FacetTriangulator::vertex_descriptor, CGAL::Exact_intersections_tag> triangulation(fit, normal, smesh_); + triangulation.per_face(f); + } + return res; } @@ -2620,21 +2626,24 @@ void Scene_surface_mesh_item::fill_flat_vertex_map() return; } - typedef FacetTriangulator::vertex_descriptor> FT; const CGAL::qglviewer::Vec off = static_cast(CGAL::QGLViewer::QGLViewerPool().first())->offset(); EPICK::Vector_3 offset(off.x,off.y,off.z); - FT triangulation(fd,normal,face_graph(), offset); - //iterates on the internal faces - for(FT::CDT::Finite_faces_iterator - ffit = triangulation.cdt->finite_faces_begin(), - end = triangulation.cdt->finite_faces_end(); - ffit != end; ++ffit) - { - if(ffit->info().is_external) - continue; - d->flat_vertices_map[triangulation.v2v[ffit->vertex(0)]].push_back(counter++); - d->flat_vertices_map[triangulation.v2v[ffit->vertex(1)]].push_back(counter++); - d->flat_vertices_map[triangulation.v2v[ffit->vertex(2)]].push_back(counter++); + + auto f = [&](auto ffit, auto &v2v) { + if (ffit.info().is_external) + return; + d->flat_vertices_map[v2v[ffit.vertex(0)]].push_back(counter++); + d->flat_vertices_map[v2v[ffit.vertex(1)]].push_back(counter++); + d->flat_vertices_map[v2v[ffit.vertex(2)]].push_back(counter++); + }; + + try { + FacetTriangulator::vertex_descriptor> triangulation(fd, normal, face_graph(), offset); + triangulation.per_face(f); + } + catch (...) { + FacetTriangulator::vertex_descriptor, CGAL::Exact_intersections_tag> triangulation(fd, normal, face_graph(), offset); + triangulation.per_face(f); } } } diff --git a/Polyhedron/demo/Polyhedron/triangulate_primitive.h b/Polyhedron/demo/Polyhedron/triangulate_primitive.h index fd154ad05144..a294581e15d8 100644 --- a/Polyhedron/demo/Polyhedron/triangulate_primitive.h +++ b/Polyhedron/demo/Polyhedron/triangulate_primitive.h @@ -23,7 +23,7 @@ // @todo just use PMP::triangulate_face()...? // or at least mark_faces_in_domain() -template +template class FacetTriangulator { public: @@ -31,6 +31,8 @@ class FacetTriangulator using Point = typename Kernel::Point_3; using Vector = typename Kernel::Vector_3; + using Index = Index_type; + using P_traits = CGAL::Projection_traits_3; using halfedge_descriptor = typename boost::graph_traits::halfedge_descriptor; @@ -46,23 +48,14 @@ class FacetTriangulator using Fbb = CGAL::Triangulation_face_base_with_info_2; using Fb = CGAL::Constrained_triangulation_face_base_2; using TDS = CGAL::Triangulation_data_structure_2; - using Itag = CGAL::Exact_predicates_tag;//Exact_intersections_tag - using CDT = CGAL::Constrained_Delaunay_triangulation_2; + using CDT = CGAL::Constrained_Delaunay_triangulation_2; using Vertex_handle = typename CDT::Vertex_handle; using Face_handle = typename CDT::Face_handle; - struct PointAndId - { - Point point; - Index_type id; - PointAndId() = default; - PointAndId(const Point& point, const Index_type id) : point(point), id(id) { } - }; - public: CDT* cdt; - CGAL::Unique_hash_map v2v; + CGAL::Unique_hash_map v2v; public: // Constructor @@ -71,10 +64,10 @@ class FacetTriangulator Mesh* poly, Vector offset = Vector(0,0,0)) { - std::vector idPoints; + std::vector > idPoints; for(halfedge_descriptor he_circ : halfedges_around_face(halfedge(fd, *poly), *poly)) - idPoints.emplace_back(get(CGAL::vertex_point, *poly, source(he_circ, *poly)) + offset, - source(he_circ, *poly)); + idPoints.emplace_back(std::make_pair(get(CGAL::vertex_point, *poly, source(he_circ, *poly)) + offset, + source(he_circ, *poly))); if(!triangulate(idPoints, normal)) std::cerr << "Facet not displayed" << std::endl; @@ -86,22 +79,22 @@ class FacetTriangulator Mesh* poly, Vector offset = Vector(0,0,0)) { - std::vector idPoints; + std::vector > idPoints; for(halfedge_descriptor he_circ : halfedges_around_face(halfedge(fd, *poly), *poly)) - idPoints.emplace_back(get(CGAL::vertex_point, *poly, source(he_circ, *poly)) + offset, - source(he_circ, *poly)); + idPoints.emplace_back(std::make_pair(get(CGAL::vertex_point, *poly, source(he_circ, *poly)) + offset, + source(he_circ, *poly))); if(!triangulate_with_points(idPoints, more_points, normal)) std::cerr << "Facet not displayed" << std::endl; } - FacetTriangulator(std::vector& idPoints, + FacetTriangulator(std::vector >& idPoints, const Vector& normal) { if(!triangulate(idPoints, normal)) std::cerr << "Facet not displayed" << std::endl; } - FacetTriangulator(std::vector& idPoints, + FacetTriangulator(std::vector < std::pair >& idPoints, const std::vector& more_points, const Vector& normal) { @@ -115,8 +108,14 @@ class FacetTriangulator delete cdt; } + template + void per_face(const Func& f) { + for (typename CDT::Finite_faces_iterator fit = cdt->finite_faces_begin(); fit != cdt->finite_faces_end(); ++fit) + f(*fit, v2v); + } + private: - bool triangulate(std::vector& idPoints, + bool triangulate(std::vector >& idPoints, const Vector& normal) { P_traits cdt_traits(normal); @@ -124,28 +123,24 @@ class FacetTriangulator std::map, std::size_t> edge_map; std::vector skip(idPoints.size(), false); - bool has_ghost_edges = false; -/* for (std::size_t i = 0; i < idPoints.size(); i++) { int prev = (i - 1 + idPoints.size()) % idPoints.size(); - if (idPoints[i].point < idPoints[prev].point) { - auto it = edge_map.emplace(std::make_pair(idPoints[i].point, idPoints[prev].point), i); + if (idPoints[i].first < idPoints[prev].first) { + auto it = edge_map.emplace(std::make_pair(idPoints[i].first, idPoints[prev].first), i); if (!it.second) { skip[i] = true; skip[it.first->second] = true; - has_ghost_edges = true; } } else { - auto it = edge_map.emplace(std::make_pair(idPoints[prev].point, idPoints[i].point), i); + auto it = edge_map.emplace(std::make_pair(idPoints[prev].first, idPoints[i].first), i); if (!it.second) { skip[i] = true; skip[it.first->second] = true; - has_ghost_edges = true; } } - }*/ + } Vertex_handle previous, first, last_inserted; std::size_t previd, firstid, lastid; @@ -155,20 +150,20 @@ class FacetTriangulator for(std::size_t i = 0;i& idPoint = idPoints[i]; + x += idPoint.first.x(); + y += idPoint.first.y(); + z += idPoint.first.z(); Vertex_handle vh; // Always insert the first point, then only insert if the distance with the previous is reasonable. - if(first == Vertex_handle() || idPoint.point != previous->point()) + if(first == Vertex_handle() || idPoint.first != previous->point()) { - vh = cdt->insert(idPoint.point); - v2v[vh] = idPoint.id; + vh = cdt->insert(idPoint.first); + v2v[vh] = idPoint.second; if (first == Vertex_handle()) { first = vh; - firstid = idPoint.id; + firstid = idPoint.second; } if(previous != nullptr && previous != vh) @@ -179,7 +174,7 @@ class FacetTriangulator lastid = previd; } previous = vh; - previd = idPoint.id; + previd = idPoint.second; } } @@ -189,76 +184,66 @@ class FacetTriangulator if(previous != first && !skip[0]) cdt->insert_constraint(previous, first); -/* - std::vector pts; - std::ofstream vout("test.polylines.txt"); - for (auto& e : cdt->constrained_edges()) { - // edge is a pair of Face_handle and index - auto v1 = e.first->vertex((e.second + 1) % 3); - auto v2 = e.first->vertex((e.second + 2) % 3); - pts.push_back(v1->point()); - pts.push_back(v2->point()); - vout << "2 " << v1->point() << " " << v2->point() << std::endl; - } - vout.close();*/ - // sets mark is_external for(Face_handle f2 : cdt->all_face_handles()) f2->info().is_external = false; - std::unordered_map in_domain_map; - boost::associative_property_map< std::unordered_map > in_domain(in_domain_map); + std::unordered_map in_domain_map; + boost::associative_property_map< std::unordered_map > in_domain(in_domain_map); CGAL::mark_domain_in_triangulation(*cdt, in_domain); - // check if the facet is external or internal -/* - std::queue face_queue; - face_queue.push(cdt->infinite_vertex()->face()); - while(! face_queue.empty()) - { - typename CDT::Face_handle fh = face_queue.front(); - face_queue.pop(); - if(fh->info().is_external) - continue; - - fh->info().is_external = true; - for(int i = 0; i <3; ++i) - { - if(!cdt->is_constrained(std::make_pair(fh, i))) - face_queue.push(fh->neighbor(i)); - } - }*/ - - for (const Face_handle& fh : cdt->all_face_handles()) { + for (const Face_handle& fh : cdt->all_face_handles()) fh->info().is_external = !get(in_domain, fh); - } return true; } - bool triangulate_with_points(std::vector& idPoints, + bool triangulate_with_points(std::vector >& idPoints, const std::vector& more_points, const Vector& normal) { P_traits cdt_traits(normal); cdt = new CDT(cdt_traits); + std::map, std::size_t> edge_map; + std::vector skip(idPoints.size(), false); + + for (std::size_t i = 0; i < idPoints.size(); i++) { + int prev = (i - 1 + idPoints.size()) % idPoints.size(); + if (idPoints[i].first < idPoints[prev].first) { + auto it = edge_map.emplace(std::make_pair(idPoints[i].first, idPoints[prev].first), i); + if (!it.second) { + skip[i] = true; + skip[it.first->second] = true; + } + } + else { + auto it = edge_map.emplace(std::make_pair(idPoints[prev].first, idPoints[i].first), i); + if (!it.second) { + skip[i] = true; + skip[it.first->second] = true; + } + } + } + // Iterate the points of the facet and decide if they must be inserted in the CDT Vertex_handle previous, first, last_inserted; - for(const PointAndId& idPoint : idPoints) + for (std::size_t i = 0; i < idPoints.size(); i++) { + const std::pair& idPoint = idPoints[i]; Vertex_handle vh; // Always insert the first point, then only insert if the distance with the previous is reasonable. - if(first == Vertex_handle() || idPoint.point != previous->point()) + if(first == Vertex_handle() || idPoint.first != previous->point()) { - vh = cdt->insert(idPoint.point); - v2v[vh] = idPoint.id; + vh = cdt->insert(idPoint.first); + v2v[vh] = idPoint.second; if(first == Vertex_handle()) first = vh; if(previous != nullptr && previous != vh) { - cdt->insert_constraint(previous, vh); + if (!skip[i]) + cdt->insert_constraint(previous, vh); last_inserted = previous; } previous = vh; @@ -268,7 +253,9 @@ class FacetTriangulator if(last_inserted == Vertex_handle()) return false; + if (previous != first && !skip[0]) cdt->insert_constraint(previous, first); + for(const Point& point : more_points) cdt->insert(point); @@ -276,22 +263,12 @@ class FacetTriangulator for(Face_handle f2 : cdt->all_face_handles()) f2->info().is_external = false; - // check if the facet is external or internal - std::queue face_queue; - face_queue.push(cdt->infinite_vertex()->face()); - while(!face_queue.empty()) - { - typename CDT::Face_handle fh = face_queue.front(); - face_queue.pop(); - if(fh->info().is_external) - continue; - fh->info().is_external = true; - for(int i = 0; i <3; ++i) - { - if(!cdt->is_constrained(std::make_pair(fh, i))) - face_queue.push(fh->neighbor(i)); - } - } + std::unordered_map in_domain_map; + boost::associative_property_map< std::unordered_map > in_domain(in_domain_map); + CGAL::mark_domain_in_triangulation(*cdt, in_domain); + + for (const Face_handle& fh : cdt->all_face_handles()) + fh->info().is_external = !get(in_domain, fh); return true; } From afc5382c8c80f4eb7246ab1a99220d2b30f6ac52 Mon Sep 17 00:00:00 2001 From: Sven Oesau Date: Fri, 1 Dec 2023 08:31:50 +0100 Subject: [PATCH 3/7] removed left-overs from debugging bugfixes --- Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp | 2 +- Polyhedron/demo/Polyhedron/triangulate_primitive.h | 4 ++-- Stream_support/include/CGAL/IO/PLY/PLY_reader.h | 6 ------ 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp index e7d371e08918..fe4120c59191 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/IO/PLY_io_plugin.cpp @@ -132,7 +132,7 @@ load(QFileInfo fileinfo, bool& ok, bool add_to_scene) { std::vector fcolors; std::vector vcolors; - if (!(CGAL::IO::read_PLY (in, points, polygons, fcolors, vcolors, true))) + if (!(CGAL::IO::read_PLY (in, points, polygons, fcolors, vcolors))) { QApplication::restoreOverrideCursor(); ok = false; diff --git a/Polyhedron/demo/Polyhedron/triangulate_primitive.h b/Polyhedron/demo/Polyhedron/triangulate_primitive.h index a294581e15d8..4fd4afa6a00a 100644 --- a/Polyhedron/demo/Polyhedron/triangulate_primitive.h +++ b/Polyhedron/demo/Polyhedron/triangulate_primitive.h @@ -121,7 +121,7 @@ class FacetTriangulator P_traits cdt_traits(normal); cdt = new CDT(cdt_traits); - std::map, std::size_t> edge_map; + std::map, std::size_t> edge_map; std::vector skip(idPoints.size(), false); for (std::size_t i = 0; i < idPoints.size(); i++) { @@ -205,7 +205,7 @@ class FacetTriangulator P_traits cdt_traits(normal); cdt = new CDT(cdt_traits); - std::map, std::size_t> edge_map; + std::map, std::size_t> edge_map; std::vector skip(idPoints.size(), false); for (std::size_t i = 0; i < idPoints.size(); i++) { diff --git a/Stream_support/include/CGAL/IO/PLY/PLY_reader.h b/Stream_support/include/CGAL/IO/PLY/PLY_reader.h index c1a0ab4e580a..ee8b18ef59c0 100644 --- a/Stream_support/include/CGAL/IO/PLY/PLY_reader.h +++ b/Stream_support/include/CGAL/IO/PLY/PLY_reader.h @@ -726,9 +726,6 @@ bool read_PLY_faces(std::istream& in, for(std::size_t j = 0; j < element.number_of_items(); ++ j) { - if (j == 228) - std::cout << std::endl; - for(std::size_t k = 0; k < element.number_of_properties(); ++ k) { PLY_read_number* property = element.property(k); @@ -761,9 +758,6 @@ bool read_PLY_faces(std::istream& in, PLY_property >(vertex_indices_tag))); } - if (get<0>(new_face).size() == 0) - std::cout << "empty face encountered" << std::endl; - polygons.emplace_back(); ::CGAL::internal::resize(polygons.back(), get<0>(new_face).size()); for(std::size_t i = 0; i < get<0>(new_face).size(); ++ i) From c6eed472fd610c3ec1d2f0c315d02b8caec09da4 Mon Sep 17 00:00:00 2001 From: Sebastien Loriot Date: Thu, 4 Jan 2024 17:19:47 +0100 Subject: [PATCH 4/7] fix warning --- Polyhedron/demo/Polyhedron/triangulate_primitive.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/triangulate_primitive.h b/Polyhedron/demo/Polyhedron/triangulate_primitive.h index 4fd4afa6a00a..5f84f6e0a89e 100644 --- a/Polyhedron/demo/Polyhedron/triangulate_primitive.h +++ b/Polyhedron/demo/Polyhedron/triangulate_primitive.h @@ -125,7 +125,7 @@ class FacetTriangulator std::vector skip(idPoints.size(), false); for (std::size_t i = 0; i < idPoints.size(); i++) { - int prev = (i - 1 + idPoints.size()) % idPoints.size(); + std::size_t prev = (i - 1 + idPoints.size()) % idPoints.size(); if (idPoints[i].first < idPoints[prev].first) { auto it = edge_map.emplace(std::make_pair(idPoints[i].first, idPoints[prev].first), i); if (!it.second) { From 4a2d0704fc7aefcd44f85f8321053085967c0312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 4 Jan 2024 17:27:10 +0100 Subject: [PATCH 5/7] fix warnings --- Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp | 2 +- Polyhedron/demo/Polyhedron/triangulate_primitive.h | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp index 688cf8587459..23aeffc37958 100644 --- a/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_surface_mesh_item.cpp @@ -1371,7 +1371,7 @@ QList Scene_surface_mesh_item_priv::triangulate_primitive(fac //iterates on the internal faces to add the vertices to the positions //and the normals to the appropriate vectors - auto f = [&](auto &ffit, auto& v2v) { + auto f = [&](auto &ffit, auto&) { if (ffit.info().is_external) return; diff --git a/Polyhedron/demo/Polyhedron/triangulate_primitive.h b/Polyhedron/demo/Polyhedron/triangulate_primitive.h index 5f84f6e0a89e..4b0d0f137701 100644 --- a/Polyhedron/demo/Polyhedron/triangulate_primitive.h +++ b/Polyhedron/demo/Polyhedron/triangulate_primitive.h @@ -143,7 +143,6 @@ class FacetTriangulator } Vertex_handle previous, first, last_inserted; - std::size_t previd, firstid, lastid; // Iterate the points of the facet and decide if they must be inserted in the CDT typename Kernel::FT x(0), y(0), z(0); @@ -163,7 +162,6 @@ class FacetTriangulator v2v[vh] = idPoint.second; if (first == Vertex_handle()) { first = vh; - firstid = idPoint.second; } if(previous != nullptr && previous != vh) @@ -171,10 +169,8 @@ class FacetTriangulator if (!skip[i]) cdt->insert_constraint(previous, vh); last_inserted = previous; - lastid = previd; } previous = vh; - previd = idPoint.second; } } From 182b2c779214beffd16391ceaff5573f7cd0e49a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 8 Jan 2024 16:53:52 +0100 Subject: [PATCH 6/7] fix warning --- Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp index 70cda242d019..97b1d8306daa 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polyhedron_selection_item.cpp @@ -284,7 +284,7 @@ Scene_polyhedron_selection_item_priv::triangulate_facet(fg_face_descriptor fit,c //iterates on the internal faces to add the vertices to the positions //and the normals to the appropriate vectors - auto f = [&](auto& ffit, auto& v2v) { + auto f = [&](auto& ffit, auto& /* v2v */) { if (ffit.info().is_external) return; From de17922ca4ee3ad011eb910b9034e74cf7c7c3f7 Mon Sep 17 00:00:00 2001 From: Sven Oesau Date: Tue, 9 Jan 2024 10:26:19 +0100 Subject: [PATCH 7/7] removed warnings --- Polyhedron/demo/Polyhedron/Plugins/PMP/Distance_plugin.cpp | 2 +- Polyhedron/demo/Polyhedron/triangulate_primitive.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Plugins/PMP/Distance_plugin.cpp b/Polyhedron/demo/Polyhedron/Plugins/PMP/Distance_plugin.cpp index 72e1475f82ff..3034e7f58a3e 100644 --- a/Polyhedron/demo/Polyhedron/Plugins/PMP/Distance_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Plugins/PMP/Distance_plugin.cpp @@ -204,7 +204,7 @@ class Scene_distance_polyhedron_item: public Scene_item_rendering_helper sampled_points.push_back(r); //triangle facets with sample points for color display - auto func = [&](auto& ffit, auto& v2v) { + auto func = [&](auto& ffit, auto&) { if (ffit.info().is_external) return; diff --git a/Polyhedron/demo/Polyhedron/triangulate_primitive.h b/Polyhedron/demo/Polyhedron/triangulate_primitive.h index 4b0d0f137701..21c6223a9ea8 100644 --- a/Polyhedron/demo/Polyhedron/triangulate_primitive.h +++ b/Polyhedron/demo/Polyhedron/triangulate_primitive.h @@ -205,7 +205,7 @@ class FacetTriangulator std::vector skip(idPoints.size(), false); for (std::size_t i = 0; i < idPoints.size(); i++) { - int prev = (i - 1 + idPoints.size()) % idPoints.size(); + std::size_t prev = (i - 1 + idPoints.size()) % idPoints.size(); if (idPoints[i].first < idPoints[prev].first) { auto it = edge_map.emplace(std::make_pair(idPoints[i].first, idPoints[prev].first), i); if (!it.second) {