Merge pull request #4712 from MaelRL/PMP-Clip_with_self_intersections-GF

PMP: Generalize some corefinement code
This commit is contained in:
Laurent Rineau 2020-10-09 17:10:50 +02:00
commit d075ef4fb3
14 changed files with 625 additions and 572 deletions

View File

@ -83,10 +83,10 @@ int main(int argc, char* argv[])
} }
Exact_point_map mesh1_exact_points = Exact_point_map mesh1_exact_points =
mesh1.add_property_map<vertex_descriptor,EK::Point_3>("e:exact_point").first; mesh1.add_property_map<vertex_descriptor,EK::Point_3>("v:exact_point").first;
Exact_point_map mesh2_exact_points = Exact_point_map mesh2_exact_points =
mesh2.add_property_map<vertex_descriptor,EK::Point_3>("e:exact_point").first; mesh2.add_property_map<vertex_descriptor,EK::Point_3>("v:exact_point").first;
Exact_vertex_point_map mesh1_vpm(mesh1_exact_points, mesh1); Exact_vertex_point_map mesh1_vpm(mesh1_exact_points, mesh1);
Exact_vertex_point_map mesh2_vpm(mesh2_exact_points, mesh2); Exact_vertex_point_map mesh2_vpm(mesh2_exact_points, mesh2);

View File

