- Updated `Mesh_domain_with_polyline_features_3` to support API versioning, allowing for different output types based on the version.
- Adjusted the implementation of `construct_point_on_curve` and related methods in `Protect_edges_sizing_field`.
All those methods are now in a dedicated class helper `Protect_edges_sizing_field_versioned_API`.
- Renamed `Point_and_location` to `Point_and_position` in Polyline.h for clarity.
- Wrapped assertions in `#if CGAL_MESH_3_PROTECTION_DEBUG` to enable debug checks conditionally.
That is still a WIP: I would like to move the caching map `vertex_to_polyline_iterator_` from the domain class to
the class `Protect_edges_sizing_field`. That would avoid those member functions in the domain:
- `Domain::set_polyline_iterator`
- `Domain::remove_polyline_iterator`
- `Domain::clear_point_to_polyline_iterator_cache`
## Summary of Changes
This PR fixes the error reported in issue #781. The main two changes
are:
- in `Refine_edges.h`: allow the refinement point of a constrained edge
to be an existing close encroaching vertex,
- in `Refine_faces.h`: skip tiny bad faces when their bbox are smaller
than a few ulp.
## Release Management
* Affected package(s): Triangulation_2, Mesh_2
* Issue(s) solved (if any): fix#781
* Feature/Small Feature (if any):
* Link to compiled documentation (obligatory for small feature) [*wrong
link name to be changed*](httpssss://wrong_URL_to_be_changed/Manual/Pkg)
* License and copyright ownership: maintenance by GeometryFactory, now
copyright change
The bug was reproduced by
```shell
/path/to/build/test/Mesh_2/test_mesh_obj Mesh_2/test/Mesh_2/triwild-10070-min1.obj
```
The log of the error, with all the debug options of Mesh_2 was:
```plain
Before conforming Gabriel: 4 vertices.
Smallest squared distance between constraint endpoints: 0.010522898628224919
edge #1= 453.57378188125 445.0501073328125 -- #3= 454.05836694375 445.48749872343745 is encroached by #2= 453.77453855000005 445.23131233749996
add_constrained_edge_to_be_conformed(#1= 453.57378188125 445.0501073328125, #3= 454.05836694375 445.48749872343745)
edge #2= 453.77453855000005 445.23131233749996 -- #0= 453.49763280000002 444.98137439999999 is encroached by #1= 453.57378188125 445.0501073328125
add_constrained_edge_to_be_conformed(#2= 453.77453855000005 445.23131233749996, #0= 453.49763280000002 444.98137439999999)
split_cluster_point(454.05836694375 445.48749872343745 , 453.57378188125 445.0501073328125)
reduced: 0
result: 453.77453855000005 445.23131233750001
edge #1= 453.57378188125 445.0501073328125 -- #3= 454.05836694375 445.48749872343745 is encroached by #2= 453.77453855000005 445.23131233749996
Refine_edges_with_clusters::refinement_point_impl(Edge: (#1= 453.57378188125 445.0501073328125, #3= 454.05836694375 445.48749872343745) = 453.77453855000005 445.23131233750001
(453.77453855000005 445.23131233750001) accepted
on edge, insert(453.77453855000005 445.23131233750001): 3 boundary edges in the zone
inserted new vertex #4= 453.77453855000005 445.23131233750001
update_clusters
va_has_a_cluster=0
vb_has_a_cluster=1
clusters.size()=2
E edge #3= 454.05836694375 445.48749872343745 -- #2= 453.77453855000005 445.23131233749996 is encroached by #4= 453.77453855000005 445.23131233750001
add_constrained_edge_to_be_conformed(#3= 454.05836694375 445.48749872343745, #2= 453.77453855000005 445.23131233749996)
edge #1= 453.57378188125 445.0501073328125 -- #4= 453.77453855000005 445.23131233750001 is encroached by #2= 453.77453855000005 445.23131233749996
add_constrained_edge_to_be_conformed(#1= 453.57378188125 445.0501073328125, #4= 453.77453855000005 445.23131233750001)
Cluster at #3= 454.05836694375 445.48749872343745 is updated.
vm: #4= 453.77453855000005 445.23131233750001
reduction: 1
min_sq_len: 0.1461900214383674
clusters.size() after update_cluster=2
split_cluster_point(453.49763280000002 444.98137439999999 , 453.77453855000005 445.23131233749996)
reduced: 0
result: 453.64993096249998 445.11884026562501
edge #2= 453.77453855000005 445.23131233749996 -- #0= 453.49763280000002 444.98137439999999 is encroached by #1= 453.57378188125 445.0501073328125
Refine_edges_with_clusters::refinement_point_impl(Edge: (#2= 453.77453855000005 445.23131233749996, #0= 453.49763280000002 444.98137439999999) = 453.64993096249998 445.11884026562501
(453.64993096249998 445.11884026562501) accepted
on edge, insert(453.64993096249998 445.11884026562501): 0 boundary edges in the zone
terminate called after throwing an instance of 'CGAL::Precondition_exception'
what(): CGAL ERROR: precondition violation!
Expr: i >= 0 && i < 3
```
The following edge `(#1, #3)` is encroached by the vertex `#2`:
```plain
edge #1= 453.57378188125 445.0501073328125 -- #3= 454.05836694375 445.48749872343745 is encroached by #2= 453.77453855000005 445.23131233749996
```
The inserted vertex `#4= 453.77453855000005 445.23131233750001` is the projection of the vertex `#2= 453.77453855000005 445.23131233749996` (rules to refine a segment part of a cluster.
The distance between `#2` and its projection `#4` is:
- `0` on the x-axis,
- `ulp(v2.y()))` on the y-axis.
... and then, Mesh_2 cannot do anything with that.
The fix is to implement a snapping strategy: if the encroaching vertex is close enough, then chose it be the refinement point of the encroached segment. "Close enough" means:
- create tiny `Bbox_2` centered on the encroaching vertex, with snaps equal to 8 ulp on both axis,
- if that tiny bbox intersects the encroached segment, then the refinement is the encroaching vertex.
## Summary of Changes
New package for 3D barycentric coordinates in a convex polyhedron
## Release Management
* Affected package(s): New package
* Feature/Small Feature (if any):
[here](https://cgal.geometryfactory.com/CGAL/Members/wiki/Features/Barycentric_coordinates_3)
* Link to compiled documentation (obligatory for small feature) [*wrong
link name to be changed*](httpssss://wrong_URL_to_be_changed/Manual/Pkg)
* License and copyright ownership: GF
## TODO
- [x] check branch size (@sloriot)
- [x] check usage of `get_tolerance()` from
`Barycentric_coordinates_3/include/CGAL/Barycentric_coordinates_3/internal/utils_3.h`
fixed concepts (review)
changed Has_on_bounded_side_2/3 to require Segment_2, Iso_rectangle_2 and Iso_cuboid_3 to be fully inside the Circle_2/Sphere_3
The previous implementation defined Compare_xy_2 as
simply Compare_xyz_3. This does define an order
over the projected points, but it has a strong downside:
it ignores the direction of the normal, so its order
can be the opposite of the lexicographical order
would give. This new order is in conflict with
the existing Compare_x_2 and Compare_y_2, which
take the normal's direction into account.
(Also with the Less_x_2, Less_y_2, and Less_xy_2
family, which also exist for the projection traits).
There is also a stronger need because now we really need to map
types whereas before it could rely on result_type's to avoid
some tricky cases like CGAL::Sphere_point