2121#include < CGAL/AABB_tree.h>
2222#include < CGAL/AABB_traits_3.h>
2323#include < CGAL/AABB_primitive.h>
24+ #include < CGAL/centroid.h>
2425
2526#include < map>
2627#include < vector>
@@ -121,6 +122,16 @@ get(const Edge_to_point_property_map<C3t3>&, const typename C3t3::Edge& e)
121122} // namespace internal
122123
123124
125+
126+ template <typename Point3,
127+ typename Vector3>
128+ struct Projection_data {
129+ Point3 origin = Point3();
130+ Vector3 vector = Vector3();
131+ bool activated = true ;
132+ double weight = 1 .;
133+ };
134+
124135/* !
125136* \ingroup pkgMeshSmoothing3Projection
126137*
@@ -143,36 +154,39 @@ class C3t3_mesh_projector {
143154public:
144155 using Point_3 = typename K::Point_3;
145156 using Vector_3 = typename K::Vector_3;
157+ using Projection = Projection_data<Point_3, Vector_3>;
146158
147159 using Surface_patch_index = typename C3t3::Surface_patch_index;
148160 using Facet = typename C3t3::Facet;
149161 using Patch_face = std::pair<Surface_patch_index, Facet>;
150162
151- std::pair<Point_3, Vector_3> patch_projection_plane (Patch_face patch_face, Point_3 face_center, double /* face_radius*/ ) const {
163+ Projection patch_projection_plane (Patch_face patch_face, std::vector<Point_3> const &face_points) const {
164+ Projection projection;
165+ Point_3 face_center = CGAL::centroid (face_points.begin (), face_points.end ());
152166 auto res = _facet_trees.at (patch_face.first ).closest_point_and_primitive (face_center);
153- Point_3 closest_point = res.first ;
167+ projection. origin = res.first ;
154168 const auto triangle = _c3t3->triangulation ().triangle (res.second );
155- Vector_3 normal = CGAL::unit_normal (triangle.vertex (0 ), triangle.vertex (1 ), triangle.vertex (2 ));
156- return {closest_point, normal} ;
169+ projection. vector = CGAL::unit_normal (triangle.vertex (0 ), triangle.vertex (1 ), triangle.vertex (2 ));
170+ return projection ;
157171 }
158- bool project_patch_face (Patch_face) const { return true ; }
159172
160173 using Curve_index = typename C3t3::Curve_index;
161174 using Edge = typename C3t3::Edge;
162175 using Curve_edge = std::pair<Curve_index, Edge>;
163176
164- std::pair<Point_3, Vector_3> curve_projection_tangent (Curve_edge curve_edge, Point_3 edge_center, double /* segment_size*/ ) const {
177+ Projection curve_projection_tangent (Curve_edge curve_edge, std::array<Point_3,2 > const &edge_points) const {
178+ Projection projection;
179+ Point_3 edge_center = CGAL::midpoint (edge_points[0 ], edge_points[1 ]);
165180 auto res = _edge_trees.at (curve_edge.first ).closest_point_and_primitive (edge_center);
166- Point_3 closest_point = res.first ;
181+ projection. origin = res.first ;
167182 const auto segment = _c3t3->triangulation ().segment (res.second );
168- Vector_3 direction = (segment.target () - segment.source ());
169- if (direction .squared_length () > 1e-8 ) {
170- direction /= CGAL::sqrt (direction .squared_length ());
183+ projection. vector = (segment.target () - segment.source ());
184+ if (projection. vector .squared_length () > 1e-8 ) {
185+ projection. vector /= CGAL::sqrt (projection. vector .squared_length ());
171186 }
172- return {closest_point, direction} ;
187+ return projection ;
173188 }
174189
175- bool project_curve_edge (Curve_edge) const { return true ; }
176190
177191public:
178192
@@ -264,26 +278,82 @@ class C3t3_no_projection {
264278public:
265279 using Point_3 = typename K::Point_3;
266280 using Vector_3 = typename K::Vector_3;
281+ using Projection = Projection_data<Point_3, Vector_3>;
267282
268283 using Surface_patch_index = typename C3t3::Surface_patch_index;
269284 using Facet = typename C3t3::Facet;
270285 using Patch_face = std::pair<Surface_patch_index, Facet>;
271286
272- std::pair<Point_3, Vector_3> patch_projection_plane (Patch_face, Point_3, double ) const {
273- return {Point_3 (), Vector_3 ()};
287+ Projection patch_projection_plane (Patch_face, std::vector<Point_3> const &) const {
288+ Point_3 face_center = CGAL::centroid (face_points.begin (), face_points.end ());
289+ Vector_3 normal = CGAL::unit_normal (face_points[0 ], face_points[1 ], face_points[2 ]); // only works for triangles, but let's start with that
290+ Ray_3 ray_positive (face_center, normal);
291+ Ray_3 ray_negative (face_center, -normal);
292+ return Projection{Point_3 (), Vector_3 (), false };
274293 }
275- bool project_patch_face (Patch_face) const { return false ; }
276294
277295 using Curve_index = typename C3t3::Curve_index;
278296 using Edge = typename C3t3::Edge;
279297 using Curve_edge = std::pair<Curve_index, Edge>;
280298
281- std::pair<Point_3, Vector_3> curve_projection_tangent (Curve_edge, Point_3, double ) const {
282- return {Point_3 (), Vector_3 ()};
299+ Projection curve_projection_tangent (Curve_edge, std::array< Point_3,2 > const & ) const {
300+ return Projection {Point_3 (), Vector_3 (), false };
283301 }
284- bool project_curve_edge (Curve_edge) const { return false ; }
285302
286303};
304+
305+
306+ /*
307+ * \ingroup pkgMeshSmoothing3Projection
308+ *
309+ * \brief provides projection to a Mesh Domain
310+ *
311+ * @tparam C3t3 model of `MeshDomain_3`
312+ *
313+ * \cgalModels{C3t3Projector}
314+ *
315+ \sa `CGAL::boundary_aware_mesh_smoothing`
316+ *
317+ */
318+ template <typename C3t3, typename MeshDomain>
319+ class Mesh_domain_projection {
320+ using K = typename C3t3::Triangulation::Geom_traits;
321+ public:
322+ using Point_3 = typename K::Point_3;
323+ using Vector_3 = typename K::Vector_3;
324+ using Projection = Projection_data<Point_3, Vector_3>;
325+
326+ using Surface_patch_index = typename C3t3::Surface_patch_index;
327+ using Facet = typename C3t3::Facet;
328+ using Patch_face = std::pair<Surface_patch_index, Facet>;
329+
330+ Projection patch_projection_plane (Patch_face, std::vector<Point_3> const &) const {
331+ return Projection ();
332+ }
333+
334+ using Curve_index = typename C3t3::Curve_index;
335+ using Edge = typename C3t3::Edge;
336+ using Curve_edge = std::pair<Curve_index, Edge>;
337+
338+ Projection curve_projection_tangent (Curve_edge, std::array<Point_3,2 > const &) const {
339+ return Projection ();
340+ }
341+
342+ public:
343+
344+ /*
345+ Class constructor
346+
347+ \param mesh_domain contains the domain used for projection
348+
349+ */
350+ Mesh_domain_projection (MeshDomain const & mesh_domain)
351+ : _domain(mesh_domain)
352+ {}
353+
354+ MeshDomain const & _domain;
355+ };
356+
287357} // namespace Mesh_smoothing_3
288358
289359/* !
@@ -415,16 +485,16 @@ void boundary_aware_mesh_smoothing (
415485 using Vector_3 = typename C3t3::Triangulation::Geom_traits::Vector_3;
416486
417487 // converting Projector to Mesh_smoothing_3 queries
418- smoother.set_boundary_query ([&](const Point_3& pt , std::pair<typename C3t3::Surface_patch_index, typename C3t3::Facet> patch_face, double radius ) {
419- if (!projector. project_patch_face (patch_face)) return std::make_tuple ( Point_3 ( 0 ., 0 ., 0 .), Vector_3{ 1 ., 0 ., 0 .}, 0 . );
420- auto [point, normal] = projector. patch_projection_plane (patch_face, pt, radius) ;
421- return std::make_tuple (point, normal, 1.0 );
488+ smoother.set_boundary_query ([&](std::vector< Point_3> const & pts , std::pair<typename C3t3::Surface_patch_index, typename C3t3::Facet> patch_face) {
489+ Mesh_smoothing_3::Projection_data< Point_3, Vector_3> proj = projector. patch_projection_plane (patch_face, pts );
490+ if (!proj. activated ) proj. weight = 0 . ;
491+ return std::make_tuple (proj. origin , proj. vector , proj. weight );
422492 });
423493
424- smoother.set_curves_query ([&](const Point_3& pt , std::pair<typename C3t3::Curve_index, typename C3t3::Edge> curve_edge, double segment_size ) {
425- if (!projector. project_curve_edge (curve_edge)) return std::make_tuple ( Point_3 ( 0 ., 0 ., 0 .), Vector_3{ 1 ., 0 ., 0 .}, 0 . );
426- auto [point, tangent] = projector. curve_projection_tangent (curve_edge, pt, segment_size) ;
427- return std::make_tuple (point, tangent, 1.0 );
494+ smoother.set_curves_query ([&](std::array< Point_3, 2 > const & pts , std::pair<typename C3t3::Curve_index, typename C3t3::Edge> curve_edge) {
495+ Mesh_smoothing_3::Projection_data< Point_3, Vector_3> proj = projector. curve_projection_tangent (curve_edge, pts );
496+ if (!proj. activated ) proj. weight = 0 . ;
497+ return std::make_tuple (proj. origin , proj. vector , proj. weight );
428498 });
429499
430500 smoother.set_verbose (verbose);
0 commit comments