Skip to content

Commit

Permalink
clean up patch and make filling lazy
Browse files Browse the repository at this point in the history
  • Loading branch information
sloriot committed Dec 18, 2024
1 parent 713fb65 commit ef5950d
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1091,6 +1091,10 @@ class Face_graph_output_builder
boost::dynamic_bitset<> coplanar_patches_of_tm2_for_union_and_intersection(nb_patches_tm2,false);
patch_status_not_set_tm1.set();
patch_status_not_set_tm2.set();
// extra containers used when entire connected components are identical (filled only if needed)
std::vector<std::size_t> coplanar_tm1_to_coplanar_tm2;
std::vector<vertex_descriptor> extreme_vertex_per_cc_1;
std::vector<vertex_descriptor> extreme_vertex_per_cc_2;

// first set coplanar status of patches using the coplanar faces collected during the
// extra intersection edges collected. This is important in the case of full connected components
Expand All @@ -1107,71 +1111,6 @@ class Face_graph_output_builder
coplanar_patches_of_tm2.set(tm2_patch_ids[ fid2 ]);
}


//we have the correspondance between cpln patches thanks to faces in tm1_coplanar_faces and tm2_coplanar_faces
CGAL_assertion(tm1_coplanar_faces.size()==tm2_coplanar_faces.size());
// TODO: move it to do it lazily
std::vector<std::size_t> coplanar_tm1_to_coplanar_tm2;
std::vector<bool> is_oo_tm1(nb_patches_tm1, false);
std::vector<bool> is_oo_tm2(nb_patches_tm2, false);
if (!tm1_coplanar_faces.empty())
{
coplanar_tm1_to_coplanar_tm2.resize(nb_patches_tm1, NID);
for (std::size_t i=0; i<tm1_coplanar_faces.size(); ++i)
{
std::size_t pid1 = tm1_patch_ids[get(fids1, tm1_coplanar_faces[i])];
std::size_t pid2 = tm2_patch_ids[get(fids2, tm2_coplanar_faces[i])];
coplanar_tm1_to_coplanar_tm2[pid1]=pid2;
}

std::vector<std::optional<vertex_descriptor>> max_pts_1(nb_patches_tm1);
for (face_descriptor fd : faces(tm1))
{
std::size_t patch_id = tm1_patch_ids[get(fids1, fd)];
if (!coplanar_patches_of_tm1.test(patch_id)) continue;
halfedge_descriptor hd=halfedge(fd, tm1);
for (halfedge_descriptor h : CGAL::halfedges_around_face(hd, tm1))
{
vertex_descriptor vd = target(h, tm1);
if (!max_pts_1[patch_id].has_value() || get(vpm1,max_pts_1[patch_id].value())<get(vpm1,vd))
max_pts_1[patch_id]=vd;
}
}

for (std::size_t pid=0;pid<nb_patches_tm1; ++pid)
{
if (coplanar_patches_of_tm1.test(pid)) // TODO restrict more!
{
is_oo_tm1[pid] = ::CGAL::Polygon_mesh_processing::internal::is_outward_oriented(max_pts_1[pid].value(), tm1, parameters::vertex_point_map(vpm1));
}
}


std::vector<std::optional<vertex_descriptor>> max_pts_2(nb_patches_tm2);
for (face_descriptor fd : faces(tm2))
{
std::size_t patch_id = tm2_patch_ids[get(fids2, fd)];
if (!coplanar_patches_of_tm2.test(patch_id)) continue;
halfedge_descriptor hd=halfedge(fd, tm2);
for (halfedge_descriptor h : CGAL::halfedges_around_face(hd, tm2))
{
vertex_descriptor vd = target(h, tm2);
if (!max_pts_2[patch_id].has_value() || get(vpm2,max_pts_2[patch_id].value())<get(vpm2,vd))
max_pts_2[patch_id]=vd;
}
}

for (std::size_t pid=0;pid<nb_patches_tm2; ++pid)
{
if (coplanar_patches_of_tm2.test(pid))
{
is_oo_tm2[pid] = ::CGAL::Polygon_mesh_processing::internal::is_outward_oriented(max_pts_2[pid].value(), tm2, parameters::vertex_point_map(vpm2));
}
}
}



