This commit is contained in:
Sébastien Loriot 2018-05-24 18:23:12 +02:00
parent a097455ab3
commit eea53718bb
4 changed files with 116 additions and 115 deletions

View File

@ -243,11 +243,11 @@ bool does_bound_a_volume(const TriangleMesh& tm)
}
#define CGAL_COREF_SET_OUTPUT_VERTEX_POINT_MAP(i) \
if (desired_output[i]!=boost::none) \
if (output[i]!=boost::none) \
{ \
vpm_out.push_back( \
boost::choose_param(get_param(cpp11::get<i>(nps_out), internal_np::vertex_point), \
get_property_map(boost::vertex_point, *(*desired_output[i])))); \
get_property_map(boost::vertex_point, *(*output[i])))); \
output_vpms[i]=&vpm_out.back(); \
} \
else \
@ -275,18 +275,18 @@ template <class TriangleMesh,
class NamedParametersOut2,
class NamedParametersOut3>
cpp11::array<bool,4>
boolean_operation( TriangleMesh& tm1,
TriangleMesh& tm2,
const cpp11::array< boost::optional<TriangleMesh*>,4>& desired_output,
const NamedParameters1& np1,
const NamedParameters2& np2,
const cpp11::tuple<NamedParametersOut0,
NamedParametersOut1,
NamedParametersOut2,
NamedParametersOut3>& nps_out,
const bool throw_on_self_intersection = false )
corefine_and_compute_boolean_operations(
TriangleMesh& tm1,
TriangleMesh& tm2,
const cpp11::array< boost::optional<TriangleMesh*>,4>& output,
const NamedParameters1& np1,
const NamedParameters2& np2,
const cpp11::tuple<NamedParametersOut0,
NamedParametersOut1,
NamedParametersOut2,
NamedParametersOut3>& nps_out,
const bool throw_on_self_intersection = false )
{
// Vertex point maps
//for input meshes
typedef typename GetVertexPointMap<TriangleMesh,
@ -318,32 +318,32 @@ boolean_operation( TriangleMesh& tm1,
// for now edges in a coplanar patch are not constrained so there is nothing to constrained here
// \todo marked edges from input to output are not ported
if (desired_output[Corefinement::UNION] != boost::none)
if (&tm1 != *desired_output[Corefinement::UNION])
if (output[Corefinement::UNION] != boost::none)
if (&tm1 != *output[Corefinement::UNION])
copy_face_graph(tm1,
*(*desired_output[Corefinement::UNION]),
*(*output[Corefinement::UNION]),
Emptyset_iterator(),
Emptyset_iterator(),
Emptyset_iterator(),
vpm1,
vpm_out[Corefinement::UNION]);
if (desired_output[Corefinement::INTER] != boost::none)
if (&tm1 != *desired_output[Corefinement::INTER])
if (output[Corefinement::INTERSECTION] != boost::none)
if (&tm1 != *output[Corefinement::INTERSECTION])
copy_face_graph(tm1,
*(*desired_output[Corefinement::INTER]),
*(*output[Corefinement::INTERSECTION]),
Emptyset_iterator(),
Emptyset_iterator(),
Emptyset_iterator(),
vpm1,
vpm_out[Corefinement::INTER]);
vpm_out[Corefinement::INTERSECTION]);
if (desired_output[Corefinement::TM1_MINUS_TM2] != boost::none)
if (&tm1 == *desired_output[Corefinement::TM1_MINUS_TM2])
if (output[Corefinement::TM1_MINUS_TM2] != boost::none)
if (&tm1 == *output[Corefinement::TM1_MINUS_TM2])
clear(tm1);
if (desired_output[Corefinement::TM2_MINUS_TM1] != boost::none)
if (&tm1 == *desired_output[Corefinement::TM2_MINUS_TM1])
if (output[Corefinement::TM2_MINUS_TM1] != boost::none)
if (&tm1 == *output[Corefinement::TM2_MINUS_TM1])
clear(tm1);
return CGAL::make_array(true, true, true, true);
@ -419,7 +419,7 @@ boolean_operation( TriangleMesh& tm1,
Ecm_in ecm_in(tm1,tm2,ecm1,ecm2);
Edge_mark_map_tuple ecms_out(ecm_out_0, ecm_out_1, ecm_out_2, ecm_out_3);
Ob ob(tm1, tm2, vpm1, vpm2, fid_map1, fid_map2, ecm_in,
output_vpms, ecms_out, nfv, desired_output);
output_vpms, ecms_out, nfv, output);
Corefinement::Intersection_of_triangle_meshes<TriangleMesh,Vpm,Visitor >
functor(tm1, tm2, vpm1, vpm2, Visitor(dnv,nfv,ob,ecm_in));
@ -434,17 +434,18 @@ boolean_operation( TriangleMesh& tm1,
template <class TriangleMesh>
cpp11::array<bool,4>
boolean_operation( TriangleMesh& tm1,
TriangleMesh& tm2,
const cpp11::array< boost::optional<TriangleMesh*>,4>& desired_output,
const bool throw_on_self_intersection = false )
corefine_and_compute_boolean_operations(
TriangleMesh& tm1,
TriangleMesh& tm2,
const cpp11::array< boost::optional<TriangleMesh*>,4>& output,
const bool throw_on_self_intersection = false )
{
using namespace CGAL::Polygon_mesh_processing::parameters;
return boolean_operation(tm1, tm2, desired_output,
all_default(), all_default(),
cpp11::make_tuple(all_default(), all_default(),
all_default(), all_default()),
throw_on_self_intersection);
return corefine_and_compute_boolean_operations(tm1, tm2, output,
all_default(), all_default(),
cpp11::make_tuple(all_default(), all_default(),
all_default(), all_default()),
throw_on_self_intersection);
}
#undef CGAL_COREF_SET_OUTPUT_VERTEX_POINT_MAP
@ -527,16 +528,16 @@ corefine_and_compute_union( TriangleMesh& tm1,
const NamedParametersOut& np_out)
{
using namespace CGAL::Polygon_mesh_processing::parameters;
cpp11::array< boost::optional<TriangleMesh*>,4> desired_output;
desired_output[Corefinement::UNION]=&tm_out;
cpp11::array< boost::optional<TriangleMesh*>,4> output;
output[Corefinement::UNION]=&tm_out;
return
boolean_operation(tm1, tm2, desired_output, np1, np2,
cpp11::make_tuple(np_out,
no_parameters(np_out),
no_parameters(np_out),
no_parameters(np_out)))
[Corefinement::UNION];
corefine_and_compute_boolean_operations(tm1, tm2, output, np1, np2,
cpp11::make_tuple(np_out,
no_parameters(np_out),
no_parameters(np_out),
no_parameters(np_out)))
[Corefinement::UNION];
}
/**
@ -559,16 +560,16 @@ corefine_and_compute_intersection( TriangleMesh& tm1,
const NamedParametersOut& np_out)
{
using namespace CGAL::Polygon_mesh_processing::parameters;
cpp11::array< boost::optional<TriangleMesh*>,4> desired_output;
desired_output[Corefinement::INTER]=&tm_out;
cpp11::array< boost::optional<TriangleMesh*>,4> output;
output[Corefinement::INTERSECTION]=&tm_out;
return
boolean_operation(tm1, tm2, desired_output, np1, np2,
cpp11::make_tuple(no_parameters(np_out),
np_out,
no_parameters(np_out),
no_parameters(np_out)))
[Corefinement::INTER];
corefine_and_compute_boolean_operations(tm1, tm2, output, np1, np2,
cpp11::make_tuple(no_parameters(np_out),
np_out,
no_parameters(np_out),
no_parameters(np_out)))
[Corefinement::INTERSECTION];
}
/**
@ -592,15 +593,16 @@ corefine_and_compute_difference( TriangleMesh& tm1,
{
using namespace CGAL::Polygon_mesh_processing::parameters;
using namespace CGAL::Polygon_mesh_processing::Corefinement;
cpp11::array< boost::optional<TriangleMesh*>,4> desired_output;
desired_output[TM1_MINUS_TM2]=&tm_out;
cpp11::array< boost::optional<TriangleMesh*>,4> output;
output[TM1_MINUS_TM2]=&tm_out;
return
boolean_operation(tm1, tm2, desired_output, np1, np2,
cpp11::make_tuple(no_parameters(np_out),
no_parameters(np_out),
np_out,
no_parameters(np_out)))[TM1_MINUS_TM2];
corefine_and_compute_boolean_operations(tm1, tm2, output, np1, np2,
cpp11::make_tuple(no_parameters(np_out),
no_parameters(np_out),
np_out,
no_parameters(np_out)))
[TM1_MINUS_TM2];
}
/**

View File

@ -47,9 +47,8 @@ namespace CGAL {
namespace Polygon_mesh_processing {
namespace Corefinement {
enum Boolean_operation {UNION = 0, INTER,
TM1_MINUS_TM2, TM2_MINUS_TM1,
NONE };
enum Boolean_operation {UNION = 0, INTERSECTION,
TM1_MINUS_TM2, TM2_MINUS_TM1, NONE };
namespace PMP=Polygon_mesh_processing;
namespace params=PMP::parameters;
@ -115,7 +114,7 @@ class Face_graph_output_builder
EdgeMarkMapTuple& out_edge_mark_maps;
NewFaceVisitor& new_face_visitor;
// output meshes
const cpp11::array<boost::optional<TriangleMesh*>, 4>& desired_output;
const cpp11::array<boost::optional<TriangleMesh*>, 4>& requested_output;
// input meshes closed ?
/// \todo do we really need this?
bool is_tm1_closed;
@ -345,7 +344,7 @@ public:
EdgeMarkMapTuple& out_edge_mark_maps,
NewFaceVisitor& new_face_visitor,
const cpp11::array<
boost::optional<TriangleMesh*>, 4 >& desired_output)
boost::optional<TriangleMesh*>, 4 >& requested_output)
: tm1(tm1), tm2(tm2)
, vpm1(vpm1), vpm2(vpm2)
, fids1(fids1), fids2(fids2)
@ -353,7 +352,7 @@ public:
, output_vpms(output_vpms)
, out_edge_mark_maps(out_edge_mark_maps)
, new_face_visitor(new_face_visitor)
, desired_output(desired_output)
, requested_output(requested_output)
, is_tm1_closed( is_closed(tm1))
, is_tm2_closed( is_closed(tm2))
, is_tm1_inside_out( is_tm1_closed && !PMP::is_outward_oriented(tm1) )
@ -368,7 +367,7 @@ public:
}
bool intersection_is_valid() const
{
return !impossible_operation[INTER];
return !impossible_operation[INTERSECTION];
}
bool tm1_minus_tm2_is_valid() const
{
@ -859,7 +858,7 @@ public:
// opposite( poly_first U poly_second ) = {O}
is_patch_inside_tm2.set(patch_id_p1);
is_patch_inside_tm2.set(patch_id_p2);
impossible_operation.set(INTER); // tm1 n tm2 is non-manifold
impossible_operation.set(INTERSECTION); // tm1 n tm2 is non-manifold
}
}
else
@ -1110,7 +1109,7 @@ public:
std::vector< boost::dynamic_bitset<> > patches_of_tm2_used(4);
/// handle the bitset for the union
if ( !impossible_operation.test(UNION) && desired_output[UNION] )
if ( !impossible_operation.test(UNION) && requested_output[UNION] )
{
//define patches to import from P
patches_of_tm1_used[UNION] = ~is_patch_inside_tm2 - coplanar_patches_of_tm1;
@ -1119,7 +1118,7 @@ public:
//handle coplanar patches
if (coplanar_patches_of_tm1.any())
{
if (desired_output[UNION]==&tm2)
if (requested_output[UNION]==&tm2)
patches_of_tm2_used[UNION] |= coplanar_patches_of_tm2_for_union_and_intersection;
else
patches_of_tm1_used[UNION] |= coplanar_patches_of_tm1_for_union_and_intersection;
@ -1127,24 +1126,24 @@ public:
}
/// handle the bitset for the intersection
if ( !impossible_operation.test(INTER) && desired_output[INTER] )
if ( !impossible_operation.test(INTERSECTION) && requested_output[INTERSECTION] )
{
//define patches to import from P
patches_of_tm1_used[INTER] = is_patch_inside_tm2;
patches_of_tm1_used[INTERSECTION] = is_patch_inside_tm2;
//define patches to import from Q
patches_of_tm2_used[INTER] = is_patch_inside_tm1;
patches_of_tm2_used[INTERSECTION] = is_patch_inside_tm1;
//handle coplanar patches
if (coplanar_patches_of_tm1.any())
{
if (desired_output[INTER]==&tm2)
patches_of_tm2_used[INTER] |= coplanar_patches_of_tm2_for_union_and_intersection;
if (requested_output[INTERSECTION]==&tm2)
patches_of_tm2_used[INTERSECTION] |= coplanar_patches_of_tm2_for_union_and_intersection;
else
patches_of_tm1_used[INTER] |= coplanar_patches_of_tm1_for_union_and_intersection;
patches_of_tm1_used[INTERSECTION] |= coplanar_patches_of_tm1_for_union_and_intersection;
}
}
/// handle the bitset for P-Q
if ( !impossible_operation.test(TM1_MINUS_TM2) && desired_output[TM1_MINUS_TM2] )
if ( !impossible_operation.test(TM1_MINUS_TM2) && requested_output[TM1_MINUS_TM2] )
{
//define patches to import from P
patches_of_tm1_used[TM1_MINUS_TM2] = (~is_patch_inside_tm2 - coplanar_patches_of_tm1);
@ -1153,7 +1152,7 @@ public:
//handle coplanar patches
if (coplanar_patches_of_tm1.any())
{
if (desired_output[TM1_MINUS_TM2]==&tm2)
if (requested_output[TM1_MINUS_TM2]==&tm2)
patches_of_tm2_used[TM1_MINUS_TM2] |= ~coplanar_patches_of_tm2_for_union_and_intersection & coplanar_patches_of_tm2;
else
patches_of_tm1_used[TM1_MINUS_TM2] |= ~coplanar_patches_of_tm1_for_union_and_intersection & coplanar_patches_of_tm1;
@ -1161,7 +1160,7 @@ public:
}
/// handle the bitset for Q-P
if ( !impossible_operation.test(TM2_MINUS_TM1) && desired_output[TM2_MINUS_TM1] )
if ( !impossible_operation.test(TM2_MINUS_TM1) && requested_output[TM2_MINUS_TM1] )
{
//define patches to import from P
patches_of_tm1_used[TM2_MINUS_TM1] = is_patch_inside_tm2;
@ -1170,7 +1169,7 @@ public:
//handle coplanar patches
if (coplanar_patches_of_tm1.any())
{
if (desired_output[TM2_MINUS_TM1]==&tm2)
if (requested_output[TM2_MINUS_TM1]==&tm2)
patches_of_tm2_used[TM2_MINUS_TM1] |= ~coplanar_patches_of_tm2_for_union_and_intersection & coplanar_patches_of_tm2;
else
patches_of_tm1_used[TM2_MINUS_TM1] |= ~coplanar_patches_of_tm1_for_union_and_intersection & coplanar_patches_of_tm1;
@ -1181,8 +1180,8 @@ public:
#ifdef CGAL_COREFINEMENT_DEBUG
std::cout << "patches_of_tm1_used[UNION] " << patches_of_tm1_used[UNION] << "\n";
std::cout << "patches_of_tm2_used[UNION] " << patches_of_tm2_used[UNION] << "\n";
std::cout << "patches_of_tm1_used[INTER] " << patches_of_tm1_used[INTER] << "\n";
std::cout << "patches_of_tm2_used[INTER] " << patches_of_tm2_used[INTER] << "\n";
std::cout << "patches_of_tm1_used[INTERSECTION] " << patches_of_tm1_used[INTERSECTION] << "\n";
std::cout << "patches_of_tm2_used[INTERSECTION] " << patches_of_tm2_used[INTERSECTION] << "\n";
std::cout << "patches_of_tm1_used[TM1_MINUS_TM2] " << patches_of_tm1_used[TM1_MINUS_TM2] << "\n";
std::cout << "patches_of_tm2_used[TM1_MINUS_TM2] " << patches_of_tm2_used[TM1_MINUS_TM2] << "\n";
std::cout << "patches_of_tm1_used[TM2_MINUS_TM1] " << patches_of_tm1_used[TM2_MINUS_TM1] << "\n";
@ -1199,13 +1198,13 @@ public:
{
Boolean_operation operation=enum_cast<Boolean_operation>(i);
if (!desired_output[operation] || impossible_operation.test(operation))
if (!requested_output[operation] || impossible_operation.test(operation))
continue;
if (desired_output[operation]==&tm1)
if (requested_output[operation]==&tm1)
inplace_operation_tm1=operation;
else
if (desired_output[operation]==&tm2)
if (requested_output[operation]==&tm2)
inplace_operation_tm2=operation;
else
out_of_place_operations.push_back(operation);
@ -1214,7 +1213,7 @@ public:
/// first handle operations in a mesh that is neither tm1 nor tm2
BOOST_FOREACH(Boolean_operation operation, out_of_place_operations)
{
TriangleMesh& output = *(*desired_output[operation]);
TriangleMesh& output = *(*requested_output[operation]);
CGAL_assertion(&tm1!=&output && &tm2!=&output);
Intersection_polylines polylines(tm1_polylines,
@ -1256,7 +1255,7 @@ public:
mesh_to_intersection_edges[&tm1],
inplace_operation_tm1);
CGAL_assertion( *desired_output[inplace_operation_tm1] == &tm1 );
CGAL_assertion( *requested_output[inplace_operation_tm1] == &tm1 );
if ( inplace_operation_tm2!=NONE)
{
@ -1323,7 +1322,7 @@ public:
disconnected_patches_edge_to_tm2_edge,
new_face_visitor);
// Operation in tm2: discard patches and append the one from tm2
CGAL_assertion( *desired_output[inplace_operation_tm2] == &tm2 );
CGAL_assertion( *requested_output[inplace_operation_tm2] == &tm2 );
compute_inplace_operation( tm2, tm1,
patches_of_tm2_used[inplace_operation_tm2],
patches_of_tm1_used[inplace_operation_tm2],
@ -1363,7 +1362,7 @@ public:
}
else{
/// handle the operation updating only tm1
CGAL_assertion( *desired_output[inplace_operation_tm1] == &tm1 );
CGAL_assertion( *requested_output[inplace_operation_tm1] == &tm1 );
Intersection_polylines polylines(
tm1_polylines, tm2_polylines, polyline_lengths);
fill_polylines_to_skip(
@ -1403,7 +1402,7 @@ public:
inplace_operation_tm2);
/// handle the operation updating only tm2
CGAL_assertion( *desired_output[inplace_operation_tm2] == &tm2 );
CGAL_assertion( *requested_output[inplace_operation_tm2] == &tm2 );
Intersection_polylines polylines(
tm2_polylines, tm1_polylines, polyline_lengths);
fill_polylines_to_skip(

View File

@ -166,24 +166,24 @@ void test_bool_op_no_copy(
typedef boost::optional<Triangle_mesh*> OTM;
OTM none;
const CGAL::cpp11::array<OTM,4> desired_output =
const CGAL::cpp11::array<OTM,4> output =
reverse ? CGAL::make_array(OTM(&tm2), OTM(&tm1), none, none)
: CGAL::make_array(OTM(&tm1), OTM(&tm2), none, none);
PMP::boolean_operation(tm1,
tm2,
desired_output,
params::edge_is_constrained_map(ecm1),
params::edge_is_constrained_map(ecm2),
CGAL::cpp11::make_tuple(params::edge_is_constrained_map(ecm_out_union),
params::edge_is_constrained_map(ecm_out_inter),
params::no_parameters(params::edge_is_constrained_map(ecm_out_union)),
params::no_parameters(params::edge_is_constrained_map(ecm_out_union))));
PMP::corefine_and_compute_boolean_operations(tm1,
tm2,
output,
params::edge_is_constrained_map(ecm1),
params::edge_is_constrained_map(ecm2),
CGAL::cpp11::make_tuple(params::edge_is_constrained_map(ecm_out_union),
params::edge_is_constrained_map(ecm_out_inter),
params::no_parameters(params::edge_is_constrained_map(ecm_out_union)),
params::no_parameters(params::edge_is_constrained_map(ecm_out_union))));
// dump_constrained_edges(*(*desired_output[0]), ecm_out_union, "out_cst_union.cgal");
// dump_constrained_edges(*(*desired_output[1]), ecm_out_inter, "out_cst_inter.cgal");
// dump_constrained_edges(*(*output[0]), ecm_out_union, "out_cst_union.cgal");
// dump_constrained_edges(*(*output[1]), ecm_out_inter, "out_cst_inter.cgal");
assert( count_constrained_edges(*(*desired_output[0]), ecm_out_union)==838 );
assert( count_constrained_edges(*(*desired_output[1]), ecm_out_inter)==475 );
assert( count_constrained_edges(*(*output[0]), ecm_out_union)==838 );
assert( count_constrained_edges(*(*output[1]), ecm_out_inter)==475 );
}
void test_bool_op(Triangle_mesh tm1, Triangle_mesh tm2, bool reverse, const char* outname)

View File

@ -65,15 +65,15 @@ void run_boolean_operations(
CGAL::Emptyset_iterator output_it;
Facet_id_map P_facet_id_map, Q_facet_id_map;
CGAL::cpp11::array<boost::optional<Polyhedron*>, 4 > desired_output;
CGAL::cpp11::array<boost::optional<Polyhedron*>, 4 > output;
desired_output[Output_builder::P_UNION_Q]=boost::make_optional( &union_ );
desired_output[Output_builder::P_INTER_Q]=boost::make_optional( &inter );
desired_output[Output_builder::P_MINUS_Q]=boost::make_optional( &P_minus_Q );
desired_output[Output_builder::Q_MINUS_P]=boost::make_optional( &Q_minus_P );
output[Output_builder::P_UNION_Q]=boost::make_optional( &union_ );
output[Output_builder::P_INTER_Q]=boost::make_optional( &inter );
output[Output_builder::P_MINUS_Q]=boost::make_optional( &P_minus_Q );
output[Output_builder::Q_MINUS_P]=boost::make_optional( &Q_minus_P );
Output_builder output_builder(P, Q,
desired_output,
output,
Facet_id_pmap(P_facet_id_map),
Facet_id_pmap(Q_facet_id_map) );
Split_visitor visitor(output_builder);
@ -169,17 +169,17 @@ void run_boolean_operations(
typedef boost::optional<Surface_mesh*> OSM;
CGAL::cpp11::array<OSM,4> desired_output;
CGAL::cpp11::array<OSM,4> output;
desired_output[CFR::UNION]=OSM( &union_ );
desired_output[CFR::INTER]=OSM( &inter );
desired_output[CFR::TM1_MINUS_TM2]=OSM( &tm1_minus_tm2 );
desired_output[CFR::TM2_MINUS_TM1]=OSM( &tm2_minus_tm1 );
output[CFR::UNION]=OSM( &union_ );
output[CFR::INTERSECTION]=OSM( &inter );
output[CFR::TM1_MINUS_TM2]=OSM( &tm1_minus_tm2 );
output[CFR::TM2_MINUS_TM1]=OSM( &tm2_minus_tm1 );
std::cout << " Vertices before " << tm1.number_of_vertices()
<< " " << tm2.number_of_vertices() << std::endl;
CGAL::cpp11::array<bool,4> res = PMP::boolean_operation(tm1, tm2, desired_output);
CGAL::cpp11::array<bool,4> res = PMP::corefine_and_compute_boolean_operations(tm1, tm2, output);
std::cout << " Vertices after " << tm1.number_of_vertices()
<< " " << tm2.number_of_vertices() << std::endl;
@ -197,7 +197,7 @@ void run_boolean_operations(
else
std::cout << " Union is invalid\n";
if ( res[CFR::INTER] ){
if ( res[CFR::INTERSECTION] ){
std::cout << " Intersection is a valid operation\n";
assert(inter.is_valid());
#ifdef CGAL_COREFINEMENT_DEBUG
@ -239,7 +239,7 @@ void run_boolean_operations(
if ( rc.check )
{
if (res[CFR::UNION]!=rc.union_res ||
res[CFR::INTER]!=rc.inter_res ||
res[CFR::INTERSECTION]!=rc.inter_res ||
res[CFR::TM1_MINUS_TM2]!=rc.P_minus_Q_res ||
res[CFR::TM2_MINUS_TM1]!=rc.Q_minus_P_res)
{