Merge pull request #6845 from sloriot/PMP-coref_open_mesh_case

PMP corefinement: Handle inconsistency with open mesh as input
This commit is contained in:
Laurent Rineau 2022-10-04 13:50:24 +02:00
commit a4f6f58e25
5 changed files with 188 additions and 12 deletions

View File

@ -1037,6 +1037,54 @@ public:
std::size_t patch_id_q1=tm2_patch_ids[ get(fids2, face(opposite(h2,tm2),tm2)) ];
std::size_t patch_id_q2=tm2_patch_ids[ get(fids2, face(h2,tm2)) ];
// info on whether the patches were already classified
std::bitset<4> patch_status_was_not_already_set;
std::bitset<4> previous_bitvalue;
// info for tm1
patch_status_was_not_already_set[0] = patch_status_not_set_tm1.test(patch_id_p1);
patch_status_was_not_already_set[1] = patch_status_not_set_tm1.test(patch_id_p2);
previous_bitvalue[0] = is_patch_inside_tm2.test(patch_id_p1);
previous_bitvalue[1] = is_patch_inside_tm2.test(patch_id_p2);
// info for tm2
patch_status_was_not_already_set[2] = patch_status_not_set_tm2.test(patch_id_q1);
patch_status_was_not_already_set[3] = patch_status_not_set_tm2.test(patch_id_q2);
previous_bitvalue[2] = is_patch_inside_tm1.test(patch_id_q1);
previous_bitvalue[3] = is_patch_inside_tm1.test(patch_id_q2);
#ifndef CGAL_NDEBUG
if (is_tm1_closed && is_tm2_closed)
{
if (!patch_status_was_not_already_set[0] &&
!patch_status_was_not_already_set[1] &&
!patch_status_was_not_already_set[2] &&
!patch_status_was_not_already_set[3])
continue; // all patches were already classified, no need to redo it
}
#endif
// check incompatibility of patch classifications
auto inconsistent_classification = [&]()
{
if (!used_to_clip_a_surface && !used_to_classify_patches && (!is_tm1_closed || !is_tm2_closed))
{
//make sure there is no ambiguity in tm1
if( (patch_status_was_not_already_set[0] && previous_bitvalue[0]!=is_patch_inside_tm2[patch_id_p1] ) ||
(patch_status_was_not_already_set[1] && previous_bitvalue[1]!=is_patch_inside_tm2[patch_id_p2] ) )
{
impossible_operation.set();
return true;
}
//make sure there is no ambiguity in tm2
if( (patch_status_was_not_already_set[2] && previous_bitvalue[2]!=is_patch_inside_tm2[patch_id_q1] ) ||
(patch_status_was_not_already_set[3] && previous_bitvalue[3]!=is_patch_inside_tm2[patch_id_q2] ) )
{
impossible_operation.set();
return true;
}
}
return false;
};
//indicates that patch status will be updated
patch_status_not_set_tm1.reset(patch_id_p1);
patch_status_not_set_tm1.reset(patch_id_p2);
@ -1082,6 +1130,7 @@ public:
if ( q2_is_between_p1p2 ) is_patch_inside_tm1.set(patch_id_q2); //case 1
else is_patch_inside_tm2.set(patch_id_p2); //case 2
if (inconsistent_classification()) return;
continue;
}
else{
@ -1112,6 +1161,7 @@ public:
is_patch_inside_tm1.set(patch_id_q1);
is_patch_inside_tm2.set(patch_id_p2);
} //else case 4
if (inconsistent_classification()) return;
continue;
}
else
@ -1142,6 +1192,7 @@ public:
is_patch_inside_tm1.set(patch_id_q2);
is_patch_inside_tm2.set(patch_id_p1);
} // else case 6
if (inconsistent_classification()) return;
continue;
}
else{
@ -1170,6 +1221,7 @@ public:
if ( q1_is_between_p1p2 ) is_patch_inside_tm1.set(patch_id_q1); //case 7
else is_patch_inside_tm2.set(patch_id_p1); //case 8
if (inconsistent_classification()) return;
continue;
}
}
@ -1331,6 +1383,11 @@ public:
}
}
}
if (inconsistent_classification()) return;
CGAL_assertion( patch_status_was_not_already_set[0] || previous_bitvalue[0]==is_patch_inside_tm2[patch_id_p1] );
CGAL_assertion( patch_status_was_not_already_set[1] || previous_bitvalue[1]==is_patch_inside_tm2[patch_id_p2] );
CGAL_assertion( patch_status_was_not_already_set[2] || previous_bitvalue[2]==is_patch_inside_tm1[patch_id_q1] );
CGAL_assertion( patch_status_was_not_already_set[3] || previous_bitvalue[3]==is_patch_inside_tm1[patch_id_q2] );
}
}

