mirror of https://github.com/CGAL/cgal
Merge pull request #4712 from MaelRL/PMP-Clip_with_self_intersections-GF
PMP: Generalize some corefinement code
This commit is contained in:
commit
d075ef4fb3
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)());
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue