diff --git a/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Bounding_box_filter.h b/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Bounding_box_filter.h new file mode 100644 index 000000000000..c8b534f0ee17 --- /dev/null +++ b/Surface_mesh_simplification/include/CGAL/Surface_mesh_simplification/Policies/Edge_collapse/Bounding_box_filter.h @@ -0,0 +1,77 @@ +// Copyright (c) 2024 GeometryFactory (France). All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// Author(s) : Andreas Fabri +// +#ifndef CGAL_SURFACE_MESH_SIMPLIFICATION_POLICIES_EDGE_COLLAPSE_BOUNDING_BOX_FILTER_H +#define CGAL_SURFACE_MESH_SIMPLIFICATION_POLICIES_EDGE_COLLAPSE_BOUNDING_BOX_FILTER_H + +#include +#include +#include + +#include + +namespace CGAL { +namespace Surface_mesh_simplification { + + +template +class Bounding_box_filter +{ +public: + Bounding_box_filter(const BaseFilter& base_filter = BaseFilter()) + : m_base_filter(base_filter) + {} + + + template + std::optional + operator()(const Profile& profile, std::optional op) const + { + typedef typename Profile::VertexPointMap Vertex_point_map; + + typedef typename Profile::Geom_traits Geom_traits; + typedef typename Geom_traits::Vector_3 Vector; + + typedef typename boost::property_traits::value_type Point; + typedef typename boost::property_traits::reference Point_reference; + + const Geom_traits& gt = profile.geom_traits(); + const Vertex_point_map& vpm = profile.vertex_point_map(); + + op = m_base_filter(profile, op); + if(op) + { + const Point& placement = *op; + Bbox_3 bb; + for(auto vd : profile.link()){ + Point_reference p = get(vpm, vd); + bb += p.bbox(); + } + double wx = bb.xmax() - bb.xmin(); + double wy = bb.ymax() - bb.ymin(); + double wz = bb.zmax() - bb.zmin(); + bb = Bbox_3(bb.xmin()- wx/10.0, bb.ymin() - wy/10.0, bb.zmin()- wz/10.0, bb.xmax() + wx/10.0, bb.ymax() + wy/10.0, bb.zmax()+ wz/10.0); + if(!do_overlap(bb, placement.bbox())){ + return std::optional(); + } + } + return op; + } + + + +private: + const BaseFilter m_base_filter; +}; + +} // namespace Surface_mesh_simplification +} // namespace CGAL + +#endif // CGAL_SURFACE_MESH_SIMPLIFICATION_POLICIES_EDGE_COLLAPSE_BOUNDING_BOX_FILTER_H diff --git a/Surface_mesh_simplification/test/Surface_mesh_simplification/issue_8213.cpp b/Surface_mesh_simplification/test/Surface_mesh_simplification/issue_8213.cpp index ca4da904544e..b086fe22e735 100644 --- a/Surface_mesh_simplification/test/Surface_mesh_simplification/issue_8213.cpp +++ b/Surface_mesh_simplification/test/Surface_mesh_simplification/issue_8213.cpp @@ -15,6 +15,7 @@ void Surface_simplification_external_trace(const std::string& s) #include #include +#include #include #include #include @@ -52,12 +53,16 @@ int main(int argc, char** argv) std::cout << "Input mesh has " << num_vertices(sm) << " vertices" << std::endl; std::cout << "Input mesh has " << num_faces(sm) << " faces" << std::endl; - SMS::Face_count_stop_predicate stop(1); - SMS::edge_collapse(sm, stop, - CGAL::parameters::filter(SMS::Bounded_normal_change_filter<>()) - .get_cost(SMS::LindstromTurk_cost()) - .get_placement(SMS::LindstromTurk_placement())); + SMS::Face_count_stop_predicate stop(1); + SMS::edge_collapse( + surface_mesh, + stop, + CGAL::parameters:: + filter(SMS::Bounded_normal_change_filter>(SMS::Bounding_box_filter<>())) + .get_cost(SMS::LindstromTurk_cost()) + .get_placement(SMS::LindstromTurk_placement()) + ); CGAL::IO::write_OFF(std::cout, sm, CGAL::parameters::stream_precision(17)); for(auto v : vertices(sm))