View File

@ -780,6 +780,7 @@ struct Patch_container{
Patch_description<PolygonMesh>& patch=this->operator[](i);
std::stringstream ss;
ss.precision(17);
std::map<vertex_descriptor, int> vertexid;
int id=0;
for(vertex_descriptor vh : patch.interior_vertices)

View File

@ -0,0 +1,96 @@
OFF
32 60 0
30 120 60
30 120 30
70 60 30
60 120 60
70 60 60
60 120 30
70 40 30
130 60 30
70 40 60
30 -20 60
60 -20 60
30 -40 60
30 -40 30
130 60 60
60 -20 30
30 -20 30
160 60 60
160 -20 60
60 -40 60
60 -40 30
130 -20 60
130 -20 30
160 -20 30
130 40 60
130 40 30
160 -40 30
160 40 30
130 -40 30
160 40 60
130 -40 60
160 -40 60
160 60 30
3 1 0 5
3 0 9 3
3 10 14 3
3 5 0 3
3 0 15 9
3 3 14 5
3 5 15 1
3 14 15 5
3 1 15 0
3 3 9 10
3 19 18 11
3 9 18 10
3 12 11 15
3 12 19 11
3 14 19 15
3 19 12 15
3 15 11 9
3 11 18 9
3 10 21 14
3 19 29 18
3 23 8 24
3 19 27 29
3 6 24 8
3 18 29 10
3 2 4 13
3 29 20 10
3 27 19 21
3 14 21 19
3 29 30 17
3 22 25 21
3 25 22 17
3 21 25 27
3 29 17 20
3 30 25 17
3 25 30 29
3 27 25 29
3 22 28 17
3 4 2 8
3 17 28 20
3 20 23 24
3 26 28 22
3 21 24 22
3 23 20 28
3 24 26 22
3 28 16 23
3 31 26 7
3 26 31 16
3 24 7 26
3 13 23 16
3 31 7 16
3 26 16 28
3 7 13 16
3 13 8 23
3 24 2 7
3 2 6 8
3 24 6 2
3 4 8 13
3 7 2 13
3 20 24 21
3 21 10 20

View File

@ -1 +1,2 @@
${CGAL_DATA_DIR}/meshes/elephant.off ${CGAL_DATA_DIR}/meshes/sphere.off ALL 1 1 1 1
${CGAL_DATA_DIR}/meshes/open_cube.off data-coref/incompatible_with_open_cube.off ALL 0 0 0 0

View File

@ -272,22 +272,43 @@ int main(int argc,char** argv)
return 1;
}
Result_checking rc;
if (argc==8)
if (argc>8 && (argc-1)%7==0)
{
rc.check=true;
rc.union_res = atoi(argv[4])!=0;
rc.inter_res = atoi(argv[5])!=0;
rc.P_minus_Q_res = atoi(argv[6])!=0;
rc.Q_minus_P_res = atoi(argv[7])!=0;
// cmd mode
for (int i=0;i<argc-1;i+=7)
{
std::cout << "Running test #" << (i/7)+1 << "\n";
Result_checking rc;
rc.check=true;
rc.union_res = atoi(argv[i+4])!=0;
rc.inter_res = atoi(argv[i+5])!=0;
rc.P_minus_Q_res = atoi(argv[i+6])!=0;
rc.Q_minus_P_res = atoi(argv[i+7])!=0;
int scenario = -1;
if (std::string(argv[i+3])!=std::string("ALL"))
scenario = atoi(argv[i+3]);
run<Surface_mesh>(argv[i+1], argv[i+2], scenario, rc);
}
}
else
{
Result_checking rc;
int scenario = -1;
if (argc>=5 && std::string(argv[3])!=std::string("ALL"))
scenario = atoi(argv[4]);
if (argc==8)
{
rc.check=true;
rc.union_res = atoi(argv[4])!=0;
rc.inter_res = atoi(argv[5])!=0;
rc.P_minus_Q_res = atoi(argv[6])!=0;
rc.Q_minus_P_res = atoi(argv[7])!=0;
}
run<Surface_mesh>(argv[1], argv[2], scenario, rc);
int scenario = -1;
if (argc>=5 && std::string(argv[3])!=std::string("ALL"))
scenario = atoi(argv[3]);
run<Surface_mesh>(argv[1], argv[2], scenario, rc);
}
return 0;
}