Skip to content

PMP: Accelerate isotropic remeshing #5507

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Apr 6, 2021
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
19e5e4a
Use flaat_set and put it outside the loop
afabri Mar 2, 2021
10f454d
reserve(8) for incident faces to a vertex
afabri Mar 2, 2021
5e2a580
map -> unordered_map
afabri Mar 2, 2021
95ea922
Important gain for Euler::add_face()
afabri Mar 2, 2021
a945c4f
small_vector has reserve()
afabri Mar 2, 2021
22789f6
Replace geometric by combinatorial test
afabri Mar 2, 2021
2ac977b
Early exit in do_intersect of Sphere/Bbox_3
afabri Mar 3, 2021
82e5b3a
Do not collect in a vector per patch, but do the tests directly (@ja…
afabri Mar 3, 2021
dad0287
Remove trailing whitespace
afabri Mar 3, 2021
e7f18df
No need for calling abs for a squared distance
afabri Mar 3, 2021
431c5b8
Comment something experimental that sneaked in
afabri Mar 3, 2021
7785a9c
Use certainly()
afabri Mar 3, 2021
4fab843
Add static filter for Equal_3::operator()(Vector_3, Null_vector)
afabri Mar 3, 2021
2e3bfa8
Reduce calls to target @sloriot please double check the correctness
afabri Mar 4, 2021
45265a7
Replace vector with optional by two vectors. No idea what is better yet
afabri Mar 4, 2021
b1c2dd8
WIP: early exit in the static filter
afabri Mar 7, 2021
643810f
WIP for not hard coding conservative. Todo: Use of Has_filtered
afabri Mar 9, 2021
9274503
remove debug code
afabri Mar 9, 2021
cea8cca
WIP: less computations of degree
afabri Mar 9, 2021
b523916
Check that the kernel has static filters
afabri Mar 10, 2021
ac708f6
use nested class for dispatch
sloriot Mar 10, 2021
3614dee
don't reinvent the wheel
sloriot Mar 10, 2021
2b5cb2d
copy tags
sloriot Mar 10, 2021
e6c2e5c
Simplify. todo: tighter bounds per case or factorization with a lambda
afabri Mar 10, 2021
da17681
Avoid computing degree several times
afabri Mar 10, 2021
109a893
remove #ifdef that should be defined
janetournois Mar 19, 2021
29a40dc
Remove the timer and the output of the result
afabri Mar 19, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion BGL/include/CGAL/boost/graph/Euler_operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -737,7 +737,7 @@ add_face(const VertexRange& vr, Graph& g)
patch_start, patch_end;
// cache for set_next and vertex' set_halfedge
typedef std::pair<halfedge_descriptor, halfedge_descriptor> NextCacheEntry;
typedef std::vector<NextCacheEntry> NextCache;
typedef boost::container::small_vector<NextCacheEntry,9> NextCache;
NextCache next_cache;
next_cache.reserve(3 * n);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,39 +35,59 @@ namespace internal {
typedef typename K::Point_3 Point;
FT d = FT(0);
FT distance = FT(0);
FT sr = sphere.squared_radius();

Point center = sphere.center();

if(center.x() < (FT)bbox.xmin())
{
d = (FT)bbox.xmin() - center.x();
distance += d * d;
d = square(d);
if(d > sr){
return false;
}
distance = d;
}
else if(center.x() > (FT)bbox.xmax())
{
d = center.x() - (FT)bbox.xmax();
distance += d * d;
d = square(d);
if(d > sr){
return false;
}
distance = d;
}

if(center.y() < (FT)bbox.ymin())
{
d = (FT)bbox.ymin() - center.y();
distance += d * d;
d = square(d);
if(d > sr){
return false;
}
distance += d ;
}
else if(center.y() > (FT)bbox.ymax())
{
d = center.y() - (FT)bbox.ymax();
distance += d * d;
d = square(d);
if(d > sr){
return false;
}
distance += d;
}

if(center.z() < (FT)bbox.zmin())
{
d = (FT)bbox.zmin() - center.z();
distance += d * d;
d = square(d);
distance += d;
}
else if(center.z() > (FT)bbox.zmax())
{
d = center.z() - (FT)bbox.zmax();
distance += d * d;
d = square(d);
distance += d;
}

// For unknown reason this causes a syntax error on VC2005
Expand All @@ -87,7 +107,7 @@ namespace internal {
// }
//}

return distance <= sphere.squared_radius();
return distance <= sr;
}

template <class K>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <limits>
#include <utility>
#include <vector>
#include <unordered_map>

#ifdef CGAL_PMP_COMPUTE_NORMAL_DEBUG_PP
# ifndef CGAL_PMP_COMPUTE_NORMAL_DEBUG
Expand Down Expand Up @@ -506,6 +507,7 @@ compute_vertex_normal_most_visible_min_circle(typename boost::graph_traits<Polyg
typedef typename GT::Vector_3 Vector_3;

std::vector<face_descriptor> incident_faces;
incident_faces.reserve(8);
for(face_descriptor f : CGAL::faces_around_target(halfedge(v, pmesh), pmesh))
{
if(f == boost::graph_traits<PolygonMesh>::null_face())
Expand Down Expand Up @@ -669,7 +671,7 @@ compute_vertex_normal(typename boost::graph_traits<PolygonMesh>::vertex_descript
VPMap vpmap = choose_parameter(get_parameter(np, internal_np::vertex_point),
get_const_property_map(vertex_point, pmesh));

typedef std::map<face_descriptor, Vector_3> Face_vector_map;
typedef std::unordered_map<face_descriptor, Vector_3> Face_vector_map;
typedef boost::associative_property_map<Face_vector_map> Default_map;

typedef typename internal_np::Lookup_named_param_def<internal_np::face_normal_t,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include <boost/unordered_set.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/container/flat_set.hpp>
#include <boost/optional.hpp>

#include <map>
#include <list>
Expand Down Expand Up @@ -1393,6 +1394,7 @@ namespace internal {

bool collapse_would_invert_face(const halfedge_descriptor& h) const
{
vertex_descriptor tv = target(h, mesh_);
typename boost::property_traits<VertexPointMap>::reference
s = get(vpmap_, source(h, mesh_)); //s for source
typename boost::property_traits<VertexPointMap>::reference
Expand All @@ -1409,16 +1411,21 @@ namespace internal {
if (face(hd, mesh_) == boost::graph_traits<PM>::null_face())
continue;

vertex_descriptor tnhd = target(next(hd, mesh_), mesh_);
vertex_descriptor tnnhd = target(next(next(hd, mesh_), mesh_), mesh_);
typename boost::property_traits<VertexPointMap>::reference
p = get(vpmap_, target(next(hd, mesh_), mesh_));
p = get(vpmap_, tnhd);
typename boost::property_traits<VertexPointMap>::reference
q = get(vpmap_, target(next(next(hd, mesh_), mesh_), mesh_));
q = get(vpmap_, tnnhd);

#ifdef CGAL_PMP_REMESHING_DEBUG
CGAL_assertion((Triangle_3(t, p, q).is_degenerate())
== GeomTraits().collinear_3_object()(t, p, q));
#endif

if((tv == tnnhd) || (tv == tnhd))
continue;

if ( GeomTraits().collinear_3_object()(s, p, q)
|| GeomTraits().collinear_3_object()(t, p, q))
continue;
Expand Down Expand Up @@ -1879,8 +1886,8 @@ namespace internal {
bool check_normals(const HalfedgeRange& hedges) const
{
std::size_t nb_patches = patch_id_to_index_map.size();
std::vector<boost::optional<Vector_3> > normal_per_patch(nb_patches,boost::none);

std::vector< std::vector<Vector_3> > normals_per_patch(nb_patches);
for(halfedge_descriptor hd : hedges)
{
Halfedge_status s = status(hd);
Expand All @@ -1892,18 +1899,15 @@ namespace internal {
if (n == CGAL::NULL_VECTOR) //for degenerate faces
continue;
Patch_id pid = get_patch_id(face(hd, mesh_));
normals_per_patch[patch_id_to_index_map.at(pid)].push_back(n);
}

//on each surface patch,
//check all normals have same orientation
for (std::size_t i=0; i < nb_patches; ++i)
{
const std::vector<Vector_3>& normals = normals_per_patch[i];
if (normals.empty()) continue;

if (!check_orientation(normals))
return false;
std::size_t index = patch_id_to_index_map.at(pid);
if(normal_per_patch[index]){
const Vector_3& vec = *normal_per_patch[index];
double dot = to_double(n * vec);
if (dot <= 0.){
return false;
}
}
normal_per_patch[index] = boost::make_optional(n);
}
return true;
}
Expand All @@ -1916,20 +1920,7 @@ namespace internal {
Vector_3 no = compute_normal(face(opposite(h, mesh_), mesh_));
return n * no > 0.;
}

bool check_orientation(const std::vector<Vector_3>& normals) const
{
if (normals.size() < 2)
return true;
for (std::size_t i = 1; i < normals.size(); ++i)/*start at 1 on purpose*/
{
double dot = to_double(normals[i - 1] * normals[i]);
if (dot <= 0.)
return false;
}
return true;
}


public:
const Triangle_list& input_triangles() const {
return input_triangles_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <boost/range/size.hpp>
#include <boost/range/value_type.hpp>
#include <boost/range/reference.hpp>
#include <boost/container/flat_set.hpp>

#include <array>
#include <set>
Expand Down Expand Up @@ -177,14 +178,16 @@ bool is_polygon_soup_a_polygon_mesh(const PolygonRange& polygons)
//check there is no duplicated ordered edge, and
//check there is no polygon with twice the same vertex
std::set<std::pair<V_ID, V_ID> > edge_set;
boost::container::flat_set<V_ID> polygon_vertices;
V_ID max_id = 0;

for(const Polygon& polygon : polygons)
{
std::size_t nb_edges = boost::size(polygon);
if(nb_edges < 3)
return false;

std::set<V_ID> polygon_vertices;
polygon_vertices.clear();
V_ID prev = *std::prev(boost::end(polygon));
for(V_ID id : polygon)
{
Expand Down