@ -33,7 +33,14 @@
#include <boost/property_map/property_map.hpp> #include <boost/property_map/property_map.hpp>
#include <array>
#include <algorithm>
#include <map>
#include <set>
#include <type_traits>
#include <unordered_map> #include <unordered_map>
#include <utility>
#include <vector>
namespace CGAL{ namespace CGAL{
namespace Polygon_mesh_processing { namespace Polygon_mesh_processing {
@ -420,10 +427,9 @@ generic_clip_impl(
NamedParameters1>::type Vpm; NamedParameters1>::type Vpm;
typedef typename GetVertexPointMap<TriangleMesh, typedef typename GetVertexPointMap<TriangleMesh,
NamedParameters2>::type Vpm2; NamedParameters2>::type Vpm2;
CGAL_USE_TYPE(Vpm2);
CGAL_assertion_code( CGAL_static_assertion((std::is_same<typename boost::property_traits<Vpm>::value_type,
static const bool same_vpm = (boost::is_same<Vpm,Vpm2>::value); ) typename boost::property_traits<Vpm>::value_type>::value));
CGAL_static_assertion(same_vpm);
Vpm vpm1 = choose_parameter(get_parameter(np1, internal_np::vertex_point), Vpm vpm1 = choose_parameter(get_parameter(np1, internal_np::vertex_point),
get_property_map(boost::vertex_point, tm1)); get_property_map(boost::vertex_point, tm1));
@ -477,17 +483,17 @@ generic_clip_impl(
// surface intersection algorithm call // surface intersection algorithm call
typedef Corefinement::Generic_clip_output_builder<TriangleMesh, typedef Corefinement::Generic_clip_output_builder<TriangleMesh,
Vpm, Vpm, Vpm2,
Algo_ecm1, Algo_ecm1,
FaceIndexMap1, FaceIndexMap1,
Default> Ob; Default> Ob;
typedef Corefinement::Surface_intersection_visitor_for_corefinement< 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); Ecm_in ecm_in(tm1,tm2,ecm1,ecm2);
Ob ob(tm1, tm2, vpm1, vpm2, algo_ecm1, fid_map1, use_compact_clipper); Ob ob(tm1, tm2, vpm1, vpm2, algo_ecm1, fid_map1, use_compact_clipper);
Corefinement::Intersection_of_triangle_meshes<TriangleMesh, Vpm, Algo_visitor > Corefinement::Intersection_of_triangle_meshes<TriangleMesh, Vpm, Vpm2, Algo_visitor >
functor(tm1, tm2, vpm1, vpm2, Algo_visitor(uv,ob,ecm_in,&tm2)); functor(tm1, tm2, vpm1, vpm2, Algo_visitor(uv,ob,ecm_in,&tm2));
functor(CGAL::Emptyset_iterator(), false, true); functor(CGAL::Emptyset_iterator(), false, true);
} }

View File

@ -201,22 +201,19 @@ corefine_and_compute_boolean_operations(
// Vertex point maps // Vertex point maps
//for input meshes //for input meshes
typedef typename GetVertexPointMap<TriangleMesh, typedef typename GetVertexPointMap<TriangleMesh, NamedParameters1>::type VPM1;
NamedParameters1>::type Vpm; typedef typename GetVertexPointMap<TriangleMesh, NamedParameters2>::type VPM2;
typedef typename GetVertexPointMap<TriangleMesh,
NamedParameters2>::type Vpm2;
CGAL_USE_TYPE(Vpm2);
CGAL_assertion_code(
static const bool same_vpm = (boost::is_same<Vpm,Vpm2>::value); )
CGAL_static_assertion(same_vpm);
Vpm vpm1 = choose_parameter(get_parameter(np1, internal_np::vertex_point), CGAL_static_assertion((std::is_same<typename boost::property_traits<VPM1>::value_type,
typename boost::property_traits<VPM2>::value_type>::value));
VPM1 vpm1 = choose_parameter(get_parameter(np1, internal_np::vertex_point),
get_property_map(boost::vertex_point, tm1)); get_property_map(boost::vertex_point, tm1));
Vpm vpm2 = choose_parameter(get_parameter(np2, internal_np::vertex_point), VPM2 vpm2 = choose_parameter(get_parameter(np2, internal_np::vertex_point),
get_property_map(boost::vertex_point, tm2)); get_property_map(boost::vertex_point, tm2));
typedef typename boost::property_traits<Vpm>::value_type Point_3; typedef typename boost::property_traits<VPM1>::value_type Point_3;
// for output meshes: here we have to use a trick so that if for a specific output // 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 // 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<Point_3, NamedParametersOut1, TriangleMesh>, Corefinement::TweakedGetVertexPointMap<Point_3, NamedParametersOut1, TriangleMesh>,
Corefinement::TweakedGetVertexPointMap<Point_3, NamedParametersOut2, TriangleMesh>, Corefinement::TweakedGetVertexPointMap<Point_3, NamedParametersOut2, TriangleMesh>,
Corefinement::TweakedGetVertexPointMap<Point_3, NamedParametersOut3, TriangleMesh> Corefinement::TweakedGetVertexPointMap<Point_3, NamedParametersOut3, TriangleMesh>
> Vpm_out_tuple_helper; > VPM_out_tuple_helper;
typedef std::tuple< typedef std::tuple<
boost::optional< typename std::tuple_element<0, Vpm_out_tuple_helper>::type::type >, 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<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<2, VPM_out_tuple_helper>::type::type >,
boost::optional< typename std::tuple_element<3, 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 vpm_out_tuple(
Corefinement::get_vpm<Point_3>(std::get<0>(nps_out), output[0], Corefinement::get_vpm<Point_3>(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<Point_3>(std::get<1>(nps_out), output[1], Corefinement::get_vpm<Point_3>(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<Point_3>(std::get<2>(nps_out), output[2], Corefinement::get_vpm<Point_3>(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<Point_3>(std::get<3>(nps_out), output[3], Corefinement::get_vpm<Point_3>(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) if (&tm1==&tm2)
@ -375,8 +372,9 @@ corefine_and_compute_boolean_operations(
// surface intersection algorithm call // surface intersection algorithm call
typedef Corefinement::Face_graph_output_builder<TriangleMesh, typedef Corefinement::Face_graph_output_builder<TriangleMesh,
Vpm, VPM1,
Vpm_out_tuple, VPM2,
VPM_out_tuple,
FaceIndexMap1, FaceIndexMap1,
FaceIndexMap2, FaceIndexMap2,
Default, Default,
@ -385,7 +383,8 @@ corefine_and_compute_boolean_operations(
User_visitor> Ob; User_visitor> Ob;
typedef Corefinement::Surface_intersection_visitor_for_corefinement< 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); 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); 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); 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); ob.setup_for_clipping_a_surface(use_compact_clipper);
} }
Corefinement::Intersection_of_triangle_meshes<TriangleMesh, Vpm, Algo_visitor > Corefinement::Intersection_of_triangle_meshes<TriangleMesh, VPM1, VPM2, Algo_visitor >
functor(tm1, tm2, vpm1, vpm2, Algo_visitor(uv,ob,ecm_in)); functor(tm1, tm2, vpm1, vpm2, Algo_visitor(uv,ob,ecm_in));
functor(CGAL::Emptyset_iterator(), throw_on_self_intersection, true); functor(CGAL::Emptyset_iterator(), throw_on_self_intersection, true);
@ -735,19 +734,16 @@ corefine( TriangleMesh& tm1,
choose_parameter(get_parameter(np1, internal_np::throw_on_self_intersection), false); choose_parameter(get_parameter(np1, internal_np::throw_on_self_intersection), false);
// Vertex point maps // Vertex point maps
typedef typename GetVertexPointMap<TriangleMesh, typedef typename GetVertexPointMap<TriangleMesh, NamedParameters1>::type VPM1;
NamedParameters1>::type Vpm; typedef typename GetVertexPointMap<TriangleMesh, NamedParameters2>::type VPM2;
typedef typename GetVertexPointMap<TriangleMesh,
NamedParameters2>::type Vpm2;
CGAL_USE_TYPE(Vpm2);
CGAL_assertion_code(
static const bool same_vpm = (boost::is_same<Vpm,Vpm2>::value);)
CGAL_static_assertion(same_vpm);
Vpm vpm1 = choose_parameter(get_parameter(np1, internal_np::vertex_point), CGAL_static_assertion((std::is_same<typename boost::property_traits<VPM1>::value_type,
typename boost::property_traits<VPM2>::value_type>::value));
VPM1 vpm1 = choose_parameter(get_parameter(np1, internal_np::vertex_point),
get_property_map(boost::vertex_point, tm1)); get_property_map(boost::vertex_point, tm1));
Vpm vpm2 = choose_parameter(get_parameter(np2, internal_np::vertex_point), VPM2 vpm2 = choose_parameter(get_parameter(np2, internal_np::vertex_point),
get_property_map(boost::vertex_point, tm2)); get_property_map(boost::vertex_point, tm2));
// Edge is-constrained maps // Edge is-constrained maps
@ -786,10 +782,11 @@ corefine( TriangleMesh& tm1,
// surface intersection algorithm call // surface intersection algorithm call
typedef Corefinement::No_extra_output_from_corefinement<TriangleMesh> Ob; typedef Corefinement::No_extra_output_from_corefinement<TriangleMesh> Ob;
typedef Corefinement::Surface_intersection_visitor_for_corefinement< 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; Ob ob;
Ecm ecm(tm1,tm2,ecm1,ecm2); Ecm ecm(tm1,tm2,ecm1,ecm2);
Corefinement::Intersection_of_triangle_meshes<TriangleMesh, Vpm, Algo_visitor> Corefinement::Intersection_of_triangle_meshes<TriangleMesh, VPM1, VPM2, Algo_visitor>
functor(tm1, tm2, vpm1, vpm2, Algo_visitor(uv,ob,ecm,const_mesh_ptr)); functor(tm1, tm2, vpm1, vpm2, Algo_visitor(uv,ob,ecm,const_mesh_ptr));
functor(CGAL::Emptyset_iterator(), throw_on_self_intersection, true); functor(CGAL::Emptyset_iterator(), throw_on_self_intersection, true);
} }
@ -852,9 +849,9 @@ autorefine( TriangleMesh& tm,
using parameters::get_parameter; using parameters::get_parameter;
// Vertex point maps // Vertex point maps
typedef typename GetVertexPointMap<TriangleMesh, NamedParameters>::type Vpm; typedef typename GetVertexPointMap<TriangleMesh, NamedParameters>::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)); get_property_map(boost::vertex_point, tm));
// Edge is-constrained maps // Edge is-constrained maps
@ -877,10 +874,10 @@ autorefine( TriangleMesh& tm,
// surface intersection algorithm call // surface intersection algorithm call
typedef Corefinement::No_extra_output_from_corefinement<TriangleMesh> Ob; typedef Corefinement::No_extra_output_from_corefinement<TriangleMesh> Ob;
typedef Corefinement::Surface_intersection_visitor_for_corefinement< 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; Ob ob;
Corefinement::Intersection_of_triangle_meshes<TriangleMesh, Vpm, Algo_visitor> Corefinement::Intersection_of_triangle_meshes<TriangleMesh, VPM, VPM, Algo_visitor>
functor(tm, vpm, Algo_visitor(uv,ob,ecm) ); functor(tm, vpm, Algo_visitor(uv,ob,ecm) );
functor(CGAL::Emptyset_iterator(), true); functor(CGAL::Emptyset_iterator(), true);
@ -945,8 +942,8 @@ autorefine_and_remove_self_intersections( TriangleMesh& tm,
using parameters::get_parameter; using parameters::get_parameter;
// Vertex point maps // Vertex point maps
typedef typename GetVertexPointMap<TriangleMesh, NamedParameters>::type Vpm; typedef typename GetVertexPointMap<TriangleMesh, NamedParameters>::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)); get_property_map(boost::vertex_point, tm));
// Face index map // Face index map
@ -972,16 +969,16 @@ autorefine_and_remove_self_intersections( TriangleMesh& tm,
// surface intersection algorithm call // surface intersection algorithm call
typedef Corefinement::Output_builder_for_autorefinement<TriangleMesh, typedef Corefinement::Output_builder_for_autorefinement<TriangleMesh,
Vpm, VPM,
Fid_map, Fid_map,
Ecm, Ecm,
Default > Ob; Default > Ob;
typedef Corefinement::Surface_intersection_visitor_for_corefinement< 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); Ob ob(tm, vpm, fid_map, ecm);
Corefinement::Intersection_of_triangle_meshes<TriangleMesh, Vpm, Algo_visitor> Corefinement::Intersection_of_triangle_meshes<TriangleMesh, VPM, VPM, Algo_visitor>
functor(tm, vpm, Algo_visitor(uv,ob,ecm) ); functor(tm, vpm, Algo_visitor(uv,ob,ecm) );
functor(CGAL::Emptyset_iterator(), true); functor(CGAL::Emptyset_iterator(), true);

View File

@ -58,7 +58,8 @@ namespace PMP=Polygon_mesh_processing;
namespace params=PMP::parameters; namespace params=PMP::parameters;
template <class TriangleMesh, template <class TriangleMesh,
class VertexPointMap, class VertexPointMap1,
class VertexPointMap2,
class VpmOutTuple, class VpmOutTuple,
class FaceIdMap1, class FaceIdMap1,
class FaceIdMap2, class FaceIdMap2,
@ -72,8 +73,9 @@ class Face_graph_output_builder
typedef typename Default::Get< typedef typename Default::Get<
Kernel_, Kernel_,
typename Kernel_traits< typename Kernel_traits<
typename boost::property_traits<VertexPointMap>::value_type typename boost::property_traits<VertexPointMap1>::value_type
>::Kernel >::type Kernel; >::Kernel >::type Kernel;
typedef typename Default::Get<EdgeMarkMapBind_, typedef typename Default::Get<EdgeMarkMapBind_,
Ecm_bind<TriangleMesh, No_mark<TriangleMesh> > Ecm_bind<TriangleMesh, No_mark<TriangleMesh> >
>::type EdgeMarkMapBind; >::type EdgeMarkMapBind;
@ -111,8 +113,8 @@ class Face_graph_output_builder
//Data members //Data members
TriangleMesh &tm1, &tm2; TriangleMesh &tm1, &tm2;
// property maps of input meshes // property maps of input meshes
const VertexPointMap vpm1; const VertexPointMap1& vpm1;
const VertexPointMap vpm2; const VertexPointMap2& vpm2;
FaceIdMap1 fids1; FaceIdMap1 fids1;
FaceIdMap2 fids2; FaceIdMap2 fids2;
EdgeMarkMapBind& marks_on_input_edges; EdgeMarkMapBind& marks_on_input_edges;
@ -346,8 +348,8 @@ public:
Face_graph_output_builder(TriangleMesh& tm1, Face_graph_output_builder(TriangleMesh& tm1,
TriangleMesh& tm2, TriangleMesh& tm2,
const VertexPointMap vpm1, const VertexPointMap1& vpm1,
const VertexPointMap vpm2, const VertexPointMap2& vpm2,
FaceIdMap1 fids1, FaceIdMap1 fids1,
FaceIdMap2 fids2, FaceIdMap2 fids2,
EdgeMarkMapBind& marks_on_input_edges, EdgeMarkMapBind& marks_on_input_edges,
@ -1098,10 +1100,6 @@ public:
if (!is_tm2_closed) if (!is_tm2_closed)
patch_status_not_set_tm1.reset(); patch_status_not_set_tm1.reset();
typedef Side_of_triangle_mesh<TriangleMesh,
Kernel,
VertexPointMap> Inside_poly_test;
#ifdef CGAL_COREFINEMENT_POLYHEDRA_DEBUG #ifdef CGAL_COREFINEMENT_POLYHEDRA_DEBUG
#warning stop using next_marked_halfedge_around_target_vertex and create lists of halfedges instead? #warning stop using next_marked_halfedge_around_target_vertex and create lists of halfedges instead?
#endif #endif
@ -1111,7 +1109,7 @@ public:
CGAL::Bounded_side in_tm2 = is_tm2_inside_out CGAL::Bounded_side in_tm2 = is_tm2_inside_out
? ON_UNBOUNDED_SIDE : ON_BOUNDED_SIDE; ? ON_UNBOUNDED_SIDE : ON_BOUNDED_SIDE;
Inside_poly_test inside_tm2(tm2, vpm2); Side_of_triangle_mesh<TriangleMesh, Kernel, VertexPointMap2> inside_tm2(tm2, vpm2);
for(face_descriptor f : faces(tm1)) for(face_descriptor f : faces(tm1))
{ {
@ -1173,7 +1171,7 @@ public:
CGAL::Bounded_side in_tm1 = is_tm1_inside_out CGAL::Bounded_side in_tm1 = is_tm1_inside_out
? ON_UNBOUNDED_SIDE : ON_BOUNDED_SIDE; ? ON_UNBOUNDED_SIDE : ON_BOUNDED_SIDE;
Inside_poly_test inside_tm1(tm1, vpm1); Side_of_triangle_mesh<TriangleMesh, Kernel, VertexPointMap1> inside_tm1(tm1, vpm1);
for(face_descriptor f : faces(tm2)) for(face_descriptor f : faces(tm2))
{ {
const std::size_t f_id = get(fids2, f); const std::size_t f_id = get(fids2, f);

View File

@ -38,7 +38,8 @@ namespace PMP=Polygon_mesh_processing;
namespace params=PMP::parameters; namespace params=PMP::parameters;
template <class TriangleMesh, template <class TriangleMesh,
class VertexPointMap, class VertexPointMap1,
class VertexPointMap2,
class Ecm1, class Ecm1,
class FaceIdMap1, class FaceIdMap1,
class Kernel_=Default> class Kernel_=Default>
@ -48,7 +49,7 @@ class Generic_clip_output_builder
typedef typename Default::Get< typedef typename Default::Get<
Kernel_, Kernel_,
typename Kernel_traits< typename Kernel_traits<
typename boost::property_traits<VertexPointMap>::value_type typename boost::property_traits<VertexPointMap2>::value_type
>::Kernel >::type Kernel; >::Kernel >::type Kernel;
// graph_traits typedefs // graph_traits typedefs
@ -76,8 +77,8 @@ class Generic_clip_output_builder
//Data members //Data members
TriangleMesh &tm1, &tm2; TriangleMesh &tm1, &tm2;
// property maps of input meshes // property maps of input meshes
const VertexPointMap vpm1; const VertexPointMap1 vpm1;
const VertexPointMap vpm2; const VertexPointMap2 vpm2;
Ecm1 ecm1; Ecm1 ecm1;
FaceIdMap1 fids1; FaceIdMap1 fids1;
bool use_compact_clipper; bool use_compact_clipper;
@ -105,8 +106,8 @@ public:
Generic_clip_output_builder(TriangleMesh& tm1, Generic_clip_output_builder(TriangleMesh& tm1,
TriangleMesh& tm2, TriangleMesh& tm2,
const VertexPointMap vpm1, const VertexPointMap1 vpm1,
const VertexPointMap vpm2, const VertexPointMap2 vpm2,
const Ecm1& ecm1, const Ecm1& ecm1,
FaceIdMap1 fids1, FaceIdMap1 fids1,
bool use_compact_clipper) bool use_compact_clipper)
@ -167,7 +168,7 @@ public:
typedef Side_of_triangle_mesh<TriangleMesh, typedef Side_of_triangle_mesh<TriangleMesh,
Kernel, Kernel,
VertexPointMap> Inside_poly_test; VertexPointMap2> Inside_poly_test;
CGAL::Bounded_side in_tm2 = is_tm2_inside_out CGAL::Bounded_side in_tm2 = is_tm2_inside_out
? ON_UNBOUNDED_SIDE : ON_BOUNDED_SIDE; ? ON_UNBOUNDED_SIDE : ON_BOUNDED_SIDE;

View File

@ -102,7 +102,8 @@ struct No_extra_output_from_corefinement
// A visitor for Intersection_of_triangle_meshes that can be used to corefine // A visitor for Intersection_of_triangle_meshes that can be used to corefine
// two meshes // two meshes
template< class TriangleMesh, template< class TriangleMesh,
class VertexPointMap, class VertexPointMap1,
class VertexPointMap2,
class OutputBuilder_ = Default, class OutputBuilder_ = Default,
class EdgeMarkMapBind_ = Default, class EdgeMarkMapBind_ = Default,
class UserVisitor_ = Default, class UserVisitor_ = Default,
@ -141,8 +142,9 @@ private:
typedef boost::unordered_map<vertex_descriptor,Node_id> Vertex_to_node_id; typedef boost::unordered_map<vertex_descriptor,Node_id> Vertex_to_node_id;
typedef std::map<TriangleMesh*, Vertex_to_node_id> Mesh_to_vertex_to_node_id; typedef std::map<TriangleMesh*, Vertex_to_node_id> Mesh_to_vertex_to_node_id;
// typedef for the CDT // typedef for the CDT
typedef typename Intersection_nodes<TriangleMesh, typedef Intersection_nodes<TriangleMesh, VertexPointMap1, VertexPointMap2,
VertexPointMap, Predicates_on_constructions_needed>::Exact_kernel EK; Predicates_on_constructions_needed> INodes;
typedef typename INodes::Exact_kernel EK;
typedef Triangulation_2_projection_traits_3<EK> CDT_traits; typedef Triangulation_2_projection_traits_3<EK> CDT_traits;
typedef Triangulation_vertex_base_with_info_2<Node_id,CDT_traits> Vb; typedef Triangulation_vertex_base_with_info_2<Node_id,CDT_traits> Vb;
typedef Constrained_triangulation_face_base_2<CDT_traits> Fb; typedef Constrained_triangulation_face_base_2<CDT_traits> 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 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 //sort node ids so that we can split the hedge
//consecutively //consecutively
template <class Node_vector> template <class VPM, class Node_vector>
void sort_vertices_along_hedge(std::vector<std::size_t>& node_ids, void sort_vertices_along_hedge(std::vector<std::size_t>& node_ids,
halfedge_descriptor hedge, halfedge_descriptor hedge,
const TriangleMesh& tm, const TriangleMesh& tm,
const VertexPointMap& vpm, const VPM& vpm,
const Node_vector& nodes) const Node_vector& nodes)
{ {
std::sort(node_ids.begin(), std::sort(node_ids.begin(),
node_ids.end(), node_ids.end(),
Less_along_a_halfedge<TriangleMesh,VertexPointMap,Node_vector> Less_along_a_halfedge<TriangleMesh, VPM, Node_vector>
(hedge, tm, vpm, nodes) (hedge, tm, vpm, nodes)
); );
} }
@ -490,6 +493,8 @@ public:
}; };
typedef boost::unordered_map<face_descriptor,Face_boundary> Face_boundaries;
//update the id of input mesh vertex that are also a node //update the id of input mesh vertex that are also a node
void update_face_indices( void update_face_indices(
std::array<vertex_descriptor,3>& f_vertices, std::array<vertex_descriptor,3>& f_vertices,
@ -592,117 +597,15 @@ public:
return vh; return vh;
} }
void finalize(Intersection_nodes<TriangleMesh, template <class OnEdgeMapIterator, class VPM>
VertexPointMap, Predicates_on_constructions_needed>& nodes, void split_halfedges(OnEdgeMapIterator it,
const TriangleMesh& tm1, const VPM& vpm,
const TriangleMesh& tm2, INodes& nodes,
const VertexPointMap& vpm1, std::map<TriangleMesh*, Face_boundaries>& mesh_to_face_boundaries)
const VertexPointMap& vpm2)
{
nodes.all_nodes_created();
TriangleMesh* tm1_ptr = const_cast<TriangleMesh*>(&tm1);
TriangleMesh* tm2_ptr = const_cast<TriangleMesh*>(&tm2);
std::map<TriangleMesh*, VertexPointMap> 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
// face triangulation
mesh_to_node_id_to_vertex[tm1_ptr].resize(nb_nodes+3, null_vertex);
mesh_to_node_id_to_vertex[tm2_ptr].resize(nb_nodes+3, null_vertex);
//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_descriptor,Face_boundary> Face_boundaries;
std::map<TriangleMesh*,Face_boundaries> mesh_to_face_boundaries;
//0) For each triangle mesh, collect original vertices that belongs to the intersection.
// From the graph of constraints, extract intersection edges that are incident to such vertices. In case
// there exists another original vertex adjacent to the first one found, this halfedge must be
// marked on the boundary (and possibly update an_edge_per_polyline).
// This is done first to avoid halfedges stored to be modified in the steps following.
for (typename Mesh_to_vertices_on_intersection_map::iterator
it=mesh_to_vertices_on_inter.begin();
it!=mesh_to_vertices_on_inter.end();
++it)
{ {
TriangleMesh& tm=*it->first; TriangleMesh& tm=*it->first;
CGAL_assertion(&tm!=const_mesh_ptr); 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;
for(typename Node_to_target_of_hedge_map::iterator
it_node_2_hedge=nodes_to_hedge.begin();
it_node_2_hedge!=nodes_to_hedge.end();
++it_node_2_hedge)
{
Node_id node_id_of_first=it_node_2_hedge->first;
std::vector<Node_id>& neighbors=graph_of_constraints[node_id_of_first];
if ( !neighbors.empty() )
{
for(Node_id node_id : neighbors)
{
//if already done for the opposite
if (node_id >= node_id_of_first) continue;
typename Node_to_target_of_hedge_map::iterator
it_node_2_hedge_two = nodes_to_hedge.find(node_id);
if ( it_node_2_hedge_two!=nodes_to_hedge.end() ) //a full edge is on intersection
{
//get the corresponding halfedge with vertex corresponding to node_id_of_first
halfedge_descriptor hedge=it_node_2_hedge->second;
halfedge_descriptor start=hedge;
bool did_break=false;
while ( source(hedge,tm) !=
target(it_node_2_hedge_two->second,tm) )
{
hedge=opposite(next(hedge,tm),tm);
if (tm1_ptr==tm2_ptr && hedge==start)
{
++it_node_2_hedge_two; // we are using a multimap and
// the halfedge we are looking for
// might be on another sheet
if (it_node_2_hedge_two==nodes_to_hedge.end() ||
node_id!=it_node_2_hedge_two->first)
{
did_break=true;
break;
}
CGAL_assertion(it_node_2_hedge_two!=nodes_to_hedge.end());
CGAL_assertion(it_node_2_hedge->first==node_id_of_first);
}
else
{
CGAL_assertion(hedge!=start);
}
}
if (did_break) continue;
std::pair<Node_id,Node_id> edge_pair(node_id,node_id_of_first);
call_put(marks_on_edges,tm,edge(hedge,tm),true);
output_builder.set_edge_per_polyline(tm,edge_pair,hedge);
}
}
}
#ifdef CGAL_COREFINEMENT_DEBUG
else
{
std::cout << "X1: Found an isolated point" << std::endl;
}
#endif
}
}
//1) First split halfedges cut by the intersection polyline(s)
for (typename std::map<TriangleMesh*,On_edge_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_edge_map& on_edge_map=it->second;
On_face_map& on_face_map=on_face[&tm]; On_face_map& on_face_map=on_face[&tm];
Face_boundaries& face_boundaries=mesh_to_face_boundaries[&tm]; Face_boundaries& face_boundaries=mesh_to_face_boundaries[&tm];
@ -791,19 +694,22 @@ public:
} }
} }
//2)triangulation of the triangle faces containing intersection point in their interior template <class OnFaceMapIterator, class VPM>
// and also those with intersection points only on the boundary. void triangulate_intersected_faces(OnFaceMapIterator it,
for (typename std::map<TriangleMesh*,On_face_map>::iterator const VPM& vpm,
it=on_face.begin(); it!=on_face.end(); ++it) INodes& nodes,
std::map<TriangleMesh*, Face_boundaries>& mesh_to_face_boundaries)
{ {
TriangleMesh& tm=*it->first; TriangleMesh& tm=*it->first;
CGAL_assertion(&tm!=const_mesh_ptr); CGAL_assertion(&tm!=const_mesh_ptr);
const VertexPointMap& vpm=vpms[&tm];
On_face_map& on_face_map=it->second; On_face_map& on_face_map=it->second;
Face_boundaries& face_boundaries=mesh_to_face_boundaries[&tm]; Face_boundaries& face_boundaries=mesh_to_face_boundaries[&tm];
Node_id_to_vertex& node_id_to_vertex=mesh_to_node_id_to_vertex[&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]; 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(); for (typename On_face_map::iterator it=on_face_map.begin();
it!=on_face_map.end();++it) it!=on_face_map.end();++it)
{ {
@ -1040,6 +946,126 @@ public:
} }
} }
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<TriangleMesh*>(&tm1);
TriangleMesh* tm2_ptr = const_cast<TriangleMesh*>(&tm2);
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
// face triangulation
mesh_to_node_id_to_vertex[tm1_ptr].resize(nb_nodes+3, null_vertex);
mesh_to_node_id_to_vertex[tm2_ptr].resize(nb_nodes+3, null_vertex);
//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)
std::map<TriangleMesh*,Face_boundaries> mesh_to_face_boundaries;
//0) For each triangle mesh, collect original vertices that belongs to the intersection.
// From the graph of constraints, extract intersection edges that are incident to such vertices. In case
// there exists another original vertex adjacent to the first one found, this halfedge must be
// marked on the boundary (and possibly update an_edge_per_polyline).
// This is done first to avoid halfedges stored to be modified in the steps following.
for (typename Mesh_to_vertices_on_intersection_map::iterator
it=mesh_to_vertices_on_inter.begin();
it!=mesh_to_vertices_on_inter.end();
++it)
{
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;
for(typename Node_to_target_of_hedge_map::iterator
it_node_2_hedge=nodes_to_hedge.begin();
it_node_2_hedge!=nodes_to_hedge.end();
++it_node_2_hedge)
{
Node_id node_id_of_first=it_node_2_hedge->first;
std::vector<Node_id>& neighbors=graph_of_constraints[node_id_of_first];
if ( !neighbors.empty() )
{
for(Node_id node_id : neighbors)
{
//if already done for the opposite
if (node_id >= node_id_of_first) continue;
typename Node_to_target_of_hedge_map::iterator
it_node_2_hedge_two = nodes_to_hedge.find(node_id);
if ( it_node_2_hedge_two!=nodes_to_hedge.end() ) //a full edge is on intersection
{
//get the corresponding halfedge with vertex corresponding to node_id_of_first
halfedge_descriptor hedge=it_node_2_hedge->second;
halfedge_descriptor start=hedge;
bool did_break=false;
while ( source(hedge,tm) !=
target(it_node_2_hedge_two->second,tm) )
{
hedge=opposite(next(hedge,tm),tm);
if (tm1_ptr==tm2_ptr && hedge==start)
{
++it_node_2_hedge_two; // we are using a multimap and
// the halfedge we are looking for
// might be on another sheet
if (it_node_2_hedge_two==nodes_to_hedge.end() ||
node_id!=it_node_2_hedge_two->first)
{
did_break=true;
break;
}
CGAL_assertion(it_node_2_hedge_two!=nodes_to_hedge.end());
CGAL_assertion(it_node_2_hedge->first==node_id_of_first);
}
else
{
CGAL_assertion(hedge!=start);
}
}
if (did_break) continue;
std::pair<Node_id,Node_id> edge_pair(node_id,node_id_of_first);
call_put(marks_on_edges,tm,edge(hedge,tm),true);
output_builder.set_edge_per_polyline(tm,edge_pair,hedge);
}
}
}
#ifdef CGAL_COREFINEMENT_DEBUG
else
{
std::cout << "X1: Found an isolated point" << std::endl;
}
#endif
}
}
//1) First split halfedges cut by the intersection polyline(s)
for (typename std::map<TriangleMesh*,On_edge_map>::iterator
it=on_edge.begin(); it!=on_edge.end(); ++it)
{
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
// and also those with intersection points only on the boundary.
for (typename std::map<TriangleMesh*,On_face_map>::iterator
it=on_face.begin(); it!=on_face.end(); ++it)
{
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(); nodes.finalize();
// additional operations // additional operations

View File

@ -583,7 +583,8 @@ next_marked_halfedge_around_target_vertex(
template <class PolygonMesh, template <class PolygonMesh,
class EdgeMap, class EdgeMap,
class VertexMap, class VertexMap,
class VertexPointMap, class VertexPointMap1,
class VertexPointMap2,
class VertexPointMapOut, class VertexPointMapOut,
class IntersectionEdgeMap> class IntersectionEdgeMap>
void import_polyline( void import_polyline(
@ -598,8 +599,8 @@ void import_polyline(
VertexMap& pm1_to_output_vertices, VertexMap& pm1_to_output_vertices,
const IntersectionEdgeMap& intersection_edges1, const IntersectionEdgeMap& intersection_edges1,
const IntersectionEdgeMap& intersection_edges2, const IntersectionEdgeMap& intersection_edges2,
const VertexPointMap& vpm1, const VertexPointMap1& vpm1,
const VertexPointMap& /*vpm2*/, const VertexPointMap2& /*vpm2*/,
const VertexPointMapOut& vpm_out, const VertexPointMapOut& vpm_out,
std::vector<typename boost::graph_traits<PolygonMesh> std::vector<typename boost::graph_traits<PolygonMesh>
::edge_descriptor>& output_shared_edges) ::edge_descriptor>& output_shared_edges)
@ -1004,7 +1005,8 @@ void append_patches_to_triangle_mesh(
template < class TriangleMesh, template < class TriangleMesh,
class IntersectionEdgeMap, class IntersectionEdgeMap,
class VertexPointMap, class VertexPointMap1,
class VertexPointMap2,
class VertexPointMapOut, class VertexPointMapOut,
class EdgeMarkMap1, class EdgeMarkMap1,
class EdgeMarkMap2, class EdgeMarkMap2,
@ -1024,8 +1026,8 @@ void fill_new_triangle_mesh(
const IntersectionPolylines& polylines, const IntersectionPolylines& polylines,
const IntersectionEdgeMap& intersection_edges1, const IntersectionEdgeMap& intersection_edges1,
const IntersectionEdgeMap& intersection_edges2, const IntersectionEdgeMap& intersection_edges2,
const VertexPointMap& vpm1, const VertexPointMap1& vpm1,
const VertexPointMap& vpm2, const VertexPointMap2& vpm2,
const VertexPointMapOut& vpm_out, const VertexPointMapOut& vpm_out,
const EdgeMarkMap1& edge_mark_map1, const EdgeMarkMap1& edge_mark_map1,
const EdgeMarkMap2& edge_mark_map2, const EdgeMarkMap2& edge_mark_map2,
@ -1261,7 +1263,8 @@ template <class TriangleMesh,
class PatchContainer2, class PatchContainer2,
class IntersectionPolylines, class IntersectionPolylines,
class EdgeMap, class EdgeMap,
class VertexPointMap, class VertexPointMap1,
class VertexPointMap2,
class EdgeMarkMapIn1, class EdgeMarkMapIn1,
class EdgeMarkMapIn2, class EdgeMarkMapIn2,
class EdgeMarkMapOut, class EdgeMarkMapOut,
@ -1275,8 +1278,8 @@ void compute_inplace_operation_delay_removal_and_insideout(
PatchContainer2& patches_of_tm2, PatchContainer2& patches_of_tm2,
bool reverse_patch_orientation_tm2, bool reverse_patch_orientation_tm2,
const IntersectionPolylines& polylines, const IntersectionPolylines& polylines,
const VertexPointMap& vpm1, const VertexPointMap1& vpm1,
const VertexPointMap& vpm2, const VertexPointMap2& vpm2,
EdgeMarkMapIn1&, EdgeMarkMapIn1&,
const EdgeMarkMapIn2& edge_mark_map2, const EdgeMarkMapIn2& edge_mark_map2,
const EdgeMarkMapOut& edge_mark_map_out1, const EdgeMarkMapOut& edge_mark_map_out1,
@ -1420,7 +1423,8 @@ remove_patches(TriangleMesh& tm,
template <class TriangleMesh, template <class TriangleMesh,
class PatchContainer1, class PatchContainer1,
class PatchContainer2, class PatchContainer2,
class VertexPointMap, class VertexPointMap1,
class VertexPointMap2,
class EdgeMarkMapIn1, class EdgeMarkMapIn1,
class EdgeMarkMapIn2, class EdgeMarkMapIn2,
class EdgeMarkMapOut1, class EdgeMarkMapOut1,
@ -1434,8 +1438,8 @@ void compute_inplace_operation(
PatchContainer2& patches_of_tm2, PatchContainer2& patches_of_tm2,
bool reverse_patch_orientation_tm1, bool reverse_patch_orientation_tm1,
bool reverse_patch_orientation_tm2, bool reverse_patch_orientation_tm2,
const VertexPointMap& vpm1, const VertexPointMap1& vpm1,
const VertexPointMap& vpm2, const VertexPointMap2& vpm2,
EdgeMarkMapIn1& edge_mark_map_in1, EdgeMarkMapIn1& edge_mark_map_in1,
const EdgeMarkMapIn2& edge_mark_map_in2, const EdgeMarkMapIn2& edge_mark_map_in2,
EdgeMarkMapOut1& edge_mark_map_out1, EdgeMarkMapOut1& edge_mark_map_out1,
@ -1527,7 +1531,8 @@ template <class TriangleMesh,
class PatchContainer1, class PatchContainer1,
class PatchContainer2, class PatchContainer2,
class IntersectionPolylines, class IntersectionPolylines,
class VertexPointMap, class VertexPointMap1,
class VertexPointMap2,
class EdgeMarkMapIn1, class EdgeMarkMapIn1,
class EdgeMarkMapIn2, class EdgeMarkMapIn2,
class EdgeMarkMapOut1, class EdgeMarkMapOut1,
@ -1541,8 +1546,8 @@ void compute_inplace_operation(
PatchContainer2& patches_of_tm2, PatchContainer2& patches_of_tm2,
bool reverse_patch_orientation_tm1, bool reverse_patch_orientation_tm1,
bool reverse_patch_orientation_tm2, bool reverse_patch_orientation_tm2,
const VertexPointMap& vpm1, const VertexPointMap1& vpm1,
const VertexPointMap& vpm2, const VertexPointMap2& vpm2,
const EdgeMarkMapIn1& edge_mark_map_in1, const EdgeMarkMapIn1& edge_mark_map_in1,
const EdgeMarkMapIn2& edge_mark_map_in2, const EdgeMarkMapIn2& edge_mark_map_in2,
const EdgeMarkMapOut1& edge_mark_map_out1, const EdgeMarkMapOut1& edge_mark_map_out1,

View File

@ -78,7 +78,7 @@ find_intersection(const Point_3& p, const Point_3& q, //segment
} }
template<class TriangleMesh, class VertexPointMap> template<class TriangleMesh, class VertexPointMap1, class VertexPointMap2>
std::tuple<Intersection_type, std::tuple<Intersection_type,
typename boost::graph_traits<TriangleMesh>::halfedge_descriptor, typename boost::graph_traits<TriangleMesh>::halfedge_descriptor,
bool,bool> bool,bool>
@ -87,23 +87,26 @@ intersection_type(
typename boost::graph_traits<TriangleMesh>::face_descriptor f_2, typename boost::graph_traits<TriangleMesh>::face_descriptor f_2,
const TriangleMesh& tm1, const TriangleMesh& tm1,
const TriangleMesh& tm2, const TriangleMesh& tm2,
const VertexPointMap& vpm1, const VertexPointMap1& vpm1,
const VertexPointMap& vpm2) const VertexPointMap2& vpm2)
{ {
typedef boost::graph_traits<TriangleMesh> GT; typedef boost::graph_traits<TriangleMesh> GT;
typedef typename GT::halfedge_descriptor halfedge_descriptor; typedef typename GT::halfedge_descriptor halfedge_descriptor;
typedef std::tuple<Intersection_type,halfedge_descriptor,bool,bool> result_type; typedef std::tuple<Intersection_type,halfedge_descriptor,bool,bool> result_type;
typedef typename boost::property_traits<VertexPointMap>::reference Point_ref; typedef typename boost::property_traits<VertexPointMap1>::reference Point_ref1;
typedef typename boost::property_traits<VertexPointMap>::value_type Point_3; typedef typename boost::property_traits<VertexPointMap2>::reference Point_ref2;
typedef typename boost::property_traits<VertexPointMap1>::value_type Point_3;
typedef typename Kernel_traits<Point_3>::Kernel Kernel; typedef typename Kernel_traits<Point_3>::Kernel Kernel;
CGAL_static_assertion((std::is_same<Point_3, typename boost::property_traits<VertexPointMap2>::value_type>::value));
halfedge_descriptor h_2=halfedge(f_2,tm2); halfedge_descriptor h_2=halfedge(f_2,tm2);
Point_ref a = get(vpm2, target(h_2,tm2) ); Point_ref2 a = get(vpm2, target(h_2,tm2) );
Point_ref b = get(vpm2, target(next(h_2,tm2),tm2) ); Point_ref2 b = get(vpm2, target(next(h_2,tm2),tm2) );
Point_ref c = get(vpm2, source(h_2,tm2) ); Point_ref2 c = get(vpm2, source(h_2,tm2) );
Point_ref p = get(vpm1, source(h_1,tm1) ); Point_ref1 p = get(vpm1, source(h_1,tm1) );
Point_ref q = get(vpm1, target(h_1,tm1) ); Point_ref1 q = get(vpm1, target(h_1,tm1) );
const Orientation abcp = orientation(a,b,c,p); const Orientation abcp = orientation(a,b,c,p);
const Orientation abcq = orientation(a,b,c,q); const Orientation abcq = orientation(a,b,c,q);

View File

@ -67,15 +67,15 @@ public:
}; };
template<class TriangleMesh, template<class TriangleMesh,
class VertexPointMap, class VertexPointMapF, class VertexPointMapE,
class EdgeToFaces, class EdgeToFaces,
class CoplanarFaceSet> class CoplanarFaceSet>
class Collect_face_bbox_per_edge_bbox_with_coplanar_handling { class Collect_face_bbox_per_edge_bbox_with_coplanar_handling {
protected: protected:
const TriangleMesh& tm_faces; const TriangleMesh& tm_faces;
const TriangleMesh& tm_edges; const TriangleMesh& tm_edges;
const VertexPointMap& vpmap_tmf; const VertexPointMapF& vpmap_tmf;
const VertexPointMap& vpmap_tme; const VertexPointMapE& vpmap_tme;
EdgeToFaces& edge_to_faces; EdgeToFaces& edge_to_faces;
CoplanarFaceSet& coplanar_faces; CoplanarFaceSet& coplanar_faces;
@ -83,7 +83,7 @@ protected:
typedef typename Graph_traits::face_descriptor face_descriptor; typedef typename Graph_traits::face_descriptor face_descriptor;
typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename Graph_traits::halfedge_descriptor halfedge_descriptor;
typedef typename boost::property_traits<VertexPointMap>::reference Point; typedef typename boost::property_traits<VertexPointMapF>::reference Point;
typedef CGAL::Box_intersection_d::ID_FROM_BOX_ADDRESS Box_policy; typedef CGAL::Box_intersection_d::ID_FROM_BOX_ADDRESS Box_policy;
typedef CGAL::Box_intersection_d::Box_with_info_d<double, 3, halfedge_descriptor, Box_policy> Box; typedef CGAL::Box_intersection_d::Box_with_info_d<double, 3, halfedge_descriptor, Box_policy> Box;
@ -92,8 +92,8 @@ public:
Collect_face_bbox_per_edge_bbox_with_coplanar_handling( Collect_face_bbox_per_edge_bbox_with_coplanar_handling(
const TriangleMesh& tm_faces, const TriangleMesh& tm_faces,
const TriangleMesh& tm_edges, const TriangleMesh& tm_edges,
const VertexPointMap& vpmap_tmf, const VertexPointMapF& vpmap_tmf,
const VertexPointMap& vpmap_tme, const VertexPointMapE& vpmap_tme,
EdgeToFaces& edge_to_faces, EdgeToFaces& edge_to_faces,
CoplanarFaceSet& coplanar_faces) CoplanarFaceSet& coplanar_faces)
: tm_faces(tm_faces) : tm_faces(tm_faces)

View File

@ -83,10 +83,10 @@ struct Default_surface_intersection_visitor{
void start_new_polyline(std::size_t,std::size_t){} void start_new_polyline(std::size_t,std::size_t){}
void add_node_to_polyline(std::size_t){} void add_node_to_polyline(std::size_t){}
void input_have_coplanar_faces(){} void input_have_coplanar_faces(){}
template<class T,class VertexPointMap> template<class T,class VPM1,class VPM2>
void finalize(T&, void finalize(T&,
const TriangleMesh&, const TriangleMesh&, const TriangleMesh&, const TriangleMesh&,
const VertexPointMap&, const VertexPointMap&) const VPM1, const VPM2)
{} {}
void new_node_added_triple_face(std::size_t /* node_id */, void new_node_added_triple_face(std::size_t /* node_id */,
face_descriptor /* f1 */, face_descriptor /* f1 */,
@ -144,7 +144,7 @@ struct Node_id_set {
}; };
template< class TriangleMesh, template< class TriangleMesh,
class VertexPointMap, class VertexPointMap1, class VertexPointMap2,
class Node_visitor=Default_surface_intersection_visitor<TriangleMesh> class Node_visitor=Default_surface_intersection_visitor<TriangleMesh>
> >
class Intersection_of_triangle_meshes class Intersection_of_triangle_meshes
@ -175,7 +175,7 @@ class Intersection_of_triangle_meshes
// may contain several segments. // may contain several segments.
typedef std::map< Face_pair_and_int, Node_id_set > Faces_to_nodes_map; typedef std::map< Face_pair_and_int, Node_id_set > Faces_to_nodes_map;
typedef Intersection_nodes<TriangleMesh, typedef Intersection_nodes<TriangleMesh,
VertexPointMap, VertexPointMap1, VertexPointMap2,
Predicates_on_constructions_needed> Node_vector; Predicates_on_constructions_needed> Node_vector;
// data members // 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 Faces_to_nodes_map f_to_node; //Associate a pair of triangles to their intersection points
std::vector<Node_id> extra_terminal_nodes; //used only for autorefinement std::vector<Node_id> extra_terminal_nodes; //used only for autorefinement
CGAL_assertion_code(bool doing_autorefinement;) CGAL_assertion_code(bool doing_autorefinement;)
// member functions // member functions
template <class VPMF, class VPME>
void filter_intersections(const TriangleMesh& tm_f, void filter_intersections(const TriangleMesh& tm_f,
const TriangleMesh& tm_e, const TriangleMesh& tm_e,
const VertexPointMap& vpm_f, const VPMF& vpm_f,
const VertexPointMap& vpm_e, const VPME& vpm_e,
bool throw_on_self_intersection) bool throw_on_self_intersection)
{ {
std::vector<Box> face_boxes, edge_boxes; std::vector<Box> face_boxes, edge_boxes;
@ -237,7 +239,7 @@ class Intersection_of_triangle_meshes
Callback callback(tm_f, tm_e, edge_to_faces); Callback callback(tm_f, tm_e, edge_to_faces);
#else #else
typedef Collect_face_bbox_per_edge_bbox_with_coplanar_handling< 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 callback(tm_f, tm_e, vpm_f, vpm_e, edge_to_faces, coplanar_faces); Callback callback(tm_f, tm_e, vpm_f, vpm_e, edge_to_faces, coplanar_faces);
#endif #endif
@ -258,8 +260,9 @@ class Intersection_of_triangle_meshes
} }
// for autorefinement // for autorefinement
template <class VPM>
void filter_intersections(const TriangleMesh& tm, void filter_intersections(const TriangleMesh& tm,
const VertexPointMap& vpm) const VPM& vpm)
{ {
std::vector<Box> face_boxes, edge_boxes; std::vector<Box> face_boxes, edge_boxes;
std::vector<Box*> face_boxes_ptr, edge_boxes_ptr; std::vector<Box*> 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; Edge_to_faces& edge_to_faces = stm_edge_to_ltm_faces;
typedef Collect_face_bbox_per_edge_bbox_with_coplanar_handling_one_mesh< 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 callback(tm, vpm, edge_to_faces, coplanar_faces); Callback callback(tm, vpm, edge_to_faces, coplanar_faces);
@ -527,12 +530,12 @@ class Intersection_of_triangle_meshes
} }
} }
void compute_intersection_of_coplanar_faces( template <typename VPM1, typename VPM2>
Node_id& current_node, void compute_intersection_of_coplanar_faces(Node_id& current_node,
const TriangleMesh& tm1, const TriangleMesh& tm1,
const TriangleMesh& tm2, const TriangleMesh& tm2,
const VertexPointMap& vpm1, const VPM1& vpm1,
const VertexPointMap& vpm2) const VPM2& vpm2)
{ {
CGAL_assertion( &tm1 < &tm2 || &tm1==&tm2 ); CGAL_assertion( &tm1 < &tm2 || &tm1==&tm2 );
@ -637,12 +640,13 @@ class Intersection_of_triangle_meshes
//add a new node in the final graph. //add a new node in the final graph.
//it is the intersection of the triangle with the segment //it is the intersection of the triangle with the segment
template <typename VPM1, typename VPM2>
void add_new_node(halfedge_descriptor h_1, void add_new_node(halfedge_descriptor h_1,
face_descriptor f_2, face_descriptor f_2,
const TriangleMesh& tm1, const TriangleMesh& tm1,
const TriangleMesh& tm2, const TriangleMesh& tm2,
const VertexPointMap& vpm1, const VPM1& vpm1,
const VertexPointMap& vpm2, const VPM2& vpm2,
std::tuple<Intersection_type, std::tuple<Intersection_type,
halfedge_descriptor, halfedge_descriptor,
bool,bool> inter_res) bool,bool> inter_res)
@ -657,11 +661,12 @@ class Intersection_of_triangle_meshes
} }
} }
template <typename VPM1, typename VPM2>
void compute_intersection_points(Edge_to_faces& tm1_edge_to_tm2_faces, void compute_intersection_points(Edge_to_faces& tm1_edge_to_tm2_faces,
const TriangleMesh& tm1, const TriangleMesh& tm1,
const TriangleMesh& tm2, const TriangleMesh& tm2,
const VertexPointMap& vpm1, const VPM1& vpm1,
const VertexPointMap& vpm2, const VPM2& vpm2,
Node_id& current_node) Node_id& current_node)
{ {
typedef std::tuple<Intersection_type, halfedge_descriptor, bool,bool> Inter_type; typedef std::tuple<Intersection_type, halfedge_descriptor, bool,bool> Inter_type;
@ -821,8 +826,9 @@ class Intersection_of_triangle_meshes
} }
}; };
template <class VPM>
void detect_intersections_in_the_graph(const TriangleMesh& tm, void detect_intersections_in_the_graph(const TriangleMesh& tm,
const VertexPointMap& vpm, const VPM& vpm,
Node_id& current_node) Node_id& current_node)
{ {
boost::unordered_map<face_descriptor, boost::unordered_map<face_descriptor,
@ -1082,7 +1088,7 @@ class Intersection_of_triangle_meshes
template <class Output_iterator> template <class Output_iterator>
void construct_polylines(Output_iterator out){ void construct_polylines(Output_iterator out){
typedef typename boost::property_traits<VertexPointMap>::value_type Point_3; typedef typename boost::property_traits<VertexPointMap1>::value_type Point_3;
std::size_t nb_nodes=nodes.size(); std::size_t nb_nodes=nodes.size();
std::vector<Graph_node> graph(nb_nodes); std::vector<Graph_node> graph(nb_nodes);
//counts the number of time each node has been seen //counts the number of time each node has been seen
@ -1262,8 +1268,8 @@ class Intersection_of_triangle_meshes
public: public:
Intersection_of_triangle_meshes(const TriangleMesh& tm1, Intersection_of_triangle_meshes(const TriangleMesh& tm1,
const TriangleMesh& tm2, const TriangleMesh& tm2,
const VertexPointMap& vpm1, const VertexPointMap1& vpm1,
const VertexPointMap& vpm2, const VertexPointMap2& vpm2,
const Node_visitor& v=Node_visitor()) const Node_visitor& v=Node_visitor())
: nodes(tm1, tm2, vpm1, vpm2) : nodes(tm1, tm2, vpm1, vpm2)
, visitor(v) , visitor(v)
@ -1275,7 +1281,7 @@ public:
// for autorefinement // for autorefinement
Intersection_of_triangle_meshes(const TriangleMesh& tm, Intersection_of_triangle_meshes(const TriangleMesh& tm,
const VertexPointMap& vpm, const VertexPointMap1& vpm,
const Node_visitor& v=Node_visitor()) const Node_visitor& v=Node_visitor())
: nodes(tm, tm, vpm, vpm) : nodes(tm, tm, vpm, vpm)
, visitor(v) , visitor(v)
@ -1293,8 +1299,8 @@ public:
const TriangleMesh& tm1=nodes.tm1; const TriangleMesh& tm1=nodes.tm1;
const TriangleMesh& tm2=nodes.tm2; const TriangleMesh& tm2=nodes.tm2;
const VertexPointMap& vpm1=nodes.vpm1; const VertexPointMap1& vpm1=nodes.vpm1;
const VertexPointMap& vpm2=nodes.vpm2; const VertexPointMap2& vpm2=nodes.vpm2;
filter_intersections(tm1, tm2, vpm1, vpm2, throw_on_self_intersection); filter_intersections(tm1, tm2, vpm1, vpm2, throw_on_self_intersection);
filter_intersections(tm2, tm1, vpm2, vpm1, 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); compute_intersection_of_coplanar_faces(current_node, tm1, tm2, vpm1, vpm2);
else else
compute_intersection_of_coplanar_faces(current_node, tm2, tm1, vpm2, vpm1); compute_intersection_of_coplanar_faces(current_node, tm2, tm1, vpm2, vpm1);
visitor.set_number_of_intersection_points_from_coplanar_faces(current_node+1); visitor.set_number_of_intersection_points_from_coplanar_faces(current_node+1);
if (!coplanar_faces.empty()) if (!coplanar_faces.empty())
visitor.input_have_coplanar_faces(); 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(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); compute_intersection_points(tm2_edge_to_tm1_faces, tm2, tm1, vpm2, vpm1, current_node);
if (!build_polylines){ if (!build_polylines){
visitor.finalize(nodes,tm1,tm2,vpm1,vpm2); visitor.finalize(nodes,tm1,tm2,vpm1,vpm2);
return output; return output;
@ -1361,7 +1369,7 @@ public:
CGAL_assertion(doing_autorefinement); CGAL_assertion(doing_autorefinement);
const TriangleMesh& tm=nodes.tm1; const TriangleMesh& tm=nodes.tm1;
const VertexPointMap& vpm=nodes.vpm1; const VertexPointMap1& vpm=nodes.vpm1;
filter_intersections(tm, vpm); filter_intersections(tm, vpm);

View File

@ -28,23 +28,26 @@ namespace Corefinement {
// polylines. Different specializations are available depending whether // polylines. Different specializations are available depending whether
// predicates on constructions are needed. // predicates on constructions are needed.
template <class TriangleMesh, template <class TriangleMesh,
class VertexPointMap, class VertexPointMap1, class VertexPointMap2,
bool Predicates_on_constructions_needed, bool Predicates_on_constructions_needed,
bool Has_exact_constructions= bool Has_exact_constructions =
!boost::is_floating_point< !boost::is_floating_point<
typename Kernel_traits< typename Kernel_traits<
typename boost::property_traits<VertexPointMap>::value_type typename boost::property_traits<VertexPointMap1>::value_type
>::Kernel::FT >::Kernel::FT
>::value > >::value >
class Intersection_nodes; class Intersection_nodes;
//Store only the double version of the intersection points. //Store only the double version of the intersection points.
template <class TriangleMesh, template <class TriangleMesh,
class VertexPointMap> class VertexPointMap1, class VertexPointMap2>
class Intersection_nodes<TriangleMesh,VertexPointMap,false,false> class Intersection_nodes<TriangleMesh, VertexPointMap1, VertexPointMap2, false, false>
{ {
//typedefs //typedefs
typedef typename boost::property_traits<VertexPointMap>::value_type Point_3; typedef typename boost::property_traits<VertexPointMap1>::value_type Point_3;
CGAL_static_assertion((std::is_same<typename boost::property_traits<VertexPointMap1>::value_type,
typename boost::property_traits<VertexPointMap2>::value_type>::value));
typedef typename Kernel_traits<Point_3>::Kernel Input_kernel; typedef typename Kernel_traits<Point_3>::Kernel Input_kernel;
typedef std::vector <Point_3> Nodes_vector; typedef std::vector <Point_3> Nodes_vector;
typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_kernel; typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_kernel;
@ -67,12 +70,13 @@ class Intersection_nodes<TriangleMesh,VertexPointMap,false,false>
public: public:
const TriangleMesh &tm1, &tm2; const TriangleMesh &tm1, &tm2;
VertexPointMap vpm1, vpm2; const VertexPointMap1& vpm1;
const VertexPointMap2& vpm2;
Intersection_nodes(const TriangleMesh& tm1_, Intersection_nodes(const TriangleMesh& tm1_,
const TriangleMesh& tm2_, const TriangleMesh& tm2_,
const VertexPointMap& vpm1_, const VertexPointMap1& vpm1_,
const VertexPointMap& vpm2_) const VertexPointMap2& vpm2_)
: tm1(tm1_) : tm1(tm1_)
, tm2(tm2_) , tm2(tm2_)
, vpm1(vpm1_) , vpm1(vpm1_)
@ -97,12 +101,13 @@ public:
//add a new node in the final graph. //add a new node in the final graph.
//it is the intersection of the triangle with the segment //it is the intersection of the triangle with the segment
template <class VPM_A, class VPM_B> // VertexPointMap1 or VertexPointMap2
void add_new_node(halfedge_descriptor h_a, void add_new_node(halfedge_descriptor h_a,
face_descriptor f_b, face_descriptor f_b,
const TriangleMesh& tm_a, const TriangleMesh& tm_a,
const TriangleMesh& tm_b, const TriangleMesh& tm_b,
const VertexPointMap vpm_a, const VPM_A& vpm_a,
const VertexPointMap& vpm_b) const VPM_B& vpm_b)
{ {
halfedge_descriptor h_b = halfedge(f_b, tm_b); halfedge_descriptor h_b = halfedge(f_b, tm_b);
add_new_node( add_new_node(
@ -114,12 +119,8 @@ public:
to_exact( get(vpm_a, target(h_a,tm_a)) ) ) ); to_exact( get(vpm_a, target(h_a,tm_a)) ) ) );
} }
void add_new_node(halfedge_descriptor edge_1, face_descriptor face_2) template <class VPM> // VertexPointMap1 or VertexPointMap2
{ void call_put(const VPM& vpm, vertex_descriptor vd, std::size_t i, TriangleMesh&)
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&)
{ {
put(vpm, vd, nodes[i]); put(vpm, vd, nodes[i]);
} }
@ -132,14 +133,18 @@ public:
// second specializations: store an exact copy of the points so // second specializations: store an exact copy of the points so
// that we can answer exactly predicates // that we can answer exactly predicates
template <class TriangleMesh, class VertexPointMap> template <class TriangleMesh, class VertexPointMap1, class VertexPointMap2>
class Intersection_nodes<TriangleMesh,VertexPointMap,true,false> class Intersection_nodes<TriangleMesh, VertexPointMap1, VertexPointMap2, true, false>
{ {
//typedefs //typedefs
public: public:
typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_kernel; typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_kernel;
private: private:
typedef typename boost::property_traits<VertexPointMap>::value_type Point_3; typedef typename boost::property_traits<VertexPointMap1>::value_type Point_3;
CGAL_static_assertion((std::is_same<typename boost::property_traits<VertexPointMap1>::value_type,
typename boost::property_traits<VertexPointMap2>::value_type>::value));
typedef typename Kernel_traits<Point_3>::Kernel Input_kernel; typedef typename Kernel_traits<Point_3>::Kernel Input_kernel;
typedef Cartesian_converter<Input_kernel,Exact_kernel> Double_to_exact; typedef Cartesian_converter<Input_kernel,Exact_kernel> Double_to_exact;
@ -160,14 +165,16 @@ private:
Exact_kernel::Intersect_3 exact_intersection; Exact_kernel::Intersect_3 exact_intersection;
std::vector<vertex_descriptor> tm1_vertices, tm2_vertices; std::vector<vertex_descriptor> tm1_vertices, tm2_vertices;
const bool doing_autorefinement; const bool doing_autorefinement;
public: public:
const TriangleMesh &tm1, &tm2; const TriangleMesh &tm1, &tm2;
VertexPointMap vpm1, vpm2; const VertexPointMap1& vpm1;
const VertexPointMap2& vpm2;
Intersection_nodes(const TriangleMesh& tm1_, Intersection_nodes(const TriangleMesh& tm1_,
const TriangleMesh& tm2_, const TriangleMesh& tm2_,
const VertexPointMap& vpm1_, const VertexPointMap1& vpm1_,
const VertexPointMap& vpm2_) const VertexPointMap2& vpm2_)
: doing_autorefinement(&tm1_ == &tm2_) : doing_autorefinement(&tm1_ == &tm2_)
, tm1(tm1_) , tm1(tm1_)
, tm2(tm2_) , tm2(tm2_)
@ -211,12 +218,13 @@ public:
//add a new node in the final graph. //add a new node in the final graph.
//it is the intersection of the triangle with the segment //it is the intersection of the triangle with the segment
template <class VPM_A, class VPM_B> // VertexPointMap1 or VertexPointMap2
void add_new_node(halfedge_descriptor h_a, void add_new_node(halfedge_descriptor h_a,
face_descriptor f_b, face_descriptor f_b,
const TriangleMesh& tm_a, const TriangleMesh& tm_a,
const TriangleMesh& tm_b, const TriangleMesh& tm_b,
const VertexPointMap vpm_a, const VPM_A vpm_a,
const VertexPointMap& vpm_b) const VPM_B vpm_b)
{ {
halfedge_descriptor h_b = halfedge(f_b, tm_b); halfedge_descriptor h_b = halfedge(f_b, tm_b);
add_new_node( add_new_node(
@ -229,11 +237,12 @@ public:
} }
// use to resolve intersection of 3 faces in autorefinement only // use to resolve intersection of 3 faces in autorefinement only
template <class VPM>
void add_new_node(halfedge_descriptor h1, void add_new_node(halfedge_descriptor h1,
halfedge_descriptor h2, halfedge_descriptor h2,
halfedge_descriptor h3, halfedge_descriptor h3,
const TriangleMesh& tm, const TriangleMesh& tm,
const VertexPointMap& vpm) const VPM& vpm)
{ {
// TODO Far from optimal! // TODO Far from optimal!
typedef Exact_kernel::Plane_3 Plane_3; typedef Exact_kernel::Plane_3 Plane_3;
@ -257,11 +266,6 @@ public:
add_new_node(*pt); 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 //the point is an input
void add_new_node(const Point_3& p){ void add_new_node(const Point_3& p){
enodes.push_back(to_exact(p)); enodes.push_back(to_exact(p));
@ -273,7 +277,8 @@ public:
tm2_vertices.resize(enodes.size(), GT::null_vertex()); tm2_vertices.resize(enodes.size(), GT::null_vertex());
} }
void call_put(const VertexPointMap& vpm, vertex_descriptor vd, std::size_t i, TriangleMesh& tm) template <class VPM> // 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])); put(vpm, vd, exact_to_double(enodes[i]));
if (&tm1==&tm) if (&tm1==&tm)
@ -306,11 +311,16 @@ public:
//Third specialization: The kernel already has exact constructions. //Third specialization: The kernel already has exact constructions.
template <class TriangleMesh,class VertexPointMap,bool Predicates_on_constructions_needed> template <class TriangleMesh, class VertexPointMap1, class VertexPointMap2,
class Intersection_nodes<TriangleMesh,VertexPointMap,Predicates_on_constructions_needed,true> bool Predicates_on_constructions_needed>
class Intersection_nodes<TriangleMesh, VertexPointMap1, VertexPointMap2,
Predicates_on_constructions_needed, true>
{ {
//typedefs //typedefs
typedef typename boost::property_traits<VertexPointMap>::value_type Point_3; typedef typename boost::property_traits<VertexPointMap1>::value_type Point_3;
CGAL_static_assertion((std::is_same<typename boost::property_traits<VertexPointMap1>::value_type,
typename boost::property_traits<VertexPointMap2>::value_type>::value));
typedef typename Kernel_traits<Point_3>::Kernel Input_kernel; typedef typename Kernel_traits<Point_3>::Kernel Input_kernel;
typedef std::vector <Point_3> Nodes_vector; typedef std::vector <Point_3> Nodes_vector;
@ -326,12 +336,13 @@ public:
typedef Input_kernel Exact_kernel; typedef Input_kernel Exact_kernel;
const TriangleMesh &tm1, &tm2; const TriangleMesh &tm1, &tm2;
VertexPointMap vpm1, vpm2; const VertexPointMap1& vpm1;
const VertexPointMap2& vpm2;
Intersection_nodes(const TriangleMesh& tm1_, Intersection_nodes(const TriangleMesh& tm1_,
const TriangleMesh& tm2_, const TriangleMesh& tm2_,
const VertexPointMap& vpm1_, const VertexPointMap1& vpm1_,
const VertexPointMap& vpm2_) const VertexPointMap2& vpm2_)
: tm1(tm1_) : tm1(tm1_)
, tm2(tm2_) , tm2(tm2_)
, vpm1(vpm1_) , vpm1(vpm1_)
@ -346,11 +357,12 @@ public:
size_t size() const {return nodes.size();} size_t size() const {return nodes.size();}
const Point_3& exact_node(std::size_t i) const {return nodes[i];} const Point_3& exact_node(std::size_t i) const {return nodes[i];}
template <class VPM>
void add_new_node(halfedge_descriptor h1, void add_new_node(halfedge_descriptor h1,
halfedge_descriptor h2, halfedge_descriptor h2,
halfedge_descriptor h3, halfedge_descriptor h3,
const TriangleMesh& tm, const TriangleMesh& tm,
const VertexPointMap& vpm) const VPM& vpm)
{ {
// TODO Far from optimal! // TODO Far from optimal!
typedef typename Exact_kernel::Plane_3 Plane_3; typedef typename Exact_kernel::Plane_3 Plane_3;
@ -376,12 +388,13 @@ public:
//add a new node in the final graph. //add a new node in the final graph.
//it is the intersection of the triangle with the segment //it is the intersection of the triangle with the segment
template <class VPM_A, class VPM_B> // VertexPointMap1 or VertexPointMap2
void add_new_node(halfedge_descriptor h_a, void add_new_node(halfedge_descriptor h_a,
face_descriptor f_b, face_descriptor f_b,
const TriangleMesh& tm_a, const TriangleMesh& tm_a,
const TriangleMesh& tm_b, const TriangleMesh& tm_b,
const VertexPointMap vpm_a, const VPM_A& vpm_a,
const VertexPointMap& vpm_b) const VPM_B& vpm_b)
{ {
halfedge_descriptor h_b=halfedge(f_b,tm_b); halfedge_descriptor h_b=halfedge(f_b,tm_b);
@ -394,12 +407,6 @@ public:
get(vpm_a, target(h_a,tm_a)) ) ); 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) void add_new_node(const Point_3& p)
{ {
nodes.push_back(p); nodes.push_back(p);
@ -407,7 +414,8 @@ public:
const Point_3& to_exact(const Point_3& p) const { return p; } 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 <class VPM> // VertexPointMap1 or VertexPointMap2
void call_put(const VPM& vpm, vertex_descriptor vd, std::size_t i, TriangleMesh&)
{ {
put(vpm, vd, nodes[i]); put(vpm, vd, nodes[i]);
} }

View File

@ -27,10 +27,15 @@ namespace CGAL{
namespace Polygon_mesh_processing { namespace Polygon_mesh_processing {
namespace Corefinement{ namespace Corefinement{
template <class TriangleMesh, class VertexPointMap> template <class TriangleMesh, class VertexPointMap1, class VertexPointMap2>
struct Intersect_coplanar_faces_3{ struct Intersect_coplanar_faces_3
{
// typedefs // typedefs
typedef typename boost::property_traits<VertexPointMap>::value_type Point; typedef typename boost::property_traits<VertexPointMap1>::value_type Point;
CGAL_static_assertion((std::is_same<typename boost::property_traits<VertexPointMap1>::value_type,
typename boost::property_traits<VertexPointMap1>::value_type>::value));
typedef typename CGAL::Kernel_traits<Point>::Kernel Input_kernel; typedef typename CGAL::Kernel_traits<Point>::Kernel Input_kernel;
typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_kernel; typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_kernel;
@ -40,12 +45,14 @@ struct Intersect_coplanar_faces_3{
typedef Coplanar_intersection<TriangleMesh, Exact_kernel> Inter_pt_info; typedef Coplanar_intersection<TriangleMesh, Exact_kernel> Inter_pt_info;
// data members // data members
const TriangleMesh &tm1, &tm2; const TriangleMesh &tm1, &tm2;
const VertexPointMap &vpm1, &vpm2; const VertexPointMap1& vpm1;
const VertexPointMap2& vpm2;
// constructor // constructor
Intersect_coplanar_faces_3(const TriangleMesh& tm1_, Intersect_coplanar_faces_3(const TriangleMesh& tm1_,
const TriangleMesh& tm2_, const TriangleMesh& tm2_,
const VertexPointMap& vpm1_, const VertexPointMap1& vpm1_,
const VertexPointMap& vpm2_) const VertexPointMap2& vpm2_)
: tm1(tm1_), tm2(tm2_), vpm1(vpm1_), vpm2(vpm2_) : tm1(tm1_), tm2(tm2_), vpm1(vpm1_), vpm2(vpm2_)
{} {}
@ -282,14 +289,14 @@ struct Intersect_coplanar_faces_3{
} }
}; };
template <class TriangleMesh, class VertexPointMap, class Exact_kernel> template <class TriangleMesh, class VertexPointMap1, class VertexPointMap2, class Exact_kernel>
void intersection_coplanar_faces( void intersection_coplanar_faces(
typename boost::graph_traits<TriangleMesh>::face_descriptor f1, typename boost::graph_traits<TriangleMesh>::face_descriptor f1,
typename boost::graph_traits<TriangleMesh>::face_descriptor f2, typename boost::graph_traits<TriangleMesh>::face_descriptor f2,
const TriangleMesh& tm1, const TriangleMesh& tm1,
const TriangleMesh& tm2, const TriangleMesh& tm2,
const VertexPointMap& vpm1, const VertexPointMap1& vpm1,
const VertexPointMap& vpm2, const VertexPointMap2& vpm2,
std::list< Coplanar_intersection<TriangleMesh, Exact_kernel> >& inter_pts) std::list< Coplanar_intersection<TriangleMesh, Exact_kernel> >& inter_pts)
{ {
typedef boost::graph_traits<TriangleMesh> GT; typedef boost::graph_traits<TriangleMesh> GT;
@ -297,7 +304,7 @@ void intersection_coplanar_faces(
halfedge_descriptor h1=halfedge(f1,tm1), h2=halfedge(f2,tm2); halfedge_descriptor h1=halfedge(f1,tm1), h2=halfedge(f2,tm2);
Intersect_coplanar_faces_3<TriangleMesh, VertexPointMap> Intersect_coplanar_faces_3<TriangleMesh, VertexPointMap1, VertexPointMap2>
intersect_cpln(tm1, tm2, vpm1, vpm2); intersect_cpln(tm1, tm2, vpm1, vpm2);
// We will add in `inter_pts` the initial triangle of h1 // We will add in `inter_pts` the initial triangle of h1

View File

@ -122,15 +122,15 @@ bool are_triangles_coplanar_same_side(
} }
template <class Node_id, class Node_vector, class vertex_descriptor, class Vpm> template <class Node_id, class Node_vector, class vertex_descriptor, class VPMP, class VPMQ>
bool are_triangles_coplanar_same_side(Node_id o_prime_index, bool are_triangles_coplanar_same_side(Node_id o_prime_index,
Node_id o_index, Node_id o_index,
Node_id p_index, Node_id p_index,
Node_id q_index, Node_id q_index,
vertex_descriptor p, vertex_descriptor p,
vertex_descriptor q, vertex_descriptor q,
const Vpm& vpm_p, const VPMP& vpm_p,
const Vpm& vpm_q, const VPMQ& vpm_q,
const Node_vector& nodes) const Node_vector& nodes)
{ {
const Node_id NID((std::numeric_limits<Node_id>::max)()); const Node_id NID((std::numeric_limits<Node_id>::max)());
@ -142,7 +142,7 @@ bool are_triangles_coplanar_same_side(Node_id o_prime_index,
); );
} }
template <class Node_id, class Node_vector, class vertex_descriptor, class Vpm> template <class Node_id, class Node_vector, class vertex_descriptor, class VPMP, class VPMQ>
bool sorted_around_edge( Node_id o_prime_index, bool sorted_around_edge( Node_id o_prime_index,
Node_id o_index, Node_id o_index,
Node_id p1_index, Node_id p1_index,
@ -151,8 +151,8 @@ bool sorted_around_edge( Node_id o_prime_index,
vertex_descriptor p1, vertex_descriptor p1,
vertex_descriptor p2, vertex_descriptor p2,
vertex_descriptor q, vertex_descriptor q,
const Vpm& vpm_p, const VPMP& vpm_p,
const Vpm& vpm_q, const VPMQ& vpm_q,
const Node_vector& nodes) const Node_vector& nodes)
{ {
const Node_id NID((std::numeric_limits<Node_id>::max)()); const Node_id NID((std::numeric_limits<Node_id>::max)());

View File

@ -1758,21 +1758,18 @@ surface_intersection(const TriangleMesh& tm1,
const bool throw_on_self_intersection = const bool throw_on_self_intersection =
parameters::choose_parameter(parameters::get_parameter(np1, internal_np::throw_on_self_intersection), false); parameters::choose_parameter(parameters::get_parameter(np1, internal_np::throw_on_self_intersection), false);
typedef typename GetVertexPointMap<TriangleMesh, typedef typename GetVertexPointMap<TriangleMesh, NamedParameters1>::const_type VPM1;
NamedParameters1>::const_type Vpm; typedef typename GetVertexPointMap<TriangleMesh, NamedParameters2>::const_type VPM2;
typedef typename GetVertexPointMap<TriangleMesh,
NamedParameters2>::const_type Vpm2;
CGAL_USE_TYPE(Vpm2);
CGAL_assertion_code(
static const bool same_vpm = (boost::is_same<Vpm,Vpm2>::value);)
CGAL_static_assertion(same_vpm);
Vpm vpm1 = parameters::choose_parameter(parameters::get_parameter(np1, internal_np::vertex_point), CGAL_static_assertion((std::is_same<typename boost::property_traits<VPM1>::value_type,
typename boost::property_traits<VPM2>::value_type>::value));
VPM1 vpm1 = parameters::choose_parameter(parameters::get_parameter(np1, internal_np::vertex_point),
get_const_property_map(CGAL::vertex_point, tm1)); get_const_property_map(CGAL::vertex_point, tm1));
Vpm vpm2 = parameters::choose_parameter(parameters::get_parameter(np2, internal_np::vertex_point), VPM2 vpm2 = parameters::choose_parameter(parameters::get_parameter(np2, internal_np::vertex_point),
get_const_property_map(CGAL::vertex_point, tm2)); get_const_property_map(CGAL::vertex_point, tm2));
Corefinement::Intersection_of_triangle_meshes<TriangleMesh,Vpm> Corefinement::Intersection_of_triangle_meshes<TriangleMesh, VPM1, VPM2>
functor(tm1, tm2, vpm1, vpm2); functor(tm1, tm2, vpm1, vpm2);
return functor(polyline_output, throw_on_self_intersection, true); return functor(polyline_output, throw_on_self_intersection, true);
} }
@ -1814,17 +1811,14 @@ surface_self_intersection(const TriangleMesh& tm,
const NamedParameters& np) const NamedParameters& np)
{ {
// Vertex point maps // Vertex point maps
typedef typename GetVertexPointMap<TriangleMesh, typedef typename GetVertexPointMap<TriangleMesh, NamedParameters>::const_type VPM;
NamedParameters>::const_type Vpm;
Vpm vpm = parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_point), VPM vpm = parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_point),
get_const_property_map(CGAL::vertex_point, tm)); get_const_property_map(CGAL::vertex_point, tm));
// surface intersection algorithm call // surface intersection algorithm call
typedef Corefinement::Default_surface_intersection_visitor<TriangleMesh, typedef Corefinement::Default_surface_intersection_visitor<TriangleMesh, true> Visitor;
true> Visitor; Corefinement::Intersection_of_triangle_meshes<TriangleMesh, VPM, VPM, Visitor> functor(tm, vpm);
Corefinement::Intersection_of_triangle_meshes<TriangleMesh,Vpm, Visitor>
functor(tm, vpm);
polyline_output=functor(polyline_output, true); polyline_output=functor(polyline_output, true);
return polyline_output; return polyline_output;