for (typename An_edge_per_polyline_map::iterator
it=an_edge_per_polyline.begin(),
it_end=an_edge_per_polyline.end(); it!=it_end;++it)
Expand Down Expand Up @@ -1912,10 +1851,56 @@ class Face_graph_output_builder
{
if (coplanar_patches_of_tm1.test(patch_id))
{
// Two "identical" coplanar patches that are entire connected components
//we have the correspondance between cpln patches thanks to faces in tm1_coplanar_faces and tm2_coplanar_faces
CGAL_assertion(tm1_coplanar_faces.size()==tm2_coplanar_faces.size());
if (coplanar_tm1_to_coplanar_tm2.empty()) // fill container only once
{
coplanar_tm1_to_coplanar_tm2.resize(nb_patches_tm1, NID);
for (std::size_t i=0; i<tm1_coplanar_faces.size(); ++i)
{
std::size_t pid1 = tm1_patch_ids[get(fids1, tm1_coplanar_faces[i])];
std::size_t pid2 = tm2_patch_ids[get(fids2, tm2_coplanar_faces[i])];
coplanar_tm1_to_coplanar_tm2[pid1]=pid2;
}

const vertex_descriptor null_v = boost::graph_traits<TriangleMesh>::null_vertex();
extreme_vertex_per_cc_1.assign(nb_patches_tm1, null_v);
for (face_descriptor fd : faces(tm1))
{
std::size_t patch_id = tm1_patch_ids[get(fids1, fd)];
if (!coplanar_patches_of_tm1.test(patch_id)) continue;
halfedge_descriptor hd=halfedge(fd, tm1);
for (halfedge_descriptor h : CGAL::halfedges_around_face(hd, tm1))
{
vertex_descriptor vd = target(h, tm1);
if (extreme_vertex_per_cc_1[patch_id]==null_v || get(vpm1,extreme_vertex_per_cc_1[patch_id])<get(vpm1,vd))
extreme_vertex_per_cc_1[patch_id]=vd;
}
}

extreme_vertex_per_cc_2.assign(nb_patches_tm2, null_v);
for (face_descriptor fd : faces(tm2))
{
std::size_t patch_id = tm2_patch_ids[get(fids2, fd)];
if (!coplanar_patches_of_tm2.test(patch_id)) continue;
halfedge_descriptor hd=halfedge(fd, tm2);
for (halfedge_descriptor h : CGAL::halfedges_around_face(hd, tm2))
{
vertex_descriptor vd = target(h, tm2);
if (extreme_vertex_per_cc_2[patch_id]==null_v || get(vpm2,extreme_vertex_per_cc_2[patch_id])<get(vpm2,vd))
extreme_vertex_per_cc_2[patch_id]=vd;
}
}
}

const std::size_t patch_id2=coplanar_tm1_to_coplanar_tm2[patch_id];
CGAL_assertion(patch_id2!=NID);

if (is_oo_tm1[patch_id]==is_oo_tm2[patch_id2])
bool is_oo_tm1 = ::CGAL::Polygon_mesh_processing::internal::is_outward_oriented(extreme_vertex_per_cc_1[patch_id], tm1, parameters::vertex_point_map(vpm1)),
is_oo_tm2 = ::CGAL::Polygon_mesh_processing::internal::is_outward_oriented(extreme_vertex_per_cc_2[patch_id2], tm2, parameters::vertex_point_map(vpm2));

if (is_oo_tm1==is_oo_tm2)
{
coplanar_patches_of_tm1_for_union_and_intersection.set(patch_id);
coplanar_patches_of_tm2_for_union_and_intersection.set(patch_id2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ void test_operations(Mesh A, Mesh B,
std::string round,
std::size_t union_v, std::size_t inter_v, std::size_t diff1_v, std::size_t diff2_v)
{
#ifndef VERBOSE
CGAL_USE(round);
#endif
if (reverse_A) PMP::reverse_face_orientations(A);
if (reverse_B) PMP::reverse_face_orientations(B);

Expand Down

0 comments on commit ef5950d

Please sign in to comment.