@@ -1091,6 +1091,10 @@ class Face_graph_output_builder
1091
1091
boost::dynamic_bitset<> coplanar_patches_of_tm2_for_union_and_intersection (nb_patches_tm2,false );
1092
1092
patch_status_not_set_tm1.set ();
1093
1093
patch_status_not_set_tm2.set ();
1094
+ // extra containers used when entire connected components are identical (filled only if needed)
1095
+ std::vector<std::size_t > coplanar_tm1_to_coplanar_tm2;
1096
+ std::vector<vertex_descriptor> extreme_vertex_per_cc_1;
1097
+ std::vector<vertex_descriptor> extreme_vertex_per_cc_2;
1094
1098
1095
1099
// first set coplanar status of patches using the coplanar faces collected during the
1096
1100
// extra intersection edges collected. This is important in the case of full connected components
@@ -1847,8 +1851,61 @@ class Face_graph_output_builder
1847
1851
{
1848
1852
if (coplanar_patches_of_tm1.test (patch_id))
1849
1853
{
1850
- if (is_tm1_inside_out == is_tm2_inside_out)
1854
+ // Two "identical" coplanar patches that are entire connected components
1855
+ // we have the correspondance between cpln patches thanks to faces in tm1_coplanar_faces and tm2_coplanar_faces
1856
+ CGAL_assertion (tm1_coplanar_faces.size ()==tm2_coplanar_faces.size ());
1857
+ if (coplanar_tm1_to_coplanar_tm2.empty ()) // fill container only once
1858
+ {
1859
+ coplanar_tm1_to_coplanar_tm2.resize (nb_patches_tm1, NID);
1860
+ for (std::size_t i=0 ; i<tm1_coplanar_faces.size (); ++i)
1861
+ {
1862
+ std::size_t pid1 = tm1_patch_ids[get (fids1, tm1_coplanar_faces[i])];
1863
+ std::size_t pid2 = tm2_patch_ids[get (fids2, tm2_coplanar_faces[i])];
1864
+ coplanar_tm1_to_coplanar_tm2[pid1]=pid2;
1865
+ }
1866
+
1867
+ const vertex_descriptor null_v = boost::graph_traits<TriangleMesh>::null_vertex ();
1868
+ extreme_vertex_per_cc_1.assign (nb_patches_tm1, null_v);
1869
+ for (face_descriptor fd : faces (tm1))
1870
+ {
1871
+ std::size_t patch_id = tm1_patch_ids[get (fids1, fd)];
1872
+ if (!coplanar_patches_of_tm1.test (patch_id)) continue ;
1873
+ halfedge_descriptor hd=halfedge (fd, tm1);
1874
+ for (halfedge_descriptor h : CGAL::halfedges_around_face (hd, tm1))
1875
+ {
1876
+ vertex_descriptor vd = target (h, tm1);
1877
+ if (extreme_vertex_per_cc_1[patch_id]==null_v || get (vpm1,extreme_vertex_per_cc_1[patch_id])<get (vpm1,vd))
1878
+ extreme_vertex_per_cc_1[patch_id]=vd;
1879
+ }
1880
+ }
1881
+
1882
+ extreme_vertex_per_cc_2.assign (nb_patches_tm2, null_v);
1883
+ for (face_descriptor fd : faces (tm2))
1884
+ {
1885
+ std::size_t patch_id = tm2_patch_ids[get (fids2, fd)];
1886
+ if (!coplanar_patches_of_tm2.test (patch_id)) continue ;
1887
+ halfedge_descriptor hd=halfedge (fd, tm2);
1888
+ for (halfedge_descriptor h : CGAL::halfedges_around_face (hd, tm2))
1889
+ {
1890
+ vertex_descriptor vd = target (h, tm2);
1891
+ if (extreme_vertex_per_cc_2[patch_id]==null_v || get (vpm2,extreme_vertex_per_cc_2[patch_id])<get (vpm2,vd))
1892
+ extreme_vertex_per_cc_2[patch_id]=vd;
1893
+ }
1894
+ }
1895
+ }
1896
+
1897
+ const std::size_t patch_id2=coplanar_tm1_to_coplanar_tm2[patch_id];
1898
+ CGAL_assertion (patch_id2!=NID);
1899
+
1900
+ 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)),
1901
+ is_oo_tm2 = ::CGAL::Polygon_mesh_processing::internal::is_outward_oriented (extreme_vertex_per_cc_2[patch_id2], tm2, parameters::vertex_point_map (vpm2));
1902
+
1903
+ if (is_oo_tm1==is_oo_tm2)
1904
+ {
1851
1905
coplanar_patches_of_tm1_for_union_and_intersection.set (patch_id);
1906
+ coplanar_patches_of_tm2_for_union_and_intersection.set (patch_id2);
1907
+ patch_status_not_set_tm2.reset ( patch_id2 );
1908
+ }
1852
1909
}
1853
1910
else
1854
1911
{
0 commit comments