mirror of https://github.com/CGAL/cgal
Test code fixes
This commit is contained in:
parent
a7a9cc0660
commit
a43b79a69f
|
|
@ -22,6 +22,7 @@
|
|||
#include <CGAL/Polygon_mesh_processing/measure.h>
|
||||
#include <CGAL/Polygon_mesh_processing/orientation.h>
|
||||
#include <CGAL/Polygon_mesh_processing/repair.h>
|
||||
#include <CGAL/Polygon_mesh_processing/repair_polygon_soup.h>
|
||||
#include <CGAL/Side_of_triangle_mesh.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
|
@ -124,6 +125,22 @@ bool is_valid_wrap(const TriangleMesh& wrap,
|
|||
{
|
||||
namespace PMP = CGAL::Polygon_mesh_processing;
|
||||
|
||||
if(is_empty(wrap))
|
||||
{
|
||||
#ifdef CGAL_AW3_DEBUG
|
||||
std::cerr << "Error: empty wrap" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!is_valid_polygon_mesh(wrap))
|
||||
{
|
||||
#ifdef CGAL_AW3_DEBUG
|
||||
std::cerr << "Error: Invalid wrap mesh" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!is_triangle_mesh(wrap))
|
||||
{
|
||||
#ifdef CGAL_AW3_DEBUG
|
||||
|
|
@ -134,8 +151,24 @@ bool is_valid_wrap(const TriangleMesh& wrap,
|
|||
|
||||
if(!is_closed(wrap))
|
||||
{
|
||||
if(check_manifoldness)
|
||||
{
|
||||
#ifdef CGAL_AW3_DEBUG
|
||||
std::cerr << "Error: Wrap is not closed" << std::endl;
|
||||
std::cerr << "Error: Wrap is not closed" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef CGAL_AW3_DEBUG
|
||||
std::cerr << "W: Wrap is not closed" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if(!PMP::does_bound_a_volume(wrap, np))
|
||||
{
|
||||
#ifdef CGAL_AW3_DEBUG
|
||||
std::cerr << "Error: Wrap does not bound a volume" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
|
@ -166,18 +199,10 @@ bool is_valid_wrap(const TriangleMesh& wrap,
|
|||
return false;
|
||||
}
|
||||
#ifdef CGAL_AW3_DEBUG
|
||||
std::cerr << "Warning: Wrap self-intersects" << std::endl;
|
||||
std::cerr << "W: Wrap self-intersects" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
if(!PMP::does_bound_a_volume(wrap, np))
|
||||
{
|
||||
#ifdef CGAL_AW3_DEBUG
|
||||
std::cerr << "Error: Wrap does not bound a volume" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -268,6 +293,7 @@ bool is_outer_wrap_of_triangle_soup(const TriangleMesh& wrap,
|
|||
namespace PMP = CGAL::Polygon_mesh_processing;
|
||||
|
||||
// Make a mesh out of the soup
|
||||
PMP::repair_polygon_soup(points, faces);
|
||||
PMP::orient_polygon_soup(points, faces);
|
||||
CGAL_assertion(PMP::is_polygon_soup_a_polygon_mesh(faces));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#define CGAL_AW3_TIMER
|
||||
#define CGAL_AW3_DEBUG
|
||||
#define CGAL_AW3_DEBUG_INITIALIZATION
|
||||
// #define CGAL_AW3_DEBUG_INITIALIZATION
|
||||
|
||||
#include <CGAL/Surface_mesh.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
|
|
@ -21,24 +21,21 @@ using Mesh = CGAL::Surface_mesh<Point_3>;
|
|||
|
||||
using Seeds = std::vector<Point_3>;
|
||||
|
||||
Point_3 generate_point(const CGAL::Bbox_3 bbox,
|
||||
CGAL::Random& r)
|
||||
{
|
||||
return Point_3(bbox.xmin() + bbox.x_span() * r.get_double(),
|
||||
bbox.ymin() + bbox.y_span() * r.get_double(),
|
||||
bbox.zmin() + bbox.z_span() * r.get_double());
|
||||
}
|
||||
|
||||
template <typename Oracle>
|
||||
void generate_random_seeds(const Oracle& oracle,
|
||||
const double offset,
|
||||
Seeds& seeds,
|
||||
CGAL::Random& r)
|
||||
{
|
||||
auto sq_offset = CGAL::square(offset);
|
||||
const auto bbox = CGAL::Alpha_wraps_3::internal::Alpha_wrap_3<Oracle>(oracle).construct_bbox(offset);
|
||||
const double sq_offset = CGAL::square(offset);
|
||||
|
||||
while(seeds.size() < 3)
|
||||
{
|
||||
const Point_3 seed = generate_point(oracle.bbox(), r);
|
||||
const Point_3 seed (bbox.xmin() + r.get_double(0., 1.) * (bbox.xmax() - bbox.xmin()),
|
||||
bbox.ymin() + r.get_double(0., 1.) * (bbox.ymax() - bbox.ymin()),
|
||||
bbox.zmin() + r.get_double(0., 1.) * (bbox.zmax() - bbox.zmin()));
|
||||
|
||||
const FT sqd = oracle.squared_distance(seed);
|
||||
#ifdef CGAL_AW3_DEBUG
|
||||
std::cout << "Generate " << seed << " at squared distance " << sqd << " (sqo: " << sq_offset << ")" << std::endl;
|
||||
|
|
@ -66,6 +63,7 @@ void alpha_wrap_triangle_mesh(Mesh& input_mesh,
|
|||
if(has_degeneracies)
|
||||
std::cerr << "Warning: Failed to remove some degenerate faces." << std::endl;
|
||||
|
||||
std::cout << "Processed input: " << vertices(input_mesh).size() << " vertices, " << faces(input_mesh).size() << " faces" << std::endl;
|
||||
// CGAL::IO::write_polygon_mesh("input.off", input_mesh, CGAL::parameters::stream_precision(17));
|
||||
|
||||
Oracle oracle;
|
||||
|
|
@ -81,23 +79,32 @@ void alpha_wrap_triangle_mesh(Mesh& input_mesh,
|
|||
|
||||
assert(!seeds.empty());
|
||||
|
||||
const bool enforce_manifoldness = true;
|
||||
|
||||
Mesh wrap;
|
||||
aw3(alpha, offset, wrap,
|
||||
CGAL::parameters::seed_points(std::ref(seeds))
|
||||
.do_enforce_manifoldness(true));
|
||||
.do_enforce_manifoldness(enforce_manifoldness));
|
||||
|
||||
std::cout << "Result: " << vertices(wrap).size() << " vertices, " << faces(wrap).size() << " faces" << std::endl;
|
||||
|
||||
// Tolerate failed initialization since we use random seeds and it's difficult to guarantee it
|
||||
if(is_empty(wrap))
|
||||
return;
|
||||
|
||||
// CGAL::IO::write_polygon_mesh("last.off", wrap, CGAL::parameters::stream_precision(17));
|
||||
|
||||
if(!has_degeneracies)
|
||||
{
|
||||
assert(AW3::internal::is_valid_wrap(wrap, true /*manifoldness*/));
|
||||
assert(AW3::internal::is_outer_wrap_of_triangle_mesh(wrap, input_mesh));
|
||||
// assert(AW3::internal::has_expected_Hausdorff_distance(wrap, input_mesh, alpha, offset));
|
||||
|
||||
if(!enforce_manifoldness)
|
||||
assert(AW3::internal::has_expected_Hausdorff_distance(wrap, input_mesh, alpha, offset));
|
||||
}
|
||||
|
||||
// assert(AW3::internal::check_edge_length(wrap, alpha));
|
||||
if(!enforce_manifoldness)
|
||||
assert(AW3::internal::check_edge_length(wrap, alpha));
|
||||
}
|
||||
|
||||
void alpha_wrap_triangle_mesh(Mesh& input_mesh,
|
||||
|
|
@ -125,8 +132,8 @@ void alpha_wrap_triangle_mesh(const std::string& filename)
|
|||
{
|
||||
CGAL::Random r;
|
||||
|
||||
const double alpha_expo = r.get_double(0., 7.5); // to have alpha_rel between 1 and ~200
|
||||
const double offset_expo = r.get_double(0., 7.5);
|
||||
const double alpha_expo = r.get_double(0., 6); // to have alpha_rel between 1 and 64
|
||||
const double offset_expo = r.get_double(0., 6);
|
||||
const double alpha_rel = std::pow(2, alpha_expo);
|
||||
const double offset_rel = std::pow(2, offset_expo);
|
||||
const double alpha = longest_diag_length / alpha_rel;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ void alpha_wrap_triangle_manifoldness(Mesh& input_mesh,
|
|||
namespace PMP = CGAL::Polygon_mesh_processing;
|
||||
|
||||
std::cout << "Input: " << num_vertices(input_mesh) << " vertices, " << num_faces(input_mesh) << " faces" << std::endl;
|
||||
std::cout << "Alpha: " << alpha << " Offset: " << offset << std::endl;
|
||||
|
||||
const bool has_degeneracies = !PMP::remove_degenerate_faces(input_mesh);
|
||||
if(has_degeneracies)
|
||||
|
|
@ -49,9 +50,18 @@ void alpha_wrap_triangle_manifoldness(Mesh& input_mesh,
|
|||
|
||||
std::cout << "Result: " << vertices(nm_wrap).size() << " vertices, " << faces(nm_wrap).size() << " faces" << std::endl;
|
||||
|
||||
if(!has_degeneracies)
|
||||
{
|
||||
assert(AW3::internal::is_valid_wrap(nm_wrap, false));
|
||||
assert(AW3::internal::is_outer_wrap_of_triangle_mesh(nm_wrap, input_mesh));
|
||||
assert(AW3::internal::has_expected_Hausdorff_distance(nm_wrap, input_mesh, alpha, offset));
|
||||
}
|
||||
|
||||
assert(AW3::internal::check_edge_length(nm_wrap, alpha));
|
||||
|
||||
FT base_vol = 0;
|
||||
if(!is_closed(nm_wrap))
|
||||
std::cerr << "Warning: non-manifold wrap is not closed" << std::endl;
|
||||
std::cerr << "W: non-manifold wrap is not closed" << std::endl;
|
||||
else
|
||||
base_vol = PMP::volume(nm_wrap);
|
||||
|
||||
|
|
@ -66,13 +76,8 @@ void alpha_wrap_triangle_manifoldness(Mesh& input_mesh,
|
|||
{
|
||||
assert(AW3::internal::is_valid_wrap(m_wrap, true /*manifoldness*/));
|
||||
assert(AW3::internal::is_outer_wrap_of_triangle_mesh(m_wrap, input_mesh));
|
||||
|
||||
// These assertions might not be honored since we have added material
|
||||
// assert(AW3::internal::has_expected_Hausdorff_distance(m_wrap, input_mesh, alpha, offset));
|
||||
}
|
||||
|
||||
// assert(AW3::internal::check_edge_length(wrap, alpha));
|
||||
|
||||
const FT final_vol = PMP::volume(m_wrap);
|
||||
|
||||
if(base_vol != 0)
|
||||
|
|
@ -84,7 +89,7 @@ void alpha_wrap_triangle_manifoldness(Mesh& input_mesh,
|
|||
<< "after: " << final_vol << "\n"
|
||||
<< "ratio: " << ratio << std::endl;
|
||||
if(ratio > 1.1) // more than 10% extra volume
|
||||
std::cerr << "Warning: large increase of volume after manifoldness resolution" << std::endl;
|
||||
std::cerr << "W: large increase of volume after manifoldness resolution" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -124,8 +129,8 @@ void alpha_wrap_triangle_manifoldness(const std::string& filename)
|
|||
|
||||
for(int i=0; i<2; ++i)
|
||||
{
|
||||
const double alpha_expo = r.get_double(0., 7.5); // to have alpha_rel between 1 and ~200
|
||||
const double offset_expo = r.get_double(0., 7.5);
|
||||
const double alpha_expo = r.get_double(0., 6); // to have alpha_rel between 1 and 64
|
||||
const double offset_expo = r.get_double(0., 6);
|
||||
const double alpha_rel = std::pow(2, alpha_expo);
|
||||
const double offset_rel = std::pow(2, offset_expo);
|
||||
const double alpha = longest_diag_length / alpha_rel;
|
||||
|
|
|
|||
|
|
@ -23,32 +23,30 @@ using Point_3 = Kernel::Point_3;
|
|||
using Vector_3 = Kernel::Vector_3;
|
||||
|
||||
using Points = std::vector<Point_3>;
|
||||
using Face = std::array<std::size_t, 3>;
|
||||
using Face = std::vector<std::size_t>;
|
||||
using Faces = std::vector<Face>;
|
||||
|
||||
using Mesh = CGAL::Surface_mesh<Point_3>;
|
||||
|
||||
void alpha_wrap_triangle_soup(Points& pr,
|
||||
Faces& fr,
|
||||
const double alpha,
|
||||
const double offset)
|
||||
double alpha,
|
||||
double offset)
|
||||
{
|
||||
namespace AW3 = CGAL::Alpha_wraps_3;
|
||||
namespace PMP = CGAL::Polygon_mesh_processing;
|
||||
|
||||
using Oracle = AW3::internal::Triangle_soup_oracle<Points, Faces, Kernel, int, false>;
|
||||
using Oracle = AW3::internal::Triangle_soup_oracle<Points, Faces, Kernel, int, false /*subdivide*/>;
|
||||
|
||||
std::cout << "Input: " << pr.size() << " points, " << fr.size() << " faces" << std::endl;
|
||||
|
||||
PMP::repair_polygon_soup(pr, fr);
|
||||
std::cout << "Processed input: " << pr.size() << " points, " << fr.size() << " faces" << std::endl;
|
||||
// CGAL::IO::write_polygon_soup("input.off", pr, fr, CGAL::parameters::stream_precision(17));
|
||||
|
||||
Mesh input_mesh;
|
||||
if(!PMP::orient_polygon_soup(pr, fr) ||
|
||||
!PMP::is_polygon_soup_a_polygon_mesh(fr))
|
||||
{
|
||||
std::cerr << "Warning: polygon soup does not describe a polygon mesh" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
Mesh input_mesh; // only required for Hausdorff
|
||||
PMP::orient_polygon_soup(pr, fr);
|
||||
assert(PMP::is_polygon_soup_a_polygon_mesh(fr));
|
||||
PMP::polygon_soup_to_polygon_mesh(pr, fr, input_mesh);
|
||||
|
||||
// AW3
|
||||
|
|
@ -59,7 +57,7 @@ void alpha_wrap_triangle_soup(Points& pr,
|
|||
Mesh wrap;
|
||||
aw3(alpha, offset, wrap, CGAL::parameters::do_enforce_manifoldness(false));
|
||||
|
||||
std::cout << "Result: " << vertices(wrap).size() << " vertices, " << faces(wrap).size() << " faces" << std::endl;
|
||||
std::cout << "First call result: " << vertices(wrap).size() << " vertices, " << faces(wrap).size() << " faces" << std::endl;
|
||||
|
||||
// CGAL::IO::write_polygon_mesh("last.off", wrap, CGAL::parameters::stream_precision(17));
|
||||
|
||||
|
|
@ -68,8 +66,15 @@ void alpha_wrap_triangle_soup(Points& pr,
|
|||
assert(AW3::internal::has_expected_Hausdorff_distance(wrap, input_mesh, alpha, offset));
|
||||
assert(AW3::internal::check_edge_length(wrap, alpha));
|
||||
|
||||
alpha *= 2;
|
||||
offset *= 2;
|
||||
|
||||
Mesh wrap_2;
|
||||
aw3(2 * alpha, 2 * offset, wrap, CGAL::parameters::do_enforce_manifoldness(false));
|
||||
aw3(alpha, offset, wrap_2, CGAL::parameters::do_enforce_manifoldness(false));
|
||||
|
||||
std::cout << "Second call result: " << vertices(wrap).size() << " vertices, " << faces(wrap).size() << " faces" << std::endl;
|
||||
|
||||
// CGAL::IO::write_polygon_mesh("last.off", wrap, CGAL::parameters::stream_precision(17));
|
||||
|
||||
assert(num_vertices(wrap_2) <= num_vertices(wrap) && num_faces(wrap_2) <= num_faces(wrap));
|
||||
assert(AW3::internal::is_valid_wrap(wrap_2, false /*manifoldness*/));
|
||||
|
|
@ -95,12 +100,12 @@ void alpha_wrap_triangle_soup(const std::string& filename)
|
|||
Point_3(bbox.xmin(), bbox.ymin(), bbox.zmin());
|
||||
double longest_diag_length = CGAL::to_double(CGAL::approximate_sqrt(longest_diag.squared_length()));
|
||||
|
||||
CGAL::Random r;
|
||||
|
||||
for(int i=0; i<2; ++i)
|
||||
{
|
||||
CGAL::Random r;
|
||||
|
||||
const double alpha_expo = r.get_double(0., 7.5); // to have alpha_rel between 1 and ~200
|
||||
const double offset_expo = r.get_double(0., 7.5);
|
||||
const double alpha_expo = r.get_double(0., 6); // to have alpha_rel between 1 and 64
|
||||
const double offset_expo = r.get_double(0., 6);
|
||||
const double alpha_rel = std::pow(2, alpha_expo);
|
||||
const double offset_rel = std::pow(2, offset_expo);
|
||||
const double alpha = longest_diag_length / alpha_rel;
|
||||
|
|
@ -139,7 +144,7 @@ int main(int argc, char** argv)
|
|||
alpha_wrap_triangle_soup("data/tetrahedron_self_intersection_tip.off");
|
||||
alpha_wrap_triangle_soup("data/tetrahedron_twisted_tip.off");
|
||||
alpha_wrap_triangle_soup("data/tetrahedron_random_perturbation.off");
|
||||
alpha_wrap_triangle_soup("data/overlay_triangulation.off");
|
||||
// alpha_wrap_triangle_soup("data/overlay_triangulation.off"); // due to geometrically degenerate faces + using soups here
|
||||
alpha_wrap_triangle_soup("data/two_knives.off");
|
||||
alpha_wrap_triangle_soup("data/three_knives.off");
|
||||
alpha_wrap_triangle_soup("data/bunny_random_perturbation.off");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#define CGAL_AW3_TIMER
|
||||
#define CGAL_AW3_DEBUG
|
||||
#define CGAL_AW3_DEBUG_MANIFOLDNESS
|
||||
//#define CGAL_AW3_DEBUG
|
||||
//#define CGAL_AW3_DEBUG_MANIFOLDNESS
|
||||
//#define CGAL_AW3_DEBUG_STEINER_COMPUTATION
|
||||
//#define CGAL_AW3_DEBUG_INITIALIZATION
|
||||
//#define CGAL_AW3_DEBUG_QUEUE
|
||||
|
|
@ -33,6 +33,7 @@ void alpha_wrap_triangle_mesh(Mesh& input_mesh,
|
|||
namespace PMP = CGAL::Polygon_mesh_processing;
|
||||
|
||||
std::cout << "Input: " << num_vertices(input_mesh) << " vertices, " << num_faces(input_mesh) << " faces" << std::endl;
|
||||
std::cout << "Alpha: " << alpha << " Offset: " << offset << std::endl;
|
||||
|
||||
bool has_degeneracies = !PMP::remove_degenerate_faces(input_mesh);
|
||||
if(has_degeneracies)
|
||||
|
|
@ -42,10 +43,12 @@ void alpha_wrap_triangle_mesh(Mesh& input_mesh,
|
|||
|
||||
// CGAL::IO::write_polygon_mesh("input.off", input_mesh, CGAL::parameters::stream_precision(17));
|
||||
|
||||
const bool enforce_manifoldness = true;
|
||||
|
||||
Mesh wrap;
|
||||
CGAL::alpha_wrap_3(input_mesh, alpha, offset, wrap,
|
||||
CGAL::parameters::default_values(),
|
||||
CGAL::parameters::do_enforce_manifoldness(true));
|
||||
CGAL::parameters::do_enforce_manifoldness(enforce_manifoldness));
|
||||
|
||||
std::cout << "Result: " << vertices(wrap).size() << " vertices, " << faces(wrap).size() << " faces" << std::endl;
|
||||
|
||||
|
|
@ -55,10 +58,13 @@ void alpha_wrap_triangle_mesh(Mesh& input_mesh,
|
|||
{
|
||||
assert(AW3::internal::is_valid_wrap(wrap, true /*manifoldness*/));
|
||||
assert(AW3::internal::is_outer_wrap_of_triangle_mesh(wrap, input_mesh));
|
||||
assert(AW3::internal::has_expected_Hausdorff_distance(wrap, input_mesh, alpha, offset));
|
||||
|
||||
if(!enforce_manifoldness)
|
||||
assert(AW3::internal::has_expected_Hausdorff_distance(wrap, input_mesh, alpha, offset));
|
||||
}
|
||||
|
||||
assert(AW3::internal::check_edge_length(wrap, alpha));
|
||||
if(!enforce_manifoldness)
|
||||
assert(AW3::internal::check_edge_length(wrap, alpha));
|
||||
}
|
||||
|
||||
void alpha_wrap_triangle_mesh(const std::string& filename,
|
||||
|
|
@ -97,8 +103,8 @@ void alpha_wrap_triangle_mesh(const std::string& filename)
|
|||
|
||||
for(int i=0; i<2; ++i)
|
||||
{
|
||||
const double alpha_expo = r.get_double(0., 7.5); // to have alpha_rel between 1 and ~200
|
||||
const double offset_expo = r.get_double(0., 7.5);
|
||||
const double alpha_expo = r.get_double(0., 6); // to have alpha_rel between 1 and 64
|
||||
const double offset_expo = r.get_double(0., 6);
|
||||
const double alpha_rel = std::pow(2, alpha_expo);
|
||||
const double offset_rel = std::pow(2, offset_expo);
|
||||
const double alpha = longest_diag_length / alpha_rel;
|
||||
|
|
|
|||
|
|
@ -104,12 +104,12 @@ int main(int argc, char * argv[])
|
|||
//***************************************
|
||||
|
||||
// usage
|
||||
if (argc-1 < 2)
|
||||
if(argc == 1)
|
||||
{
|
||||
std::cerr << "Reads a point set or a mesh's set of vertices, reconstructs a surface using Poisson,\n";
|
||||
std::cerr << "and saves the surface.\n";
|
||||
std::cerr << "\n";
|
||||
std::cerr << "Usage: " << argv[0] << " file_in file_out [options]\n";
|
||||
std::cerr << "Usage: " << argv[0] << " [file_in] [file_out] [options]\n";
|
||||
std::cerr << "Input file formats are .off (mesh) and .xyz or .pwn (point set).\n";
|
||||
std::cerr << "Output file format is .off.\n";
|
||||
std::cerr << "Options:\n";
|
||||
|
|
@ -127,8 +127,8 @@ int main(int argc, char * argv[])
|
|||
double average_spacing_ratio = 5;
|
||||
|
||||
// decode parameters
|
||||
std::string input_filename = argc == 1 ? CGAL::data_file_path("points_3/kitten.xyz") : argv[1];
|
||||
std::string output_filename = argc == 1 ? "kitten_poisson-20-100-0.5.off" : argv[2];
|
||||
std::string input_filename = (argc > 1) ? argv[1] : CGAL::data_file_path("points_3/kitten.xyz");
|
||||
std::string output_filename = (argc > 2) ? argv[2] : "kitten_poisson-20-100-0.5.off";
|
||||
for (int i=3; i+1<argc ; ++i)
|
||||
{
|
||||
if (std::string(argv[i])=="-sm_radius")
|
||||
|
|
|
|||
Loading…
Reference in New Issue