diff --git a/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_consecutive_bool_op.cpp b/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_consecutive_bool_op.cpp index 7b13f109a6d..6ade126528c 100644 --- a/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_consecutive_bool_op.cpp +++ b/Polygon_mesh_processing/examples/Polygon_mesh_processing/corefinement_consecutive_bool_op.cpp @@ -83,10 +83,10 @@ int main(int argc, char* argv[]) } Exact_point_map mesh1_exact_points = - mesh1.add_property_map("e:exact_point").first; + mesh1.add_property_map("v:exact_point").first; Exact_point_map mesh2_exact_points = - mesh2.add_property_map("e:exact_point").first; + mesh2.add_property_map("v:exact_point").first; Exact_vertex_point_map mesh1_vpm(mesh1_exact_points, mesh1); Exact_vertex_point_map mesh2_vpm(mesh2_exact_points, mesh2); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h index d2e8942ba17..95b7bd922c5 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/clip.h @@ -33,7 +33,14 @@ #include +#include +#include +#include +#include +#include #include +#include +#include namespace CGAL{ namespace Polygon_mesh_processing { @@ -420,10 +427,9 @@ generic_clip_impl( NamedParameters1>::type Vpm; typedef typename GetVertexPointMap::type Vpm2; - CGAL_USE_TYPE(Vpm2); - CGAL_assertion_code( - static const bool same_vpm = (boost::is_same::value); ) - CGAL_static_assertion(same_vpm); + + CGAL_static_assertion((std::is_same::value_type, + typename boost::property_traits::value_type>::value)); Vpm vpm1 = choose_parameter(get_parameter(np1, internal_np::vertex_point), get_property_map(boost::vertex_point, tm1)); @@ -477,17 +483,17 @@ generic_clip_impl( // surface intersection algorithm call typedef Corefinement::Generic_clip_output_builder Ob; typedef Corefinement::Surface_intersection_visitor_for_corefinement< - TriangleMesh, Vpm, Ob, Ecm_in, User_visitor> Algo_visitor; + TriangleMesh, Vpm, Vpm2, Ob, Ecm_in, User_visitor> Algo_visitor; Ecm_in ecm_in(tm1,tm2,ecm1,ecm2); Ob ob(tm1, tm2, vpm1, vpm2, algo_ecm1, fid_map1, use_compact_clipper); - Corefinement::Intersection_of_triangle_meshes + Corefinement::Intersection_of_triangle_meshes functor(tm1, tm2, vpm1, vpm2, Algo_visitor(uv,ob,ecm_in,&tm2)); functor(CGAL::Emptyset_iterator(), false, true); } diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h index 2297947a1e9..e34c951e4ea 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/corefinement.h @@ -201,22 +201,19 @@ corefine_and_compute_boolean_operations( // Vertex point maps //for input meshes - typedef typename GetVertexPointMap::type Vpm; - typedef typename GetVertexPointMap::type Vpm2; - CGAL_USE_TYPE(Vpm2); - CGAL_assertion_code( - static const bool same_vpm = (boost::is_same::value); ) - CGAL_static_assertion(same_vpm); + typedef typename GetVertexPointMap::type VPM1; + typedef typename GetVertexPointMap::type VPM2; - Vpm vpm1 = choose_parameter(get_parameter(np1, internal_np::vertex_point), - get_property_map(boost::vertex_point, tm1)); + CGAL_static_assertion((std::is_same::value_type, + typename boost::property_traits::value_type>::value)); - Vpm vpm2 = choose_parameter(get_parameter(np2, internal_np::vertex_point), - get_property_map(boost::vertex_point, tm2)); + VPM1 vpm1 = choose_parameter(get_parameter(np1, internal_np::vertex_point), + get_property_map(boost::vertex_point, tm1)); - typedef typename boost::property_traits::value_type Point_3; + VPM2 vpm2 = choose_parameter(get_parameter(np2, internal_np::vertex_point), + get_property_map(boost::vertex_point, tm2)); + + typedef typename boost::property_traits::value_type Point_3; // for output meshes: here we have to use a trick so that if for a specific output // that is not requested, the default vpm does not have the same value type as the @@ -227,24 +224,24 @@ corefine_and_compute_boolean_operations( Corefinement::TweakedGetVertexPointMap, Corefinement::TweakedGetVertexPointMap, Corefinement::TweakedGetVertexPointMap - > Vpm_out_tuple_helper; + > VPM_out_tuple_helper; typedef std::tuple< - boost::optional< typename std::tuple_element<0, Vpm_out_tuple_helper>::type::type >, - boost::optional< typename std::tuple_element<1, Vpm_out_tuple_helper>::type::type >, - boost::optional< typename std::tuple_element<2, Vpm_out_tuple_helper>::type::type >, - boost::optional< typename std::tuple_element<3, Vpm_out_tuple_helper>::type::type > - > Vpm_out_tuple; + boost::optional< typename std::tuple_element<0, VPM_out_tuple_helper>::type::type >, + boost::optional< typename std::tuple_element<1, VPM_out_tuple_helper>::type::type >, + boost::optional< typename std::tuple_element<2, VPM_out_tuple_helper>::type::type >, + boost::optional< typename std::tuple_element<3, VPM_out_tuple_helper>::type::type > + > VPM_out_tuple; - Vpm_out_tuple vpm_out_tuple( + VPM_out_tuple vpm_out_tuple( Corefinement::get_vpm(std::get<0>(nps_out), output[0], - typename std::tuple_element<0, Vpm_out_tuple_helper>::type::Use_default_tag()), + typename std::tuple_element<0, VPM_out_tuple_helper>::type::Use_default_tag()), Corefinement::get_vpm(std::get<1>(nps_out), output[1], - typename std::tuple_element<1, Vpm_out_tuple_helper>::type::Use_default_tag()), + typename std::tuple_element<1, VPM_out_tuple_helper>::type::Use_default_tag()), Corefinement::get_vpm(std::get<2>(nps_out), output[2], - typename std::tuple_element<2, Vpm_out_tuple_helper>::type::Use_default_tag()), + typename std::tuple_element<2, VPM_out_tuple_helper>::type::Use_default_tag()), Corefinement::get_vpm(std::get<3>(nps_out), output[3], - typename std::tuple_element<3, Vpm_out_tuple_helper>::type::Use_default_tag()) + typename std::tuple_element<3, VPM_out_tuple_helper>::type::Use_default_tag()) ); if (&tm1==&tm2) @@ -375,8 +372,9 @@ corefine_and_compute_boolean_operations( // surface intersection algorithm call typedef Corefinement::Face_graph_output_builder Ob; typedef Corefinement::Surface_intersection_visitor_for_corefinement< - TriangleMesh, Vpm, Ob, Ecm_in, User_visitor> Algo_visitor; + TriangleMesh, VPM1, VPM2, Ob, Ecm_in, User_visitor> Algo_visitor; + Ecm_in ecm_in(tm1,tm2,ecm1,ecm2); Edge_mark_map_tuple ecms_out(ecm_out_0, ecm_out_1, ecm_out_2, ecm_out_3); Ob ob(tm1, tm2, vpm1, vpm2, fid_map1, fid_map2, ecm_in, vpm_out_tuple, ecms_out, uv, output); @@ -402,7 +401,7 @@ corefine_and_compute_boolean_operations( ob.setup_for_clipping_a_surface(use_compact_clipper); } - Corefinement::Intersection_of_triangle_meshes + Corefinement::Intersection_of_triangle_meshes functor(tm1, tm2, vpm1, vpm2, Algo_visitor(uv,ob,ecm_in)); functor(CGAL::Emptyset_iterator(), throw_on_self_intersection, true); @@ -735,20 +734,17 @@ corefine( TriangleMesh& tm1, choose_parameter(get_parameter(np1, internal_np::throw_on_self_intersection), false); // Vertex point maps - typedef typename GetVertexPointMap::type Vpm; - typedef typename GetVertexPointMap::type Vpm2; - CGAL_USE_TYPE(Vpm2); - CGAL_assertion_code( - static const bool same_vpm = (boost::is_same::value);) - CGAL_static_assertion(same_vpm); + typedef typename GetVertexPointMap::type VPM1; + typedef typename GetVertexPointMap::type VPM2; - Vpm vpm1 = choose_parameter(get_parameter(np1, internal_np::vertex_point), - get_property_map(boost::vertex_point, tm1)); + CGAL_static_assertion((std::is_same::value_type, + typename boost::property_traits::value_type>::value)); - Vpm vpm2 = choose_parameter(get_parameter(np2, internal_np::vertex_point), - get_property_map(boost::vertex_point, tm2)); + VPM1 vpm1 = choose_parameter(get_parameter(np1, internal_np::vertex_point), + get_property_map(boost::vertex_point, tm1)); + + VPM2 vpm2 = choose_parameter(get_parameter(np2, internal_np::vertex_point), + get_property_map(boost::vertex_point, tm2)); // Edge is-constrained maps typedef typename internal_np::Lookup_named_param_def < @@ -786,10 +782,11 @@ corefine( TriangleMesh& tm1, // surface intersection algorithm call typedef Corefinement::No_extra_output_from_corefinement Ob; typedef Corefinement::Surface_intersection_visitor_for_corefinement< - TriangleMesh, Vpm, Ob, Ecm, User_visitor> Algo_visitor; + TriangleMesh, VPM1, VPM2, Ob, Ecm, User_visitor> Algo_visitor; + Ob ob; Ecm ecm(tm1,tm2,ecm1,ecm2); - Corefinement::Intersection_of_triangle_meshes + Corefinement::Intersection_of_triangle_meshes functor(tm1, tm2, vpm1, vpm2, Algo_visitor(uv,ob,ecm,const_mesh_ptr)); functor(CGAL::Emptyset_iterator(), throw_on_self_intersection, true); } @@ -852,9 +849,9 @@ autorefine( TriangleMesh& tm, using parameters::get_parameter; // Vertex point maps - typedef typename GetVertexPointMap::type Vpm; + typedef typename GetVertexPointMap::type VPM; - Vpm vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), + VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), get_property_map(boost::vertex_point, tm)); // Edge is-constrained maps @@ -877,10 +874,10 @@ autorefine( TriangleMesh& tm, // surface intersection algorithm call typedef Corefinement::No_extra_output_from_corefinement Ob; typedef Corefinement::Surface_intersection_visitor_for_corefinement< - TriangleMesh, Vpm, Ob, Ecm, User_visitor,true> Algo_visitor; + TriangleMesh, VPM, VPM, Ob, Ecm, User_visitor,true> Algo_visitor; Ob ob; - Corefinement::Intersection_of_triangle_meshes + Corefinement::Intersection_of_triangle_meshes functor(tm, vpm, Algo_visitor(uv,ob,ecm) ); functor(CGAL::Emptyset_iterator(), true); @@ -945,8 +942,8 @@ autorefine_and_remove_self_intersections( TriangleMesh& tm, using parameters::get_parameter; // Vertex point maps - typedef typename GetVertexPointMap::type Vpm; - Vpm vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), + typedef typename GetVertexPointMap::type VPM; + VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), get_property_map(boost::vertex_point, tm)); // Face index map @@ -972,16 +969,16 @@ autorefine_and_remove_self_intersections( TriangleMesh& tm, // surface intersection algorithm call typedef Corefinement::Output_builder_for_autorefinement Ob; typedef Corefinement::Surface_intersection_visitor_for_corefinement< - TriangleMesh, Vpm, Ob, Ecm, User_visitor,true> Algo_visitor; + TriangleMesh, VPM, VPM, Ob, Ecm, User_visitor,true> Algo_visitor; Ob ob(tm, vpm, fid_map, ecm); - Corefinement::Intersection_of_triangle_meshes + Corefinement::Intersection_of_triangle_meshes functor(tm, vpm, Algo_visitor(uv,ob,ecm) ); functor(CGAL::Emptyset_iterator(), true); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h index c3929c5c3cc..6f57675de59 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Face_graph_output_builder.h @@ -58,7 +58,8 @@ namespace PMP=Polygon_mesh_processing; namespace params=PMP::parameters; template ::value_type - >::Kernel >::type Kernel; + typename boost::property_traits::value_type + >::Kernel >::type Kernel; + typedef typename Default::Get > >::type EdgeMarkMapBind; @@ -111,8 +113,8 @@ class Face_graph_output_builder //Data members TriangleMesh &tm1, &tm2; // property maps of input meshes - const VertexPointMap vpm1; - const VertexPointMap vpm2; + const VertexPointMap1& vpm1; + const VertexPointMap2& vpm2; FaceIdMap1 fids1; FaceIdMap2 fids2; EdgeMarkMapBind& marks_on_input_edges; @@ -346,8 +348,8 @@ public: Face_graph_output_builder(TriangleMesh& tm1, TriangleMesh& tm2, - const VertexPointMap vpm1, - const VertexPointMap vpm2, + const VertexPointMap1& vpm1, + const VertexPointMap2& vpm2, FaceIdMap1 fids1, FaceIdMap2 fids2, EdgeMarkMapBind& marks_on_input_edges, @@ -1098,10 +1100,6 @@ public: if (!is_tm2_closed) patch_status_not_set_tm1.reset(); - typedef Side_of_triangle_mesh Inside_poly_test; - #ifdef CGAL_COREFINEMENT_POLYHEDRA_DEBUG #warning stop using next_marked_halfedge_around_target_vertex and create lists of halfedges instead? #endif @@ -1111,7 +1109,7 @@ public: CGAL::Bounded_side in_tm2 = is_tm2_inside_out ? ON_UNBOUNDED_SIDE : ON_BOUNDED_SIDE; - Inside_poly_test inside_tm2(tm2, vpm2); + Side_of_triangle_mesh inside_tm2(tm2, vpm2); for(face_descriptor f : faces(tm1)) { @@ -1173,7 +1171,7 @@ public: CGAL::Bounded_side in_tm1 = is_tm1_inside_out ? ON_UNBOUNDED_SIDE : ON_BOUNDED_SIDE; - Inside_poly_test inside_tm1(tm1, vpm1); + Side_of_triangle_mesh inside_tm1(tm1, vpm1); for(face_descriptor f : faces(tm2)) { const std::size_t f_id = get(fids2, f); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Generic_clip_output_builder.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Generic_clip_output_builder.h index bcc8e75469d..d84788ff868 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Generic_clip_output_builder.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Generic_clip_output_builder.h @@ -38,7 +38,8 @@ namespace PMP=Polygon_mesh_processing; namespace params=PMP::parameters; template @@ -48,7 +49,7 @@ class Generic_clip_output_builder typedef typename Default::Get< Kernel_, typename Kernel_traits< - typename boost::property_traits::value_type + typename boost::property_traits::value_type >::Kernel >::type Kernel; // graph_traits typedefs @@ -76,8 +77,8 @@ class Generic_clip_output_builder //Data members TriangleMesh &tm1, &tm2; // property maps of input meshes - const VertexPointMap vpm1; - const VertexPointMap vpm2; + const VertexPointMap1 vpm1; + const VertexPointMap2 vpm2; Ecm1 ecm1; FaceIdMap1 fids1; bool use_compact_clipper; @@ -105,8 +106,8 @@ public: Generic_clip_output_builder(TriangleMesh& tm1, TriangleMesh& tm2, - const VertexPointMap vpm1, - const VertexPointMap vpm2, + const VertexPointMap1 vpm1, + const VertexPointMap2 vpm2, const Ecm1& ecm1, FaceIdMap1 fids1, bool use_compact_clipper) @@ -167,7 +168,7 @@ public: typedef Side_of_triangle_mesh Inside_poly_test; + VertexPointMap2> Inside_poly_test; CGAL::Bounded_side in_tm2 = is_tm2_inside_out ? ON_UNBOUNDED_SIDE : ON_BOUNDED_SIDE; diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Visitor.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Visitor.h index 62a021acfbd..ca0d31915bb 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Visitor.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/Visitor.h @@ -102,7 +102,8 @@ struct No_extra_output_from_corefinement // A visitor for Intersection_of_triangle_meshes that can be used to corefine // two meshes template< class TriangleMesh, - class VertexPointMap, + class VertexPointMap1, + class VertexPointMap2, class OutputBuilder_ = Default, class EdgeMarkMapBind_ = Default, class UserVisitor_ = Default, @@ -141,8 +142,9 @@ private: typedef boost::unordered_map Vertex_to_node_id; typedef std::map Mesh_to_vertex_to_node_id; // typedef for the CDT - typedef typename Intersection_nodes::Exact_kernel EK; + typedef Intersection_nodes INodes; + typedef typename INodes::Exact_kernel EK; typedef Triangulation_2_projection_traits_3 CDT_traits; typedef Triangulation_vertex_base_with_info_2 Vb; typedef Constrained_triangulation_face_base_2 Fb; @@ -365,7 +367,8 @@ public: } } - if (tm1_ptr==const_mesh_ptr) return; + if (tm1_ptr==const_mesh_ptr) + return; CGAL_assertion(!is_target_coplanar || !is_source_coplanar); //coplanar edge are not forwarded @@ -406,16 +409,16 @@ public: //sort node ids so that we can split the hedge //consecutively - template + template void sort_vertices_along_hedge(std::vector& node_ids, halfedge_descriptor hedge, const TriangleMesh& tm, - const VertexPointMap& vpm, + const VPM& vpm, const Node_vector& nodes) { std::sort(node_ids.begin(), node_ids.end(), - Less_along_a_halfedge + Less_along_a_halfedge (hedge, tm, vpm, nodes) ); } @@ -490,6 +493,8 @@ public: }; + typedef boost::unordered_map Face_boundaries; + //update the id of input mesh vertex that are also a node void update_face_indices( std::array& f_vertices, @@ -592,22 +597,366 @@ public: return vh; } - void finalize(Intersection_nodes& nodes, - const TriangleMesh& tm1, - const TriangleMesh& tm2, - const VertexPointMap& vpm1, - const VertexPointMap& vpm2) + template + void split_halfedges(OnEdgeMapIterator it, + const VPM& vpm, + INodes& nodes, + std::map& mesh_to_face_boundaries) + { + TriangleMesh& tm=*it->first; + CGAL_assertion(&tm!=const_mesh_ptr); + + On_edge_map& on_edge_map=it->second; + On_face_map& on_face_map=on_face[&tm]; + Face_boundaries& face_boundaries=mesh_to_face_boundaries[&tm]; + + for(typename On_edge_map::iterator it2=on_edge_map.begin(); + it2!=on_edge_map.end(); + ++it2) + { + //the edge to be split + halfedge_descriptor hedge=halfedge(it2->first,tm); + //indices of the nodes to be inserted + Node_ids& node_ids=it2->second; + CGAL_assertion( std::set(node_ids.begin(), node_ids.end()) + .size()==node_ids.size() ); + //sort nodes along the egde to allow consecutive splits + sort_vertices_along_hedge(node_ids,hedge,tm,vpm,nodes); + + //save original face and nodes for face of hedge (1) + if ( !is_border(hedge,tm) ){ + face_descriptor f=face(hedge,tm); + typename Face_boundaries::iterator it_face = face_boundaries.find(f); + if (it_face==face_boundaries.end()) + it_face=face_boundaries.insert(std::make_pair(f,Face_boundary(hedge,tm))).first; + it_face->second.copy_node_ids(hedge,node_ids.begin(),node_ids.end()); + } + + //save original face and nodes for face of hedge->opposite (2) + typename Face_boundaries::iterator opposite_original_info=face_boundaries.end(); + halfedge_descriptor hedge_opp = opposite(hedge,tm); + if ( !is_border(hedge_opp,tm) ){ + face_descriptor f=face(hedge_opp,tm); + opposite_original_info=face_boundaries.find(f); + if (opposite_original_info==face_boundaries.end()) + opposite_original_info=face_boundaries.insert(std::make_pair(f,Face_boundary(hedge_opp,tm))).first; + opposite_original_info->second.copy_node_ids(hedge_opp,node_ids.rbegin(),node_ids.rend()); + } + + typename Mesh_to_map_node::iterator it_map=mesh_to_node_id_to_vertex.find(&tm); + CGAL_assertion(it_map!=mesh_to_node_id_to_vertex.end()); + //a map to identify the vertex in the polyhedron corresponding to an intersection point + Node_id_to_vertex& node_id_to_vertex=it_map->second; + + CGAL_assertion_code(vertex_descriptor original_vertex=source(hedge,tm);) + + //We need an edge incident to the source vertex of hedge. This is the first opposite edge created. + bool first=true; + halfedge_descriptor hedge_incident_to_src=Graph_traits::null_halfedge(); + bool hedge_is_marked = call_get(marks_on_edges,tm,edge(hedge,tm)); + //do split the edges + CGAL_assertion_code(vertex_descriptor expected_src=source(hedge,tm)); + for(std::size_t node_id : node_ids) + { + halfedge_descriptor hnew = Euler::split_edge(hedge, tm); + CGAL_assertion(expected_src==source(hnew,tm)); + vertex_descriptor vnew=target(hnew,tm); +// user_visitor.new_vertex_added(node_id, vnew, tm); // NODE_VISITOR_TAG + nodes.call_put(vpm, vnew, node_id, tm); + // register the new vertex in the output builder + output_builder.set_vertex_id(vnew, node_id, tm); + node_id_to_vertex[node_id]=vnew; + if (first){ + first=false; + hedge_incident_to_src=next(opposite(hedge,tm),tm); + } + + //update marker tags. If the edge was marked, then the resulting edges in the split must be marked + if ( hedge_is_marked ) + call_put(marks_on_edges,tm,edge(hnew,tm),true); + + CGAL_assertion_code(expected_src=vnew); + } + + CGAL_assertion(target(hedge_incident_to_src,tm)==original_vertex); + CGAL_assertion(face(hedge_incident_to_src,tm)==face(hedge_opp,tm)); + + //save original face and nodes for face of hedge->opposite (2) + if ( !is_border(hedge_opp,tm) ){ + CGAL_assertion(opposite_original_info!=face_boundaries.end()); + opposite_original_info->second.update_original_halfedge( + hedge_opp,hedge_incident_to_src,tm); + } + + //insert the two incident faces in on_face map so that they will be triangulated. + if (!is_border(hedge,tm)) on_face_map[face(hedge,tm)]; + if (!is_border(hedge_opp,tm)) on_face_map[face(hedge_opp,tm)]; + } + } + + template + void triangulate_intersected_faces(OnFaceMapIterator it, + const VPM& vpm, + INodes& nodes, + std::map& mesh_to_face_boundaries) + { + TriangleMesh& tm=*it->first; + CGAL_assertion(&tm!=const_mesh_ptr); + + On_face_map& on_face_map=it->second; + Face_boundaries& face_boundaries=mesh_to_face_boundaries[&tm]; + Node_id_to_vertex& node_id_to_vertex=mesh_to_node_id_to_vertex[&tm]; + Vertex_to_node_id& vertex_to_node_id=mesh_to_vertex_to_node_id[&tm]; + + const Node_id nb_nodes = nodes.size(); + + for (typename On_face_map::iterator it=on_face_map.begin(); + it!=on_face_map.end();++it) + { + face_descriptor f = it->first; //the face to be triangulated + Node_ids& node_ids = it->second; // ids of nodes in the interior of f + typename Face_boundaries::iterator it_fb=face_boundaries.find(f); + + std::map id_to_CDT_vh; + + //associate an edge of the triangulation to a halfedge in a given polyhedron + std::map,halfedge_descriptor> edge_to_hedge; + + // the vertices of f + std::array f_vertices; + // the node_id of an input vertex or a fake id (>=nb_nodes) + std::array f_indices = {{nb_nodes,nb_nodes+1,nb_nodes+2}}; + if (it_fb!=face_boundaries.end()){ //the boundary of the triangle face was refined + f_vertices[0]=it_fb->second.vertices[0]; + f_vertices[1]=it_fb->second.vertices[1]; + f_vertices[2]=it_fb->second.vertices[2]; + update_face_indices(f_vertices,f_indices,vertex_to_node_id); + if (doing_autorefinement) + it_fb->second.update_node_id_to_vertex_map(node_id_to_vertex, tm); + } + else{ + CGAL_assertion( is_triangle(halfedge(f,tm),tm) ); + halfedge_descriptor h0=halfedge(f,tm), h1=next(h0,tm), h2=next(h1,tm); + f_vertices[0]=target(h0,tm); //nb_nodes + f_vertices[1]=target(h1,tm); //nb_nodes+1 + f_vertices[2]=target(h2,tm); //nb_nodes+2 + + update_face_indices(f_vertices,f_indices,vertex_to_node_id); + edge_to_hedge[std::make_pair( f_indices[2],f_indices[0] )] = h0; + edge_to_hedge[std::make_pair( f_indices[0],f_indices[1] )] = h1; + edge_to_hedge[std::make_pair( f_indices[1],f_indices[2] )] = h2; + } + + typename EK::Point_3 p = nodes.to_exact(get(vpm,f_vertices[0])), + q = nodes.to_exact(get(vpm,f_vertices[1])), + r = nodes.to_exact(get(vpm,f_vertices[2])); +///TODO use a positive normal and remove all work around to guarantee that triangulation of coplanar patches are compatible + CDT_traits traits(typename EK::Construct_normal_3()(p,q,r)); + CDT cdt(traits); + + // insert triangle points + std::array triangle_vertices; + //we can do this to_exact because these are supposed to be input points. + triangle_vertices[0]=cdt.insert_outside_affine_hull(p); + triangle_vertices[1]=cdt.insert_outside_affine_hull(q); + triangle_vertices[2]=cdt.tds().insert_dim_up(cdt.infinite_vertex(), false); + triangle_vertices[2]->set_point(r); + + + triangle_vertices[0]->info()=f_indices[0]; + triangle_vertices[1]->info()=f_indices[1]; + triangle_vertices[2]->info()=f_indices[2]; + + node_id_to_vertex[nb_nodes ]=f_vertices[0]; + node_id_to_vertex[nb_nodes+1]=f_vertices[1]; + node_id_to_vertex[nb_nodes+2]=f_vertices[2]; + + //if one of the triangle input vertex is also a node + for (int ik=0;ik<3;++ik){ + if ( f_indices[ik]vertex(oi) ) ); + } + + // In this loop, for each original edge of the triangle, we insert + // the constrained edges and we recover the halfedge_descriptor + // corresponding to these constrained (they are already in tm) + Face_boundary& f_boundary=it_fb->second; + for (int i=0;i<3;++i){ + //handle case of halfedge starting at triangle_vertices[i] + // and ending at triangle_vertices[(i+1)%3] + + const Node_ids& ids_on_edge=f_boundary.node_ids_array[i]; + CDT_Vertex_handle previous=triangle_vertices[i]; + Node_id prev_index=f_indices[i];// node-id of the mesh vertex + halfedge_descriptor hedge = next(f_boundary.halfedges[(i+2)%3],tm); + CGAL_assertion( source(hedge,tm)==f_boundary.vertices[i] ); + if (!ids_on_edge.empty()){ //is there at least one node on this edge? + // fh must be an infinite face + // The points must be ordered from fh->vertex(cw(infinite_vertex)) to fh->vertex(ccw(infinite_vertex)) + for(Node_id id : ids_on_edge) + { + CDT_Vertex_handle vh=insert_point_on_ch_edge(cdt,infinite_faces[i],nodes.exact_node(id)); + vh->info()=id; + id_to_CDT_vh.insert(std::make_pair(id,vh)); + edge_to_hedge[std::make_pair(prev_index,id)]=hedge; + previous=vh; + hedge=next(hedge,tm); + prev_index=id; + } + } + else{ + CGAL_assertion_code(halfedge_descriptor hd=f_boundary.halfedges[i]); + CGAL_assertion( target(hd,tm) == f_boundary.vertices[(i+1)%3] ); + CGAL_assertion( source(hd,tm) == f_boundary.vertices[ i ] ); + } + CGAL_assertion(hedge==f_boundary.halfedges[i]); + edge_to_hedge[std::make_pair(prev_index,f_indices[(i+1)%3])] = + it_fb->second.halfedges[i]; + } + } + + //insert point inside face + for(Node_id node_id : node_ids) + { + CDT_Vertex_handle vh=cdt.insert(nodes.exact_node(node_id)); + vh->info()=node_id; + id_to_CDT_vh.insert(std::make_pair(node_id,vh)); + } + + std::vector > constrained_edges; + + // insert constraints that are interior to the triangle (in the case + // no edges are collinear in the meshes) + insert_constrained_edges(node_ids,cdt,id_to_CDT_vh,constrained_edges); + + // insert constraints between points that are on the boundary + // (not a contrained on the triangle boundary) + if (it_fb!=face_boundaries.end()) //is f not a triangle ? + { + for (int i=0;i<3;++i) + { + Node_ids& ids=it_fb->second.node_ids_array[i]; + insert_constrained_edges(ids,cdt,id_to_CDT_vh,constrained_edges,1); + } + } + + //insert coplanar edges for endpoints of triangles + for (int i=0;i<3;++i){ + Node_id nindex=triangle_vertices[i]->info(); + if ( nindex < nb_nodes ) + insert_constrained_edges_coplanar_case(nindex,cdt,id_to_CDT_vh); + } + + //XSL_TAG_CPL_VERT + //collect edges incident to a point that is the intersection of two + // coplanar faces. This ensure that triangulations are compatible. + if (it_fb!=face_boundaries.end()) //is f not a triangle ? + { + for (typename CDT::Finite_vertices_iterator + vit=cdt.finite_vertices_begin(), + vit_end=cdt.finite_vertices_end();vit_end!=vit;++vit) + { + //skip original vertices (that are not nodes) and non-coplanar face + // issued vertices (this is working because intersection points + // between coplanar facets are the first inserted) + if (vit->info() >= nb_nodes || + vit->info() >= number_coplanar_vertices) continue; + // \todo no need to insert constrained edges (they also are constrained + // in the other mesh)!! + typename std::map< Node_id,std::set >::iterator res = + coplanar_constraints.insert( + std::make_pair(vit->info(),std::set())).first; + //turn around the vertex and get incident edge + typename CDT::Edge_circulator start=cdt.incident_edges(vit); + typename CDT::Edge_circulator curr=start; + do{ + if (cdt.is_infinite(*curr) ) continue; + typename CDT::Edge mirror=cdt.mirror_edge(*curr); + if ( cdt.is_infinite( curr->first->vertex(curr->second) ) || + cdt.is_infinite( mirror.first->vertex(mirror.second) ) ) + continue; // skip edges that are on the boundary of the triangle + // (these are already constrained) + //insert edges in the set of constraints + CDT_Vertex_handle vh=vit; + int nindex = curr->first->vertex((curr->second+1)%3)==vh + ? (curr->second+2)%3 + : (curr->second+1)%3; + CDT_Vertex_handle vn=curr->first->vertex(nindex); + if ( vit->info() > vn->info() || vn->info()>=nb_nodes) + continue; //take only one out of the two edges + skip input + CGAL_assertion(vn->info()second.insert( vn->info() ); + }while(start!=++curr); + } + } + + // import the triangle in `cdt` in the face `f` of `tm` + triangulate_a_face(f, tm, nodes, node_ids, node_id_to_vertex, + edge_to_hedge, cdt, vpm, output_builder, user_visitor); + + // TODO Here we do the update only for internal edges. + // Update for border halfedges could be done during the split + + //3) mark halfedges that are common to two polyhedral surfaces + //recover halfedges inserted that are on the intersection + typedef std::pair Node_id_pair; + for(const Node_id_pair& node_id_pair : constrained_edges) + { + typename std::map + ::iterator it_poly_hedge=edge_to_hedge.find(node_id_pair); + //we cannot have an assertion here in case an edge or part of an edge is a constraints. + //Indeed, the graph_of_constraints report an edge 0,1 and 1,0 for example while only one of the two + //is defined as one of them defines an adjacent face + //CGAL_assertion(it_poly_hedge!=edge_to_hedge.end()); + if( it_poly_hedge!=edge_to_hedge.end() ){ + call_put(marks_on_edges,tm,edge(it_poly_hedge->second,tm),true); + output_builder.set_edge_per_polyline(tm,node_id_pair,it_poly_hedge->second); + } + else{ + //WARNING: in few case this is needed if the marked edge is on the border + //to optimize it might be better to only use sorted pair. TAG_SLXX1 + Node_id_pair opposite_pair(node_id_pair.second,node_id_pair.first); + it_poly_hedge=edge_to_hedge.find(opposite_pair); + CGAL_assertion( it_poly_hedge!=edge_to_hedge.end() ); + + call_put(marks_on_edges,tm,edge(it_poly_hedge->second,tm),true); + output_builder.set_edge_per_polyline(tm,opposite_pair,it_poly_hedge->second); + } + } + } + } + + void finalize(INodes& nodes, + const TriangleMesh& tm1, + const TriangleMesh& tm2, + const VertexPointMap1& vpm1, + const VertexPointMap2& vpm2) { nodes.all_nodes_created(); TriangleMesh* tm1_ptr = const_cast(&tm1); TriangleMesh* tm2_ptr = const_cast(&tm2); - std::map vpms; - vpms[tm1_ptr] = vpm1; - vpms[tm2_ptr] = vpm2; - vertex_descriptor null_vertex = Graph_traits::null_vertex(); const Node_id nb_nodes = nodes.size(); // we reserve nb_nodes+3 because we use the last three entries for the @@ -617,7 +966,6 @@ public: //store for each triangle face which boundary is intersected by the other surface, //original vertices (and halfedges in the refined mesh pointing on these vertices) - typedef boost::unordered_map Face_boundaries; std::map mesh_to_face_boundaries; //0) For each triangle mesh, collect original vertices that belongs to the intersection. @@ -632,6 +980,7 @@ public: { TriangleMesh& tm=*it->first; CGAL_assertion(&tm!=const_mesh_ptr); + // Face_boundaries& face_boundaries=mesh_to_face_boundaries[&tm]; Node_to_target_of_hedge_map& nodes_to_hedge=it->second; @@ -700,95 +1049,10 @@ public: for (typename std::map::iterator it=on_edge.begin(); it!=on_edge.end(); ++it) { - TriangleMesh& tm=*it->first; - CGAL_assertion(&tm!=const_mesh_ptr); - const VertexPointMap& vpm=vpms[&tm]; - On_edge_map& on_edge_map=it->second; - On_face_map& on_face_map=on_face[&tm]; - Face_boundaries& face_boundaries=mesh_to_face_boundaries[&tm]; - - for(typename On_edge_map::iterator it2=on_edge_map.begin(); - it2!=on_edge_map.end(); - ++it2) - { - //the edge to be split - halfedge_descriptor hedge=halfedge(it2->first,tm); - //indices of the nodes to be inserted - Node_ids& node_ids=it2->second; - CGAL_assertion( std::set(node_ids.begin(), node_ids.end()) - .size()==node_ids.size() ); - //sort nodes along the egde to allow consecutive splits - sort_vertices_along_hedge(node_ids,hedge,tm,vpm,nodes); - - //save original face and nodes for face of hedge (1) - if ( !is_border(hedge,tm) ){ - face_descriptor f=face(hedge,tm); - typename Face_boundaries::iterator it_face = face_boundaries.find(f); - if (it_face==face_boundaries.end()) - it_face=face_boundaries.insert(std::make_pair(f,Face_boundary(hedge,tm))).first; - it_face->second.copy_node_ids(hedge,node_ids.begin(),node_ids.end()); - } - - //save original face and nodes for face of hedge->opposite (2) - typename Face_boundaries::iterator opposite_original_info=face_boundaries.end(); - halfedge_descriptor hedge_opp = opposite(hedge,tm); - if ( !is_border(hedge_opp,tm) ){ - face_descriptor f=face(hedge_opp,tm); - opposite_original_info=face_boundaries.find(f); - if (opposite_original_info==face_boundaries.end()) - opposite_original_info=face_boundaries.insert(std::make_pair(f,Face_boundary(hedge_opp,tm))).first; - opposite_original_info->second.copy_node_ids(hedge_opp,node_ids.rbegin(),node_ids.rend()); - } - - typename Mesh_to_map_node::iterator it_map=mesh_to_node_id_to_vertex.find(&tm); - CGAL_assertion(it_map!=mesh_to_node_id_to_vertex.end()); - //a map to identify the vertex in the polyhedron corresponding to an intersection point - Node_id_to_vertex& node_id_to_vertex=it_map->second; - - CGAL_assertion_code(vertex_descriptor original_vertex=source(hedge,tm);) - - //We need an edge incident to the source vertex of hedge. This is the first opposite edge created. - bool first=true; - halfedge_descriptor hedge_incident_to_src=Graph_traits::null_halfedge(); - bool hedge_is_marked = call_get(marks_on_edges,tm,edge(hedge,tm)); - //do split the edges - CGAL_assertion_code(vertex_descriptor expected_src=source(hedge,tm)); - for(std::size_t node_id : node_ids) - { - halfedge_descriptor hnew = Euler::split_edge(hedge, tm); - CGAL_assertion(expected_src==source(hnew,tm)); - vertex_descriptor vnew=target(hnew,tm); -// user_visitor.new_vertex_added(node_id, vnew, tm); // NODE_VISITOR_TAG - nodes.call_put(vpm, vnew, node_id, tm); - // register the new vertex in the output builder - output_builder.set_vertex_id(vnew, node_id, tm); - node_id_to_vertex[node_id]=vnew; - if (first){ - first=false; - hedge_incident_to_src=next(opposite(hedge,tm),tm); - } - - //update marker tags. If the edge was marked, then the resulting edges in the split must be marked - if ( hedge_is_marked ) - call_put(marks_on_edges,tm,edge(hnew,tm),true); - - CGAL_assertion_code(expected_src=vnew); - } - - CGAL_assertion(target(hedge_incident_to_src,tm)==original_vertex); - CGAL_assertion(face(hedge_incident_to_src,tm)==face(hedge_opp,tm)); - - //save original face and nodes for face of hedge->opposite (2) - if ( !is_border(hedge_opp,tm) ){ - CGAL_assertion(opposite_original_info!=face_boundaries.end()); - opposite_original_info->second.update_original_halfedge( - hedge_opp,hedge_incident_to_src,tm); - } - - //insert the two incident faces in on_face map so that they will be triangulated. - if (!is_border(hedge,tm)) on_face_map[face(hedge,tm)]; - if (!is_border(hedge_opp,tm)) on_face_map[face(hedge_opp,tm)]; - } + if(it->first == tm1_ptr) + split_halfedges(it, vpm1, nodes, mesh_to_face_boundaries); + else + split_halfedges(it, vpm2, nodes, mesh_to_face_boundaries); } //2)triangulation of the triangle faces containing intersection point in their interior @@ -796,248 +1060,10 @@ public: for (typename std::map::iterator it=on_face.begin(); it!=on_face.end(); ++it) { - TriangleMesh& tm=*it->first; - CGAL_assertion(&tm!=const_mesh_ptr); - const VertexPointMap& vpm=vpms[&tm]; - On_face_map& on_face_map=it->second; - Face_boundaries& face_boundaries=mesh_to_face_boundaries[&tm]; - Node_id_to_vertex& node_id_to_vertex=mesh_to_node_id_to_vertex[&tm]; - Vertex_to_node_id& vertex_to_node_id=mesh_to_vertex_to_node_id[&tm]; - - for (typename On_face_map::iterator it=on_face_map.begin(); - it!=on_face_map.end();++it) - { - face_descriptor f = it->first; //the face to be triangulated - Node_ids& node_ids = it->second; // ids of nodes in the interior of f - typename Face_boundaries::iterator it_fb=face_boundaries.find(f); - - std::map id_to_CDT_vh; - - //associate an edge of the triangulation to a halfedge in a given polyhedron - std::map,halfedge_descriptor> edge_to_hedge; - - // the vertices of f - std::array f_vertices; - // the node_id of an input vertex or a fake id (>=nb_nodes) - std::array f_indices = {{nb_nodes,nb_nodes+1,nb_nodes+2}}; - if (it_fb!=face_boundaries.end()){ //the boundary of the triangle face was refined - f_vertices[0]=it_fb->second.vertices[0]; - f_vertices[1]=it_fb->second.vertices[1]; - f_vertices[2]=it_fb->second.vertices[2]; - update_face_indices(f_vertices,f_indices,vertex_to_node_id); - if (doing_autorefinement) - it_fb->second.update_node_id_to_vertex_map(node_id_to_vertex, tm); - } - else{ - CGAL_assertion( is_triangle(halfedge(f,tm),tm) ); - halfedge_descriptor h0=halfedge(f,tm), h1=next(h0,tm), h2=next(h1,tm); - f_vertices[0]=target(h0,tm); //nb_nodes - f_vertices[1]=target(h1,tm); //nb_nodes+1 - f_vertices[2]=target(h2,tm); //nb_nodes+2 - - update_face_indices(f_vertices,f_indices,vertex_to_node_id); - edge_to_hedge[std::make_pair( f_indices[2],f_indices[0] )] = h0; - edge_to_hedge[std::make_pair( f_indices[0],f_indices[1] )] = h1; - edge_to_hedge[std::make_pair( f_indices[1],f_indices[2] )] = h2; - } - - typename EK::Point_3 p = nodes.to_exact(get(vpm,f_vertices[0])), - q = nodes.to_exact(get(vpm,f_vertices[1])), - r = nodes.to_exact(get(vpm,f_vertices[2])); -///TODO use a positive normal and remove all work around to guarantee that triangulation of coplanar patches are compatible - CDT_traits traits(typename EK::Construct_normal_3()(p,q,r)); - CDT cdt(traits); - - // insert triangle points - std::array triangle_vertices; - //we can do this to_exact because these are supposed to be input points. - triangle_vertices[0]=cdt.insert_outside_affine_hull(p); - triangle_vertices[1]=cdt.insert_outside_affine_hull(q); - triangle_vertices[2]=cdt.tds().insert_dim_up(cdt.infinite_vertex(), false); - triangle_vertices[2]->set_point(r); - - - triangle_vertices[0]->info()=f_indices[0]; - triangle_vertices[1]->info()=f_indices[1]; - triangle_vertices[2]->info()=f_indices[2]; - - node_id_to_vertex[nb_nodes ]=f_vertices[0]; - node_id_to_vertex[nb_nodes+1]=f_vertices[1]; - node_id_to_vertex[nb_nodes+2]=f_vertices[2]; - - //if one of the triangle input vertex is also a node - for (int ik=0;ik<3;++ik){ - if ( f_indices[ik]vertex(oi) ) ); - } - - // In this loop, for each original edge of the triangle, we insert - // the constrained edges and we recover the halfedge_descriptor - // corresponding to these constrained (they are already in tm) - Face_boundary& f_boundary=it_fb->second; - for (int i=0;i<3;++i){ - //handle case of halfedge starting at triangle_vertices[i] - // and ending at triangle_vertices[(i+1)%3] - - const Node_ids& ids_on_edge=f_boundary.node_ids_array[i]; - CDT_Vertex_handle previous=triangle_vertices[i]; - Node_id prev_index=f_indices[i];// node-id of the mesh vertex - halfedge_descriptor hedge = next(f_boundary.halfedges[(i+2)%3],tm); - CGAL_assertion( source(hedge,tm)==f_boundary.vertices[i] ); - if (!ids_on_edge.empty()){ //is there at least one node on this edge? - // fh must be an infinite face - // The points must be ordered from fh->vertex(cw(infinite_vertex)) to fh->vertex(ccw(infinite_vertex)) - for(Node_id id : ids_on_edge) - { - CDT_Vertex_handle vh=insert_point_on_ch_edge(cdt,infinite_faces[i],nodes.exact_node(id)); - vh->info()=id; - id_to_CDT_vh.insert(std::make_pair(id,vh)); - edge_to_hedge[std::make_pair(prev_index,id)]=hedge; - previous=vh; - hedge=next(hedge,tm); - prev_index=id; - } - } - else{ - CGAL_assertion_code(halfedge_descriptor hd=f_boundary.halfedges[i]); - CGAL_assertion( target(hd,tm) == f_boundary.vertices[(i+1)%3] ); - CGAL_assertion( source(hd,tm) == f_boundary.vertices[ i ] ); - } - CGAL_assertion(hedge==f_boundary.halfedges[i]); - edge_to_hedge[std::make_pair(prev_index,f_indices[(i+1)%3])] = - it_fb->second.halfedges[i]; - } - } - - //insert point inside face - for(Node_id node_id : node_ids) - { - CDT_Vertex_handle vh=cdt.insert(nodes.exact_node(node_id)); - vh->info()=node_id; - id_to_CDT_vh.insert(std::make_pair(node_id,vh)); - } - - std::vector > constrained_edges; - - // insert constraints that are interior to the triangle (in the case - // no edges are collinear in the meshes) - insert_constrained_edges(node_ids,cdt,id_to_CDT_vh,constrained_edges); - - // insert constraints between points that are on the boundary - // (not a contrained on the triangle boundary) - if (it_fb!=face_boundaries.end()) //is f not a triangle ? - { - for (int i=0;i<3;++i) - { - Node_ids& ids=it_fb->second.node_ids_array[i]; - insert_constrained_edges(ids,cdt,id_to_CDT_vh,constrained_edges,1); - } - } - - //insert coplanar edges for endpoints of triangles - for (int i=0;i<3;++i){ - Node_id nindex=triangle_vertices[i]->info(); - if ( nindex < nb_nodes ) - insert_constrained_edges_coplanar_case(nindex,cdt,id_to_CDT_vh); - } - - //XSL_TAG_CPL_VERT - //collect edges incident to a point that is the intersection of two - // coplanar faces. This ensure that triangulations are compatible. - if (it_fb!=face_boundaries.end()) //is f not a triangle ? - { - for (typename CDT::Finite_vertices_iterator - vit=cdt.finite_vertices_begin(), - vit_end=cdt.finite_vertices_end();vit_end!=vit;++vit) - { - //skip original vertices (that are not nodes) and non-coplanar face - // issued vertices (this is working because intersection points - // between coplanar facets are the first inserted) - if (vit->info() >= nb_nodes || - vit->info() >= number_coplanar_vertices) continue; - // \todo no need to insert constrained edges (they also are constrained - // in the other mesh)!! - typename std::map< Node_id,std::set >::iterator res = - coplanar_constraints.insert( - std::make_pair(vit->info(),std::set())).first; - //turn around the vertex and get incident edge - typename CDT::Edge_circulator start=cdt.incident_edges(vit); - typename CDT::Edge_circulator curr=start; - do{ - if (cdt.is_infinite(*curr) ) continue; - typename CDT::Edge mirror=cdt.mirror_edge(*curr); - if ( cdt.is_infinite( curr->first->vertex(curr->second) ) || - cdt.is_infinite( mirror.first->vertex(mirror.second) ) ) - continue; // skip edges that are on the boundary of the triangle - // (these are already constrained) - //insert edges in the set of constraints - CDT_Vertex_handle vh=vit; - int nindex = curr->first->vertex((curr->second+1)%3)==vh - ? (curr->second+2)%3 - : (curr->second+1)%3; - CDT_Vertex_handle vn=curr->first->vertex(nindex); - if ( vit->info() > vn->info() || vn->info()>=nb_nodes) - continue; //take only one out of the two edges + skip input - CGAL_assertion(vn->info()second.insert( vn->info() ); - }while(start!=++curr); - } - } - - // import the triangle in `cdt` in the face `f` of `tm` - triangulate_a_face(f, tm, nodes, node_ids, node_id_to_vertex, - edge_to_hedge, cdt, vpm, output_builder, user_visitor); - - // TODO Here we do the update only for internal edges. - // Update for border halfedges could be done during the split - - //3) mark halfedges that are common to two polyhedral surfaces - //recover halfedges inserted that are on the intersection - typedef std::pair Node_id_pair; - for(const Node_id_pair& node_id_pair : constrained_edges) - { - typename std::map - ::iterator it_poly_hedge=edge_to_hedge.find(node_id_pair); - //we cannot have an assertion here in case an edge or part of an edge is a constraints. - //Indeed, the graph_of_constraints report an edge 0,1 and 1,0 for example while only one of the two - //is defined as one of them defines an adjacent face - //CGAL_assertion(it_poly_hedge!=edge_to_hedge.end()); - if( it_poly_hedge!=edge_to_hedge.end() ){ - call_put(marks_on_edges,tm,edge(it_poly_hedge->second,tm),true); - output_builder.set_edge_per_polyline(tm,node_id_pair,it_poly_hedge->second); - } - else{ - //WARNING: in few case this is needed if the marked edge is on the border - //to optimize it might be better to only use sorted pair. TAG_SLXX1 - Node_id_pair opposite_pair(node_id_pair.second,node_id_pair.first); - it_poly_hedge=edge_to_hedge.find(opposite_pair); - CGAL_assertion( it_poly_hedge!=edge_to_hedge.end() ); - - call_put(marks_on_edges,tm,edge(it_poly_hedge->second,tm),true); - output_builder.set_edge_per_polyline(tm,opposite_pair,it_poly_hedge->second); - } - } - } + if(it->first == tm1_ptr) + triangulate_intersected_faces(it, vpm1, nodes, mesh_to_face_boundaries); + else + triangulate_intersected_faces(it, vpm2, nodes, mesh_to_face_boundaries); } nodes.finalize(); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h index c188231238c..4103dcd41ae 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/face_graph_utils.h @@ -583,7 +583,8 @@ next_marked_halfedge_around_target_vertex( template void import_polyline( @@ -598,8 +599,8 @@ void import_polyline( VertexMap& pm1_to_output_vertices, const IntersectionEdgeMap& intersection_edges1, const IntersectionEdgeMap& intersection_edges2, - const VertexPointMap& vpm1, - const VertexPointMap& /*vpm2*/, + const VertexPointMap1& vpm1, + const VertexPointMap2& /*vpm2*/, const VertexPointMapOut& vpm_out, std::vector ::edge_descriptor>& output_shared_edges) @@ -1004,7 +1005,8 @@ void append_patches_to_triangle_mesh( template < class TriangleMesh, class IntersectionEdgeMap, - class VertexPointMap, + class VertexPointMap1, + class VertexPointMap2, class VertexPointMapOut, class EdgeMarkMap1, class EdgeMarkMap2, @@ -1024,8 +1026,8 @@ void fill_new_triangle_mesh( const IntersectionPolylines& polylines, const IntersectionEdgeMap& intersection_edges1, const IntersectionEdgeMap& intersection_edges2, - const VertexPointMap& vpm1, - const VertexPointMap& vpm2, + const VertexPointMap1& vpm1, + const VertexPointMap2& vpm2, const VertexPointMapOut& vpm_out, const EdgeMarkMap1& edge_mark_map1, const EdgeMarkMap2& edge_mark_map2, @@ -1261,7 +1263,8 @@ template +template std::tuple::halfedge_descriptor, bool,bool> @@ -87,23 +87,26 @@ intersection_type( typename boost::graph_traits::face_descriptor f_2, const TriangleMesh& tm1, const TriangleMesh& tm2, - const VertexPointMap& vpm1, - const VertexPointMap& vpm2) + const VertexPointMap1& vpm1, + const VertexPointMap2& vpm2) { typedef boost::graph_traits GT; typedef typename GT::halfedge_descriptor halfedge_descriptor; typedef std::tuple result_type; - typedef typename boost::property_traits::reference Point_ref; - typedef typename boost::property_traits::value_type Point_3; + typedef typename boost::property_traits::reference Point_ref1; + typedef typename boost::property_traits::reference Point_ref2; + typedef typename boost::property_traits::value_type Point_3; typedef typename Kernel_traits::Kernel Kernel; + CGAL_static_assertion((std::is_same::value_type>::value)); + halfedge_descriptor h_2=halfedge(f_2,tm2); - Point_ref a = get(vpm2, target(h_2,tm2) ); - Point_ref b = get(vpm2, target(next(h_2,tm2),tm2) ); - Point_ref c = get(vpm2, source(h_2,tm2) ); - Point_ref p = get(vpm1, source(h_1,tm1) ); - Point_ref q = get(vpm1, target(h_1,tm1) ); + Point_ref2 a = get(vpm2, target(h_2,tm2) ); + Point_ref2 b = get(vpm2, target(next(h_2,tm2),tm2) ); + Point_ref2 c = get(vpm2, source(h_2,tm2) ); + Point_ref1 p = get(vpm1, source(h_1,tm1) ); + Point_ref1 q = get(vpm1, target(h_1,tm1) ); const Orientation abcp = orientation(a,b,c,p); const Orientation abcq = orientation(a,b,c,q); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_callbacks.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_callbacks.h index d5389e9f482..d7db498ae8c 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_callbacks.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_callbacks.h @@ -67,15 +67,15 @@ public: }; template class Collect_face_bbox_per_edge_bbox_with_coplanar_handling { protected: const TriangleMesh& tm_faces; const TriangleMesh& tm_edges; - const VertexPointMap& vpmap_tmf; - const VertexPointMap& vpmap_tme; + const VertexPointMapF& vpmap_tmf; + const VertexPointMapE& vpmap_tme; EdgeToFaces& edge_to_faces; CoplanarFaceSet& coplanar_faces; @@ -83,7 +83,7 @@ protected: typedef typename Graph_traits::face_descriptor face_descriptor; typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor; - typedef typename boost::property_traits::reference Point; + typedef typename boost::property_traits::reference Point; typedef CGAL::Box_intersection_d::ID_FROM_BOX_ADDRESS Box_policy; typedef CGAL::Box_intersection_d::Box_with_info_d Box; @@ -92,8 +92,8 @@ public: Collect_face_bbox_per_edge_bbox_with_coplanar_handling( const TriangleMesh& tm_faces, const TriangleMesh& tm_edges, - const VertexPointMap& vpmap_tmf, - const VertexPointMap& vpmap_tme, + const VertexPointMapF& vpmap_tmf, + const VertexPointMapE& vpmap_tme, EdgeToFaces& edge_to_faces, CoplanarFaceSet& coplanar_faces) : tm_faces(tm_faces) diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_impl.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_impl.h index 72c94c605d7..ab840fe75ec 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_impl.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_impl.h @@ -83,10 +83,10 @@ struct Default_surface_intersection_visitor{ void start_new_polyline(std::size_t,std::size_t){} void add_node_to_polyline(std::size_t){} void input_have_coplanar_faces(){} - template + template void finalize(T&, const TriangleMesh&, const TriangleMesh&, - const VertexPointMap&, const VertexPointMap&) + const VPM1, const VPM2) {} void new_node_added_triple_face(std::size_t /* node_id */, face_descriptor /* f1 */, @@ -144,7 +144,7 @@ struct Node_id_set { }; template< class TriangleMesh, - class VertexPointMap, + class VertexPointMap1, class VertexPointMap2, class Node_visitor=Default_surface_intersection_visitor > class Intersection_of_triangle_meshes @@ -175,7 +175,7 @@ class Intersection_of_triangle_meshes // may contain several segments. typedef std::map< Face_pair_and_int, Node_id_set > Faces_to_nodes_map; typedef Intersection_nodes Node_vector; // data members @@ -188,11 +188,13 @@ class Intersection_of_triangle_meshes Faces_to_nodes_map f_to_node; //Associate a pair of triangles to their intersection points std::vector extra_terminal_nodes; //used only for autorefinement CGAL_assertion_code(bool doing_autorefinement;) + // member functions + template void filter_intersections(const TriangleMesh& tm_f, const TriangleMesh& tm_e, - const VertexPointMap& vpm_f, - const VertexPointMap& vpm_e, + const VPMF& vpm_f, + const VPME& vpm_e, bool throw_on_self_intersection) { std::vector face_boxes, edge_boxes; @@ -237,7 +239,7 @@ class Intersection_of_triangle_meshes Callback callback(tm_f, tm_e, edge_to_faces); #else typedef Collect_face_bbox_per_edge_bbox_with_coplanar_handling< - TriangleMesh, VertexPointMap, Edge_to_faces, Coplanar_face_set> + TriangleMesh, VPMF, VPME, Edge_to_faces, Coplanar_face_set> Callback; Callback callback(tm_f, tm_e, vpm_f, vpm_e, edge_to_faces, coplanar_faces); #endif @@ -258,8 +260,9 @@ class Intersection_of_triangle_meshes } // for autorefinement + template void filter_intersections(const TriangleMesh& tm, - const VertexPointMap& vpm) + const VPM& vpm) { std::vector face_boxes, edge_boxes; std::vector face_boxes_ptr, edge_boxes_ptr; @@ -296,7 +299,7 @@ class Intersection_of_triangle_meshes Edge_to_faces& edge_to_faces = stm_edge_to_ltm_faces; typedef Collect_face_bbox_per_edge_bbox_with_coplanar_handling_one_mesh< - TriangleMesh, VertexPointMap, Edge_to_faces, Coplanar_face_set> + TriangleMesh, VPM, Edge_to_faces, Coplanar_face_set> Callback; Callback callback(tm, vpm, edge_to_faces, coplanar_faces); @@ -527,12 +530,12 @@ class Intersection_of_triangle_meshes } } - void compute_intersection_of_coplanar_faces( - Node_id& current_node, - const TriangleMesh& tm1, - const TriangleMesh& tm2, - const VertexPointMap& vpm1, - const VertexPointMap& vpm2) + template + void compute_intersection_of_coplanar_faces(Node_id& current_node, + const TriangleMesh& tm1, + const TriangleMesh& tm2, + const VPM1& vpm1, + const VPM2& vpm2) { CGAL_assertion( &tm1 < &tm2 || &tm1==&tm2 ); @@ -637,12 +640,13 @@ class Intersection_of_triangle_meshes //add a new node in the final graph. //it is the intersection of the triangle with the segment + template void add_new_node(halfedge_descriptor h_1, face_descriptor f_2, const TriangleMesh& tm1, const TriangleMesh& tm2, - const VertexPointMap& vpm1, - const VertexPointMap& vpm2, + const VPM1& vpm1, + const VPM2& vpm2, std::tuple inter_res) @@ -657,11 +661,12 @@ class Intersection_of_triangle_meshes } } + template void compute_intersection_points(Edge_to_faces& tm1_edge_to_tm2_faces, const TriangleMesh& tm1, const TriangleMesh& tm2, - const VertexPointMap& vpm1, - const VertexPointMap& vpm2, + const VPM1& vpm1, + const VPM2& vpm2, Node_id& current_node) { typedef std::tuple Inter_type; @@ -821,8 +826,9 @@ class Intersection_of_triangle_meshes } }; + template void detect_intersections_in_the_graph(const TriangleMesh& tm, - const VertexPointMap& vpm, + const VPM& vpm, Node_id& current_node) { boost::unordered_map void construct_polylines(Output_iterator out){ - typedef typename boost::property_traits::value_type Point_3; + typedef typename boost::property_traits::value_type Point_3; std::size_t nb_nodes=nodes.size(); std::vector graph(nb_nodes); //counts the number of time each node has been seen @@ -1262,8 +1268,8 @@ class Intersection_of_triangle_meshes public: Intersection_of_triangle_meshes(const TriangleMesh& tm1, const TriangleMesh& tm2, - const VertexPointMap& vpm1, - const VertexPointMap& vpm2, + const VertexPointMap1& vpm1, + const VertexPointMap2& vpm2, const Node_visitor& v=Node_visitor()) : nodes(tm1, tm2, vpm1, vpm2) , visitor(v) @@ -1275,7 +1281,7 @@ public: // for autorefinement Intersection_of_triangle_meshes(const TriangleMesh& tm, - const VertexPointMap& vpm, + const VertexPointMap1& vpm, const Node_visitor& v=Node_visitor()) : nodes(tm, tm, vpm, vpm) , visitor(v) @@ -1293,8 +1299,8 @@ public: const TriangleMesh& tm1=nodes.tm1; const TriangleMesh& tm2=nodes.tm2; - const VertexPointMap& vpm1=nodes.vpm1; - const VertexPointMap& vpm2=nodes.vpm2; + const VertexPointMap1& vpm1=nodes.vpm1; + const VertexPointMap2& vpm2=nodes.vpm2; filter_intersections(tm1, tm2, vpm1, vpm2, throw_on_self_intersection); filter_intersections(tm2, tm1, vpm2, vpm1, throw_on_self_intersection); @@ -1308,6 +1314,7 @@ public: compute_intersection_of_coplanar_faces(current_node, tm1, tm2, vpm1, vpm2); else compute_intersection_of_coplanar_faces(current_node, tm2, tm1, vpm2, vpm1); + visitor.set_number_of_intersection_points_from_coplanar_faces(current_node+1); if (!coplanar_faces.empty()) visitor.input_have_coplanar_faces(); @@ -1324,6 +1331,7 @@ public: compute_intersection_points(tm1_edge_to_tm2_faces, tm1, tm2, vpm1, vpm2, current_node); compute_intersection_points(tm2_edge_to_tm1_faces, tm2, tm1, vpm2, vpm1, current_node); + if (!build_polylines){ visitor.finalize(nodes,tm1,tm2,vpm1,vpm2); return output; @@ -1361,7 +1369,7 @@ public: CGAL_assertion(doing_autorefinement); const TriangleMesh& tm=nodes.tm1; - const VertexPointMap& vpm=nodes.vpm1; + const VertexPointMap1& vpm=nodes.vpm1; filter_intersections(tm, vpm); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_nodes.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_nodes.h index 9d43f9cc043..99ff0a7815f 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_nodes.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_nodes.h @@ -28,23 +28,26 @@ namespace Corefinement { // polylines. Different specializations are available depending whether // predicates on constructions are needed. template ::value_type + typename boost::property_traits::value_type >::Kernel::FT >::value > class Intersection_nodes; //Store only the double version of the intersection points. template -class Intersection_nodes + class VertexPointMap1, class VertexPointMap2> +class Intersection_nodes { //typedefs - typedef typename boost::property_traits::value_type Point_3; + typedef typename boost::property_traits::value_type Point_3; + CGAL_static_assertion((std::is_same::value_type, + typename boost::property_traits::value_type>::value)); + typedef typename Kernel_traits::Kernel Input_kernel; typedef std::vector Nodes_vector; typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_kernel; @@ -67,12 +70,13 @@ class Intersection_nodes public: const TriangleMesh &tm1, &tm2; - VertexPointMap vpm1, vpm2; + const VertexPointMap1& vpm1; + const VertexPointMap2& vpm2; Intersection_nodes(const TriangleMesh& tm1_, const TriangleMesh& tm2_, - const VertexPointMap& vpm1_, - const VertexPointMap& vpm2_) + const VertexPointMap1& vpm1_, + const VertexPointMap2& vpm2_) : tm1(tm1_) , tm2(tm2_) , vpm1(vpm1_) @@ -97,12 +101,13 @@ public: //add a new node in the final graph. //it is the intersection of the triangle with the segment + template // VertexPointMap1 or VertexPointMap2 void add_new_node(halfedge_descriptor h_a, face_descriptor f_b, const TriangleMesh& tm_a, const TriangleMesh& tm_b, - const VertexPointMap vpm_a, - const VertexPointMap& vpm_b) + const VPM_A& vpm_a, + const VPM_B& vpm_b) { halfedge_descriptor h_b = halfedge(f_b, tm_b); add_new_node( @@ -114,12 +119,8 @@ public: to_exact( get(vpm_a, target(h_a,tm_a)) ) ) ); } - void add_new_node(halfedge_descriptor edge_1, face_descriptor face_2) - { - add_new_node(edge_1, face_2, tm1, tm2, vpm1, vpm2); - } - - void call_put(const VertexPointMap& vpm, vertex_descriptor vd, std::size_t i, TriangleMesh&) + template // VertexPointMap1 or VertexPointMap2 + void call_put(const VPM& vpm, vertex_descriptor vd, std::size_t i, TriangleMesh&) { put(vpm, vd, nodes[i]); } @@ -132,14 +133,18 @@ public: // second specializations: store an exact copy of the points so // that we can answer exactly predicates -template -class Intersection_nodes +template +class Intersection_nodes { //typedefs public: typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_kernel; + private: - typedef typename boost::property_traits::value_type Point_3; + typedef typename boost::property_traits::value_type Point_3; + CGAL_static_assertion((std::is_same::value_type, + typename boost::property_traits::value_type>::value)); + typedef typename Kernel_traits::Kernel Input_kernel; typedef Cartesian_converter Double_to_exact; @@ -160,14 +165,16 @@ private: Exact_kernel::Intersect_3 exact_intersection; std::vector tm1_vertices, tm2_vertices; const bool doing_autorefinement; + public: const TriangleMesh &tm1, &tm2; - VertexPointMap vpm1, vpm2; + const VertexPointMap1& vpm1; + const VertexPointMap2& vpm2; Intersection_nodes(const TriangleMesh& tm1_, const TriangleMesh& tm2_, - const VertexPointMap& vpm1_, - const VertexPointMap& vpm2_) + const VertexPointMap1& vpm1_, + const VertexPointMap2& vpm2_) : doing_autorefinement(&tm1_ == &tm2_) , tm1(tm1_) , tm2(tm2_) @@ -211,12 +218,13 @@ public: //add a new node in the final graph. //it is the intersection of the triangle with the segment + template // VertexPointMap1 or VertexPointMap2 void add_new_node(halfedge_descriptor h_a, face_descriptor f_b, const TriangleMesh& tm_a, const TriangleMesh& tm_b, - const VertexPointMap vpm_a, - const VertexPointMap& vpm_b) + const VPM_A vpm_a, + const VPM_B vpm_b) { halfedge_descriptor h_b = halfedge(f_b, tm_b); add_new_node( @@ -229,11 +237,12 @@ public: } // use to resolve intersection of 3 faces in autorefinement only + template void add_new_node(halfedge_descriptor h1, halfedge_descriptor h2, halfedge_descriptor h3, const TriangleMesh& tm, - const VertexPointMap& vpm) + const VPM& vpm) { // TODO Far from optimal! typedef Exact_kernel::Plane_3 Plane_3; @@ -257,11 +266,6 @@ public: add_new_node(*pt); } - void add_new_node(halfedge_descriptor edge_1, face_descriptor face_2) - { - add_new_node(edge_1, face_2, tm1, tm2, vpm1, vpm2); - } - //the point is an input void add_new_node(const Point_3& p){ enodes.push_back(to_exact(p)); @@ -273,7 +277,8 @@ public: tm2_vertices.resize(enodes.size(), GT::null_vertex()); } - void call_put(const VertexPointMap& vpm, vertex_descriptor vd, std::size_t i, TriangleMesh& tm) + template // VertexPointMap1 or VertexPointMap2 + void call_put(const VPM& vpm, vertex_descriptor vd, std::size_t i, TriangleMesh& tm) { put(vpm, vd, exact_to_double(enodes[i])); if (&tm1==&tm) @@ -306,11 +311,16 @@ public: //Third specialization: The kernel already has exact constructions. -template -class Intersection_nodes +template +class Intersection_nodes { //typedefs - typedef typename boost::property_traits::value_type Point_3; + typedef typename boost::property_traits::value_type Point_3; + CGAL_static_assertion((std::is_same::value_type, + typename boost::property_traits::value_type>::value)); + typedef typename Kernel_traits::Kernel Input_kernel; typedef std::vector Nodes_vector; @@ -326,12 +336,13 @@ public: typedef Input_kernel Exact_kernel; const TriangleMesh &tm1, &tm2; - VertexPointMap vpm1, vpm2; + const VertexPointMap1& vpm1; + const VertexPointMap2& vpm2; Intersection_nodes(const TriangleMesh& tm1_, const TriangleMesh& tm2_, - const VertexPointMap& vpm1_, - const VertexPointMap& vpm2_) + const VertexPointMap1& vpm1_, + const VertexPointMap2& vpm2_) : tm1(tm1_) , tm2(tm2_) , vpm1(vpm1_) @@ -346,11 +357,12 @@ public: size_t size() const {return nodes.size();} const Point_3& exact_node(std::size_t i) const {return nodes[i];} + template void add_new_node(halfedge_descriptor h1, halfedge_descriptor h2, halfedge_descriptor h3, const TriangleMesh& tm, - const VertexPointMap& vpm) + const VPM& vpm) { // TODO Far from optimal! typedef typename Exact_kernel::Plane_3 Plane_3; @@ -376,12 +388,13 @@ public: //add a new node in the final graph. //it is the intersection of the triangle with the segment + template // VertexPointMap1 or VertexPointMap2 void add_new_node(halfedge_descriptor h_a, face_descriptor f_b, const TriangleMesh& tm_a, const TriangleMesh& tm_b, - const VertexPointMap vpm_a, - const VertexPointMap& vpm_b) + const VPM_A& vpm_a, + const VPM_B& vpm_b) { halfedge_descriptor h_b=halfedge(f_b,tm_b); @@ -394,12 +407,6 @@ public: get(vpm_a, target(h_a,tm_a)) ) ); } - void add_new_node(halfedge_descriptor edge_1, face_descriptor face_2) - { - add_new_node(edge_1, face_2, tm1, tm2, vpm1, vpm2); - } - - void add_new_node(const Point_3& p) { nodes.push_back(p); @@ -407,7 +414,8 @@ public: const Point_3& to_exact(const Point_3& p) const { return p; } - void call_put(const VertexPointMap& vpm, vertex_descriptor vd, std::size_t i, TriangleMesh&) + template // VertexPointMap1 or VertexPointMap2 + void call_put(const VPM& vpm, vertex_descriptor vd, std::size_t i, TriangleMesh&) { put(vpm, vd, nodes[i]); } diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_of_coplanar_triangles_3.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_of_coplanar_triangles_3.h index d4645badd45..3c4efee0abb 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_of_coplanar_triangles_3.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/intersection_of_coplanar_triangles_3.h @@ -27,10 +27,15 @@ namespace CGAL{ namespace Polygon_mesh_processing { namespace Corefinement{ -template -struct Intersect_coplanar_faces_3{ +template +struct Intersect_coplanar_faces_3 +{ // typedefs - typedef typename boost::property_traits::value_type Point; + typedef typename boost::property_traits::value_type Point; + + CGAL_static_assertion((std::is_same::value_type, + typename boost::property_traits::value_type>::value)); + typedef typename CGAL::Kernel_traits::Kernel Input_kernel; typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_kernel; @@ -40,12 +45,14 @@ struct Intersect_coplanar_faces_3{ typedef Coplanar_intersection Inter_pt_info; // data members const TriangleMesh &tm1, &tm2; - const VertexPointMap &vpm1, &vpm2; + const VertexPointMap1& vpm1; + const VertexPointMap2& vpm2; + // constructor Intersect_coplanar_faces_3(const TriangleMesh& tm1_, const TriangleMesh& tm2_, - const VertexPointMap& vpm1_, - const VertexPointMap& vpm2_) + const VertexPointMap1& vpm1_, + const VertexPointMap2& vpm2_) : tm1(tm1_), tm2(tm2_), vpm1(vpm1_), vpm2(vpm2_) {} @@ -282,14 +289,14 @@ struct Intersect_coplanar_faces_3{ } }; -template +template void intersection_coplanar_faces( typename boost::graph_traits::face_descriptor f1, typename boost::graph_traits::face_descriptor f2, const TriangleMesh& tm1, const TriangleMesh& tm2, - const VertexPointMap& vpm1, - const VertexPointMap& vpm2, + const VertexPointMap1& vpm1, + const VertexPointMap2& vpm2, std::list< Coplanar_intersection >& inter_pts) { typedef boost::graph_traits GT; @@ -297,7 +304,7 @@ void intersection_coplanar_faces( halfedge_descriptor h1=halfedge(f1,tm1), h2=halfedge(f2,tm2); - Intersect_coplanar_faces_3 + Intersect_coplanar_faces_3 intersect_cpln(tm1, tm2, vpm1, vpm2); // We will add in `inter_pts` the initial triangle of h1 diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/predicates.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/predicates.h index a296e8de90a..4b25b21e472 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/predicates.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/predicates.h @@ -122,15 +122,15 @@ bool are_triangles_coplanar_same_side( } -template +template bool are_triangles_coplanar_same_side(Node_id o_prime_index, Node_id o_index, Node_id p_index, Node_id q_index, vertex_descriptor p, vertex_descriptor q, - const Vpm& vpm_p, - const Vpm& vpm_q, + const VPMP& vpm_p, + const VPMQ& vpm_q, const Node_vector& nodes) { const Node_id NID((std::numeric_limits::max)()); @@ -142,7 +142,7 @@ bool are_triangles_coplanar_same_side(Node_id o_prime_index, ); } -template +template bool sorted_around_edge( Node_id o_prime_index, Node_id o_index, Node_id p1_index, @@ -151,8 +151,8 @@ bool sorted_around_edge( Node_id o_prime_index, vertex_descriptor p1, vertex_descriptor p2, vertex_descriptor q, - const Vpm& vpm_p, - const Vpm& vpm_q, + const VPMP& vpm_p, + const VPMQ& vpm_q, const Node_vector& nodes) { const Node_id NID((std::numeric_limits::max)()); diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h index 11e0708e07e..60877681330 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/intersection.h @@ -1758,21 +1758,18 @@ surface_intersection(const TriangleMesh& tm1, const bool throw_on_self_intersection = parameters::choose_parameter(parameters::get_parameter(np1, internal_np::throw_on_self_intersection), false); - typedef typename GetVertexPointMap::const_type Vpm; - typedef typename GetVertexPointMap::const_type Vpm2; - CGAL_USE_TYPE(Vpm2); - CGAL_assertion_code( - static const bool same_vpm = (boost::is_same::value);) - CGAL_static_assertion(same_vpm); + typedef typename GetVertexPointMap::const_type VPM1; + typedef typename GetVertexPointMap::const_type VPM2; - Vpm vpm1 = parameters::choose_parameter(parameters::get_parameter(np1, internal_np::vertex_point), - get_const_property_map(CGAL::vertex_point, tm1)); - Vpm vpm2 = parameters::choose_parameter(parameters::get_parameter(np2, internal_np::vertex_point), - get_const_property_map(CGAL::vertex_point, tm2)); + CGAL_static_assertion((std::is_same::value_type, + typename boost::property_traits::value_type>::value)); - Corefinement::Intersection_of_triangle_meshes + VPM1 vpm1 = parameters::choose_parameter(parameters::get_parameter(np1, internal_np::vertex_point), + get_const_property_map(CGAL::vertex_point, tm1)); + VPM2 vpm2 = parameters::choose_parameter(parameters::get_parameter(np2, internal_np::vertex_point), + get_const_property_map(CGAL::vertex_point, tm2)); + + Corefinement::Intersection_of_triangle_meshes functor(tm1, tm2, vpm1, vpm2); return functor(polyline_output, throw_on_self_intersection, true); } @@ -1814,17 +1811,14 @@ surface_self_intersection(const TriangleMesh& tm, const NamedParameters& np) { // Vertex point maps - typedef typename GetVertexPointMap::const_type Vpm; + typedef typename GetVertexPointMap::const_type VPM; - Vpm vpm = parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_point), - get_const_property_map(CGAL::vertex_point, tm)); + VPM vpm = parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_point), + get_const_property_map(CGAL::vertex_point, tm)); // surface intersection algorithm call - typedef Corefinement::Default_surface_intersection_visitor Visitor; - Corefinement::Intersection_of_triangle_meshes - functor(tm, vpm); + typedef Corefinement::Default_surface_intersection_visitor Visitor; + Corefinement::Intersection_of_triangle_meshes functor(tm, vpm); polyline_output=functor(polyline_output, true); return polyline_output;