better tests + timings + fixed support for epeck

This commit is contained in:
Dmitry Anisimov 2021-01-26 17:03:29 +01:00
parent d7e77c4c5e
commit 67fa22a86c
11 changed files with 577 additions and 1723 deletions

View File

@ -1,140 +1,141 @@
#include <fstream>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Kinetic_shape_reconstruction_2.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/boost/graph/iterator.h>
#include <CGAL/Random.h>
#include <CGAL/Aff_transformation_2.h>
#include <CGAL/IO/PLY_writer.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Random.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_2 Point_2;
typedef Kernel::Point_3 Point_3;
typedef Kernel::Vector_2 Vector_2;
typedef Kernel::Segment_2 Segment_2;
typedef CGAL::Aff_transformation_2<Kernel> Transform;
#include <vector>
#include <fstream>
#include <string>
typedef CGAL::Surface_mesh<Point_2> Mesh;
using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
typedef CGAL::Kinetic_shape_reconstruction_2<Kernel> Reconstruction;
using Point_2 = typename Kernel::Point_2;
using Point_3 = typename Kernel::Point_3;
using Vector_2 = typename Kernel::Vector_2;
using Segment_2 = typename Kernel::Segment_2;
void add_regular_case (std::vector<Segment_2>& segments, CGAL::Random& rand)
{
std::size_t size_before = segments.size();
segments.push_back (Segment_2(Point_2 (0, 1), Point_2 (0, 3)));
segments.push_back (Segment_2(Point_2 (0, 5), Point_2 (0, 7)));
segments.push_back (Segment_2(Point_2 (4, 1), Point_2 (4, 3)));
segments.push_back (Segment_2(Point_2 (4, 6), Point_2 (4, 7)));
segments.push_back (Segment_2(Point_2 (1, 0), Point_2 (3, 0)));
segments.push_back (Segment_2(Point_2 (2, 4), Point_2 (3, 4)));
segments.push_back (Segment_2(Point_2 (1.2, 8), Point_2 (2.5, 8)));
using Transform = CGAL::Aff_transformation_2<Kernel>;
using Surface_mesh = CGAL::Surface_mesh<Point_2>;
using KSR = CGAL::Kinetic_shape_reconstruction_2<Kernel>;
// Random rotation
double sine = rand.get_double(-1.1);
double cosine = std::sqrt(1. - sine * sine);
Transform rotate (CGAL::Rotation(), sine, cosine);
Transform scale (CGAL::Scaling(), rand.get_double(0.1, 10));
Transform translate (CGAL::Translation(), Vector_2 (rand.get_double(-5, 5),
rand.get_double(-5, 5)));
void add_regular_case(std::vector<Segment_2>& segments, CGAL::Random& rand) {
Transform transform = scale * rotate * translate;
const std::size_t size_before = segments.size();
segments.push_back(Segment_2(Point_2(0.0, 1.0), Point_2(0.0, 3.0)));
segments.push_back(Segment_2(Point_2(0.0, 5.0), Point_2(0.0, 7.0)));
segments.push_back(Segment_2(Point_2(4.0, 1.0), Point_2(4.0, 3.0)));
segments.push_back(Segment_2(Point_2(4.0, 6.0), Point_2(4.0, 7.0)));
segments.push_back(Segment_2(Point_2(1.0, 0.0), Point_2(3.0, 0.0)));
segments.push_back(Segment_2(Point_2(2.0, 4.0), Point_2(3.0, 4.0)));
segments.push_back(Segment_2(Point_2(1.2, 8.0), Point_2(2.5, 8.0)));
for (std::size_t i = size_before; i < segments.size(); ++ i)
{
Point_2 source = transform.transform(segments[i].source());
Point_2 target = transform.transform(segments[i].target());
segments[i] = Segment_2 (source, target);
// Random rotation.
const double sine = rand.get_double(-1.1);
const double cosine = CGAL::sqrt(1.0 - sine * sine);
const Transform rotate(CGAL::Rotation(), sine, cosine);
const Transform scale(CGAL::Scaling(), rand.get_double(0.1, 10));
const Transform translate(CGAL::Translation(),
Vector_2(rand.get_double(-5, 5), rand.get_double(-5, 5)));
const Transform transform = scale * rotate * translate;
for (std::size_t i = size_before; i < segments.size(); ++i) {
const Point_2 source = transform.transform(segments[i].source());
const Point_2 target = transform.transform(segments[i].target());
segments[i] = Segment_2(source, target);
}
}
int main (int argc, char** argv)
{
int main(int argc, char** argv) {
CGAL::Random rand(0);
std::vector<Segment_2> segments;
#define REGULAR_CASE
unsigned int nb_lines = 30;
if (argc > 1)
if (argc > 1) {
nb_lines = std::atoi(argv[1]);
unsigned int k = 2;
if (argc > 2)
k = std::atoi(argv[2]);
#define REGULAR_CASE
#ifdef REGULAR_CASE
add_regular_case (segments, rand);
#else
for (unsigned int i = 0; i < nb_lines; ++ i)
{
Point_2 source (rand.get_double(0, 5), rand.get_double(0, 5));
Vector_2 vec (rand.get_double(-0.5, 0.5), rand.get_double(-0.5, 0.5));
Point_2 target = source + vec;
segments.push_back (Segment_2(source, target));
}
#endif
unsigned int k = 2;
if (argc > 2) {
k = std::atoi(argv[2]);
}
std::ofstream input_file ("input.polylines.txt");
for (const Segment_2& s : segments)
input_file << "2 " << s.source() << " 0 " << s.target() << " 0" << std::endl;
#ifdef REGULAR_CASE
add_regular_case(segments, rand);
#else
for (unsigned int i = 0; i < nb_lines; ++i) {
const Point_2 source(rand.get_double(0, 5), rand.get_double(0, 5));
const Vector_2 vec(rand.get_double(-0.5, 0.5), rand.get_double(-0.5, 0.5));
const Point_2 target = source + vec;
segments.push_back(Segment_2(source, target));
}
#endif
Reconstruction reconstruction;
std::ofstream input_file("input.polylines.txt");
for (const Segment_2& segment : segments) {
input_file << "2 " << segment.source() << " 0 " << segment.target() << " 0" << std::endl;
}
reconstruction.partition (segments, CGAL::Identity_property_map<Segment_2>(), k, 2);
KSR ksr;
ksr.partition(segments, CGAL::Identity_property_map<Segment_2>(), k, 2);
segments.clear();
reconstruction.output_raw_partition_edges_to_segment_soup (std::back_inserter (segments));
std::ofstream raw_output_file ("output_raw.polylines.txt");
for (const Segment_2& s : segments)
raw_output_file << "2 " << s.source() << " 0 " << s.target() << " 0" << std::endl;
ksr.output_raw_partition_edges_to_segment_soup(std::back_inserter(segments));
std::ofstream raw_output_file("output_raw.polylines.txt");
for (const Segment_2& segment : segments) {
raw_output_file << "2 " << segment.source() << " 0 " << segment.target() << " 0" << std::endl;
}
segments.clear();
reconstruction.output_partition_edges_to_segment_soup (std::back_inserter (segments));
std::ofstream output_file ("output.polylines.txt");
for (const Segment_2& s : segments)
output_file << "2 " << s.source() << " 0 " << s.target() << " 0" << std::endl;
ksr.output_partition_edges_to_segment_soup(std::back_inserter(segments));
std::ofstream output_file("output.polylines.txt");
for (const Segment_2& segment : segments) {
output_file << "2 " << segment.source() << " 0 " << segment.target() << " 0" << std::endl;
}
if (!reconstruction.check_integrity(true))
{
std::cerr << "Integrity of reconstruction failed" << std::endl;
if (!ksr.check_integrity(true)) {
std::cerr << "ERROR: KSR INTEGRITY FAILED!" << std::endl;
return EXIT_FAILURE;
}
Mesh mesh;
Surface_mesh mesh;
if (ksr.output_partition_cells_to_face_graph(mesh)) {
std::cout << mesh.number_of_vertices() <<
" vertices and " << mesh.number_of_faces() << " faces" << std::endl;
if (reconstruction.output_partition_cells_to_face_graph(mesh))
{
std::cerr << mesh.number_of_vertices() << " vertices and " << mesh.number_of_faces() << " faces" << std::endl;
std::ofstream output_shapes_file ("out.ply");
std::ofstream output_shapes_file("ksr.ply");
output_shapes_file << "ply" << std::endl
<< "format ascii 1.0" << std::endl
<< "element vertex " << mesh.number_of_vertices() << std::endl
<< "property double x" << std::endl
<< "property double y" << std::endl
<< "property double z" << std::endl
<< "element face " << mesh.number_of_faces() << std::endl
<< "property list uchar int vertex_index" << std::endl
<< "property uchar red" << std::endl
<< "property uchar green" << std::endl
<< "property uchar blue" << std::endl
<< "end_header" << std::endl;
for (const auto& vindex : vertices(mesh))
output_shapes_file << mesh.point(vindex) << " 0" << std::endl;
for (const auto& findex : faces(mesh))
{
output_shapes_file << degree(findex, mesh);
for (const auto& hindex : CGAL::halfedges_around_face(halfedge(findex,mesh),mesh))
output_shapes_file << " " << int(target(hindex,mesh));
output_shapes_file << " " << rand.get_int(64,192)
<< " " << rand.get_int(64,192)
<< " " << rand.get_int(64,192) << std::endl;
}
}
else
std::cerr << "Invalid face graph" << std::endl;
<< "format ascii 1.0" << std::endl
<< "element vertex " << mesh.number_of_vertices() << std::endl
<< "property double x" << std::endl
<< "property double y" << std::endl
<< "property double z" << std::endl
<< "element face " << mesh.number_of_faces() << std::endl
<< "property list uchar int vertex_index" << std::endl
<< "property uchar red" << std::endl
<< "property uchar green" << std::endl
<< "property uchar blue" << std::endl
<< "end_header" << std::endl;
for (const auto& vindex : vertices(mesh)) {
output_shapes_file << mesh.point(vindex) << " 0" << std::endl;
}
for (const auto& findex : faces(mesh)) {
output_shapes_file << degree(findex, mesh);
for (const auto& hindex : CGAL::halfedges_around_face(halfedge(findex,mesh), mesh)) {
output_shapes_file << " " << int(target(hindex,mesh));
}
output_shapes_file
<< " " << rand.get_int(64,192)
<< " " << rand.get_int(64,192)
<< " " << rand.get_int(64,192) << std::endl;
}
} else {
std::cerr << "ERROR: INVALID FACE GRAPH!" << std::endl;
}
return EXIT_SUCCESS;
}

View File

@ -5,6 +5,7 @@
#include <CGAL/IO/OFF_reader.h>
#include <CGAL/IO/PLY_writer.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Real_timer.h>
using SCF = CGAL::Simple_cartesian<float>;
using SCD = CGAL::Simple_cartesian<double>;
@ -19,7 +20,8 @@ using Segment_3 = typename Kernel::Segment_3;
using Triangle_2 = typename Kernel::Triangle_2;
using Surface_mesh = CGAL::Surface_mesh<Point_3>;
using KSR = CGAL::Kinetic_shape_reconstruction_3<Kernel>;
using KSR = CGAL::Kinetic_shape_reconstruction_3<Kernel>;
using Timer = CGAL::Real_timer;
struct Polygon_map {
@ -49,76 +51,78 @@ struct Polygon_map {
int main(const int argc, const char** argv) {
const FT x5 = 4.771745262374, y5 = 4.395963608911; // point J
const FT x6 = 9.000000000000, y6 = 5.000000000000; // point B
const FT xx = 7.423291494505, yy = 4.774755927786; // point Q
const FT x2 = 4.074202521868, y2 = 5.606021913821; // point M
const FT x3 = 13.82144413465, y3 = 3.186692216531; // point N
// const FT x5 = 4.771745262374, y5 = 4.395963608911; // point J
// const FT x6 = 9.000000000000, y6 = 5.000000000000; // point B
// const FT xx = 7.423291494505, yy = 4.774755927786; // point Q
// const FT x2 = 4.074202521868, y2 = 5.606021913821; // point M
// const FT x3 = 13.82144413465, y3 = 3.186692216531; // point N
const Point_2 J(x5, y5);
const Point_2 B(x6, y6);
const Point_2 Q(xx, yy);
const Point_2 M(x2, y2);
const Point_2 N(x3, y3);
// const Point_2 J(x5, y5);
// const Point_2 B(x6, y6);
// const Point_2 Q(xx, yy);
// const Point_2 M(x2, y2);
// const Point_2 N(x3, y3);
const FT a1 = x5-x6;
const FT b1 = y5-y6;
const FT c1 = x6*x6-x6*x5-y6*y5+y6*y6;
// const FT a1 = x5-x6;
// const FT b1 = y5-y6;
// const FT c1 = x6*x6-x6*x5-y6*y5+y6*y6;
const FT d1 = (x6-x5)*(x6-x5)+(y6-y5)*(y6-y5);
// const FT d1 = (x6-x5)*(x6-x5)+(y6-y5)*(y6-y5);
const FT a2 = a1/d1;
const FT b2 = b1/d1;
const FT c2 = c1/d1;
// const FT a2 = a1/d1;
// const FT b2 = b1/d1;
// const FT c2 = c1/d1;
const FT l1 = a2*xx+b2*yy+c2;
const FT l2 = FT(1)-l1;
// const FT l1 = a2*xx+b2*yy+c2;
// const FT l2 = FT(1)-l1;
const FT a3 = x2-x3;
const FT b3 = y2-y3;
const FT c3 = x3*x3-x3*x2-y3*y2+y3*y3;
// const FT a3 = x2-x3;
// const FT b3 = y2-y3;
// const FT c3 = x3*x3-x3*x2-y3*y2+y3*y3;
const FT d2 = (x3-x2)*(x3-x2)+(y3-y2)*(y3-y2);
// const FT d2 = (x3-x2)*(x3-x2)+(y3-y2)*(y3-y2);
const FT a4 = a3/d2;
const FT b4 = b3/d2;
const FT c4 = c3/d2;
// const FT a4 = a3/d2;
// const FT b4 = b3/d2;
// const FT c4 = c3/d2;
const FT m1 = a4*xx+b4*yy+c4;
const FT m2 = FT(1)-m1;
// const FT m1 = a4*xx+b4*yy+c4;
// const FT m2 = FT(1)-m1;
const FT a5 = x5*a2-x6*a2-x2*a4+x3*a4;
const FT b5 = x5*b2-x6*b2-x2*b4+x3*b4;
const FT c5 = x5*c2+x6-x6*c2-x2*c4-x3+x3*c4;
// const FT a5 = x5*a2-x6*a2-x2*a4+x3*a4;
// const FT b5 = x5*b2-x6*b2-x2*b4+x3*b4;
// const FT c5 = x5*c2+x6-x6*c2-x2*c4-x3+x3*c4;
const FT a6 = y5*a2-y6*a2-y2*a4+y3*a4;
const FT b6 = y5*b2-y6*b2-y2*b4+y3*b4;
const FT c6 = y5*c2+y6-y6*c2-y2*c4-y3+y3*c4;
// const FT a6 = y5*a2-y6*a2-y2*a4+y3*a4;
// const FT b6 = y5*b2-y6*b2-y2*b4+y3*b4;
// const FT c6 = y5*c2+y6-y6*c2-y2*c4-y3+y3*c4;
const FT x = (c5*b6-b5*c6)/(b5*a6-a5*b6);
const FT y = (-c5-a5*x)/(b5);
// const FT x = (c5*b6-b5*c6)/(b5*a6-a5*b6);
// const FT y = (-c5-a5*x)/(b5);
const FT lambda1 = a2*x+b2*y+c2;
const FT lambda2 = FT(1)-lambda1;
// const FT lambda1 = a2*x+b2*y+c2;
// const FT lambda2 = FT(1)-lambda1;
std::cout.precision(20);
std::cout << "--debug--" << std::endl;
std::cout << xx << " =? " << l1*x5+l2*x6 << std::endl;
std::cout << yy << " =? " << l1*y5+l2*y6 << std::endl;
std::cout << xx << " =? " << m1*x2+m2*x3 << std::endl;
std::cout << yy << " =? " << m1*y2+m2*y3 << std::endl;
std::cout << a5*xx+b5*yy+c5 << " =? " << 0 << std::endl;
std::cout << a6*xx+b6*yy+c6 << " =? " << 0 << std::endl;
// std::cout << "--debug--" << std::endl;
// std::cout.precision(20);
// std::cout << xx << " =? " << l1*x5+l2*x6 << std::endl;
// std::cout << yy << " =? " << l1*y5+l2*y6 << std::endl;
// std::cout << xx << " =? " << m1*x2+m2*x3 << std::endl;
// std::cout << yy << " =? " << m1*y2+m2*y3 << std::endl;
// std::cout << a5*xx+b5*yy+c5 << " =? " << 0 << std::endl;
// std::cout << a6*xx+b6*yy+c6 << " =? " << 0 << std::endl;
std::cout << "--result--" << std::endl;
std::cout << xx << " =? " << x << std::endl;
std::cout << yy << " =? " << y << std::endl;
std::cout << "lambda1 = " << lambda1 << std::endl;
std::cout << "lambda2 = " << lambda2 << std::endl;
// std::cout << "--result--" << std::endl;
// std::cout.precision(20);
// std::cout << xx << " =? " << x << std::endl;
// std::cout << yy << " =? " << y << std::endl;
// std::cout << "lambda1 = " << lambda1 << std::endl;
// std::cout << "lambda2 = " << lambda2 << std::endl;
exit(EXIT_SUCCESS);
// exit(EXIT_SUCCESS);
// Input.
std::cout.precision(20);
const auto kernel_name = boost::typeindex::type_id<Kernel>().pretty_name();
std::string input_filename = (argc > 1 ? argv[1] : "data/stress-test-0/test-1-polygon-a.off");
std::ifstream input_file(input_filename);
@ -147,19 +151,25 @@ int main(const int argc, const char** argv) {
// Algorithm.
KSR ksr(verbose, debug);
const Polygon_map polygon_map(input_vertices);
const bool is_success = ksr.partition(
Timer timer;
timer.start();
const bool is_ksr_success = ksr.partition(
input_faces, polygon_map, CGAL::parameters::
k_intersections(k).
n_subdivisions(subdiv).
enlarge_bbox_ratio(eratio).
reorient(orient));
assert(is_success);
assert(is_ksr_success);
const std::string success = is_ksr_success ? "SUCCESS" : "FAILED";
timer.stop();
const FT time = static_cast<FT>(timer.time());
// Output.
const int support_plane_idx = -1;
const int num_support_planes = ksr.number_of_support_planes();
CGAL_assertion(num_support_planes > 6);
CGAL_assertion(ksr.support_plane_index(0) == 6);
assert(num_support_planes > 6);
assert(ksr.support_plane_index(0) == 6);
// Vertices.
const std::size_t num_vertices = ksr.number_of_vertices(support_plane_idx);
@ -184,7 +194,7 @@ int main(const int argc, const char** argv) {
int volume_level = -1;
const int num_volume_levels = ksr.number_of_volume_levels();
CGAL_assertion(num_volume_levels > 0);
assert(num_volume_levels > 0);
// Volumes.
const std::size_t num_volumes = ksr.number_of_volumes(volume_level);
@ -199,12 +209,12 @@ int main(const int argc, const char** argv) {
for (int i = 0; i < num_support_planes; ++i) {
Surface_mesh sp_mesh;
ksr.output_support_plane(sp_mesh, i);
CGAL_assertion(sp_mesh.number_of_vertices() == ksr.number_of_vertices(i));
CGAL_assertion(sp_mesh.number_of_edges() == ksr.number_of_edges(i));
CGAL_assertion(sp_mesh.number_of_faces() == ksr.number_of_faces(i));
assert(sp_mesh.number_of_vertices() == ksr.number_of_vertices(i));
assert(sp_mesh.number_of_edges() == ksr.number_of_edges(i));
assert(sp_mesh.number_of_faces() == ksr.number_of_faces(i));
support_planes.push_back(sp_mesh);
}
CGAL_assertion(support_planes.size() == num_support_planes);
assert(support_planes.size() == num_support_planes);
std::cout << std::endl;
std::cout << "--- OUTPUT STATS: " << std::endl;
@ -213,6 +223,7 @@ int main(const int argc, const char** argv) {
std::cout << "* number of faces: " << num_faces << std::endl;
std::cout << "* number of volumes: " << num_volumes << std::endl;
std::cout << "* number of support planes: " << num_support_planes << std::endl;
std::cout << "* number of volume levels: " << num_volume_levels << std::endl;
// Export.
std::cout << std::endl;
@ -271,6 +282,7 @@ int main(const int argc, const char** argv) {
// }
// std::cout << "* partition support planes exported successfully" << std::endl;
std::cout << std::endl << "3D KINETIC DONE!" << std::endl << std::endl;
std::cout << std::endl << "3D KINETIC " << success <<
" in " << time << " seconds!" << std::endl << std::endl;
return EXIT_SUCCESS;
}

View File

@ -407,10 +407,11 @@ int main(const int argc, const char** argv) {
const IPolygon_3_map polygon_map;
const unsigned int k = (argc > 3 ? std::atoi(argv[3]) : 1);
std::cout << "* input k: " << k << std::endl;
const bool is_success = ksr.partition(
const bool is_ksr_success = ksr.partition(
input_polygons, polygon_map, CGAL::parameters::k_intersections(k));
assert(is_success);
assert(is_ksr_success);
const std::string success = is_ksr_success ? "SUCCESS" : "FAILED";
std::cout << std::endl << "3D KINETIC DONE!" << std::endl << std::endl;
std::cout << std::endl << "3D KINETIC " << success << "!" << std::endl << std::endl;
return EXIT_SUCCESS;
}

View File

@ -5,6 +5,7 @@
#include <CGAL/Point_set_3.h>
#include <CGAL/Point_set_3/IO.h>
#include <CGAL/IO/PLY_writer.h>
#include <CGAL/Real_timer.h>
#include "include/Parameters.h"
#include "include/Terminal_parser.h"
@ -29,6 +30,7 @@ using KSR = CGAL::Kinetic_shape_reconstruction_3<Kernel>;
using Parameters = CGAL::KSR::Parameters<FT>;
using Terminal_parser = CGAL::KSR::Terminal_parser<FT>;
using Timer = CGAL::Real_timer;
void parse_terminal(Terminal_parser& parser, Parameters& parameters) {
// Set all parameters that can be loaded from the terminal.
@ -74,6 +76,7 @@ void parse_terminal(Terminal_parser& parser, Parameters& parameters) {
int main(const int argc, const char** argv) {
// Parameters.
std::cout.precision(20);
std::cout << std::endl;
std::cout << "--- PARSING INPUT: " << std::endl;
const auto kernel_name = boost::typeindex::type_id<Kernel>().pretty_name();
@ -106,7 +109,10 @@ int main(const int argc, const char** argv) {
// Algorithm.
KSR ksr(parameters.verbose, parameters.debug);
ksr.reconstruct(
Timer timer;
timer.start();
const bool is_ksr_success = ksr.reconstruct(
point_set,
point_set.point_map(),
point_set.normal_map(),
@ -119,6 +125,10 @@ int main(const int argc, const char** argv) {
regularize(parameters.regularize).
k_intersections(parameters.k_intersections).
graphcut_beta(parameters.graphcut_beta));
assert(is_ksr_success);
const std::string success = is_ksr_success ? "SUCCESS" : "FAILED";
timer.stop();
const FT time = static_cast<FT>(timer.time());
// Output.
@ -186,6 +196,7 @@ int main(const int argc, const char** argv) {
output_file_model.close();
std::cout << "* the reconstructed model exported successfully" << std::endl;
std::cout << std::endl << "3D KINETIC RECONSTRUCTION DONE!" << std::endl << std::endl;
std::cout << std::endl << "3D KINETIC RECONSTRUCTION " << success <<
" in " << time << " seconds!" << std::endl << std::endl;
return EXIT_SUCCESS;
}

File diff suppressed because it is too large Load Diff

View File

@ -106,16 +106,22 @@ public:
template<typename IG>
void convert(IG& ig) {
using Converter = CGAL::Cartesian_converter<Kernel, typename IG::Kernel>;
using CFT = typename IG::Kernel::FT;
using CPoint_3 = typename IG::Kernel::Point_3;
// using Converter = CGAL::Cartesian_converter<Kernel, typename IG::Kernel>;
// Converter converter;
Converter converter;
ig.set_nb_lines(m_nb_lines);
const auto vpair = boost::vertices(m_graph);
const auto vertex_range = CGAL::make_range(vpair);
for (const auto vertex : vertex_range) {
const auto vd = boost::add_vertex(ig.graph());
ig.graph()[vd].point = converter(m_graph[vertex].point);
// ig.graph()[vd].point = converter(m_graph[vertex].point);
ig.graph()[vd].point = CPoint_3(
static_cast<CFT>(CGAL::to_double(m_graph[vertex].point.x())),
static_cast<CFT>(CGAL::to_double(m_graph[vertex].point.y())),
static_cast<CFT>(CGAL::to_double(m_graph[vertex].point.z())));
ig.graph()[vd].active = m_graph[vertex].active;
CGAL_assertion(m_graph[vertex].active);
m_vmap[vertex] = vd;

View File

@ -172,7 +172,7 @@ public:
const bool regularize_planar_shapes(
const NamedParameters& np) {
const FT regularize = parameters::choose_parameter(
const bool regularize = parameters::choose_parameter(
parameters::get_parameter(np, internal_np::regularize), false);
if (!regularize) return true;

View File

@ -162,9 +162,13 @@ public:
template<typename IG, typename SP>
void convert(const IG& ig, SP& sp) {
using CFT = typename SP::Kernel::FT;
using CPoint_2 = typename SP::Kernel::Point_2;
using Converter = CGAL::Cartesian_converter<Kernel, typename SP::Kernel>;
Converter converter;
using CPlane_3 = typename SP::Kernel::Plane_3;
using CVector_2 = typename SP::Kernel::Vector_2;
// using Converter = CGAL::Cartesian_converter<Kernel, typename SP::Kernel>;
// Converter converter;
const auto& vmap = ig.vmap();
const auto& emap = ig.emap();
@ -172,9 +176,17 @@ public:
std::set<CPoint_2> pts;
std::map<Vertex_index, Vertex_index> map_vi;
sp.data().k = m_data->k;
sp.data().plane = converter(m_data->plane);
// sp.data().plane = converter(m_data->plane);
sp.data().plane = CPlane_3(
static_cast<CFT>(CGAL::to_double(m_data->plane.a())),
static_cast<CFT>(CGAL::to_double(m_data->plane.b())),
static_cast<CFT>(CGAL::to_double(m_data->plane.c())),
static_cast<CFT>(CGAL::to_double(m_data->plane.d())));
for (const auto& vertex : m_data->mesh.vertices()) {
const auto converted = converter(m_data->mesh.point(vertex));
// const auto converted = converter(m_data->mesh.point(vertex));
const CPoint_2 converted = CPoint_2(
static_cast<CFT>(CGAL::to_double(m_data->mesh.point(vertex).x())),
static_cast<CFT>(CGAL::to_double(m_data->mesh.point(vertex).y())));
const bool is_inserted = pts.insert(converted).second;
const auto vi = sp.data().mesh.add_vertex();
map_vi[vertex] = vi;
@ -233,7 +245,10 @@ public:
for (const auto& vertex : m_data->mesh.vertices()) {
const auto vi = map_vi.at(vertex);
sp.data().direction[vi] = converter(m_data->direction[vertex]);
// sp.data().direction[vi] = converter(m_data->direction[vertex]);
sp.data().direction[vi] = CVector_2(
static_cast<CFT>(CGAL::to_double(m_data->direction[vertex].x())),
static_cast<CFT>(CGAL::to_double(m_data->direction[vertex].y())));
const auto ivertex = m_data->v_ivertex_map[vertex];
if (ivertex != IG::null_ivertex()) {
@ -251,7 +266,9 @@ public:
sp.data().v_active_map[vi] = m_data->v_active_map[vertex];
sp.data().v_original_map[vi] = m_data->v_original_map[vertex];
sp.data().v_time_map[vi] = converter(m_data->v_time_map[vertex]);
// sp.data().v_time_map[vi] = converter(m_data->v_time_map[vertex]);
sp.data().v_time_map[vi] = static_cast<CFT>(CGAL::to_double(m_data->v_time_map[vertex]));
}
for (const auto& edge : m_data->mesh.edges()) {

View File

@ -1,22 +1,27 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Kinetic_shape_reconstruction_3.h>
#include <CGAL/IO/OFF_reader.h>
#include <CGAL/Real_timer.h>
using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel;
using Kernel = EPICK;
using Point_3 = typename Kernel::Point_3;
using KSR = CGAL::Kinetic_shape_reconstruction_3<Kernel>;
using SCF = CGAL::Simple_cartesian<float>;
using SCD = CGAL::Simple_cartesian<double>;
using EPICK = CGAL::Exact_predicates_inexact_constructions_kernel;
using EPECK = CGAL::Exact_predicates_exact_constructions_kernel;
using Timer = CGAL::Real_timer;
template<typename Point>
struct Polygon_map {
using key_type = std::vector<std::size_t>;
using value_type = std::vector<Point_3>;
using value_type = std::vector<Point>;
using reference = value_type;
using category = boost::readable_property_map_tag;
const std::vector<Point_3>& points;
const std::vector<Point>& points;
Polygon_map(
const std::vector<Point_3>& vertices) :
const std::vector<Point>& vertices) :
points(vertices)
{ }
@ -26,47 +31,164 @@ struct Polygon_map {
std::transform(
face.begin(), face.end(),
std::back_inserter(polygon),
[&](const std::size_t vertex_index) -> Point_3 {
[&](const std::size_t vertex_index) -> Point {
return map.points[vertex_index];
});
return polygon;
}
};
template<typename Traits>
const bool run_test(
const std::string input_filename,
const std::vector<unsigned int>& ks,
const std::size_t num_iters,
const std::vector<int>& results,
std::vector< std::vector<double> >& all_times,
std::size_t& num_tests) {
using Point_3 = typename Traits::Point_3;
using Segment_3 = typename Traits::Segment_3;
using Surface_mesh = CGAL::Surface_mesh<Point_3>;
using KSR = CGAL::Kinetic_shape_reconstruction_3<Traits>;
++num_tests;
std::ifstream input_file(input_filename);
std::vector<Point_3> input_vertices;
std::vector< std::vector<std::size_t> > input_faces;
assert(CGAL::read_OFF(input_file, input_vertices, input_faces));
const bool is_input_success = CGAL::read_OFF(input_file, input_vertices, input_faces);
assert(is_input_success);
if (!is_input_success) return false;
std::vector<double> times;
std::cout << std::endl;
std::cout << "--INPUT FILE: " << input_filename << std::endl;
const Polygon_map polygon_map(input_vertices);
for (const auto k : ks) {
const Polygon_map<Point_3> polygon_map(input_vertices);
for (const unsigned int k : ks) {
std::cout << std::endl << "--INPUT K: " << k << std::endl;
double time = 0.0;
for (std::size_t iter = 0; iter < num_iters; ++iter) {
std::cout << std::endl << "--ITERATION #" << iter + 1 << " BEGIN!" << std::endl;
KSR ksr(false, false);
assert(ksr.partition(
input_faces, polygon_map, CGAL::parameters::k_intersections(k)));
// Running KSR.
Timer timer;
timer.start();
const bool is_ksr_success = ksr.partition(
input_faces, polygon_map, CGAL::parameters::k_intersections(k));
assert(is_ksr_success);
if (!is_ksr_success) return false;
timer.stop();
time += timer.time();
// Testing results.
const int num_support_planes = ksr.number_of_support_planes();
const int num_volume_levels = ksr.number_of_volume_levels();
const int num_vertices = static_cast<int>(ksr.number_of_vertices());
const int num_edges = static_cast<int>(ksr.number_of_edges());
const int num_faces = static_cast<int>(ksr.number_of_faces());
const int num_volumes = static_cast<int>(ksr.number_of_volumes());
std::cout << std::endl << "--RESULTS: ";
std::cout << num_support_planes << ",";
std::cout << num_volume_levels << ",";
std::cout << num_vertices << ",";
std::cout << num_edges << ",";
std::cout << num_faces << ",";
std::cout << num_volumes << std::endl;
assert(num_support_planes > 6);
assert(num_volume_levels > 0);
if (num_support_planes <= 6) return false;
if (num_volume_levels < 1) return false;
assert(results.size() == 6);
assert(num_support_planes == results[0]);
assert(num_volume_levels >= results[1]);
if (results.size() != 6) return false;
if (num_support_planes != results[0]) return false;
if (num_volume_levels < results[1]) return false;
assert(num_vertices == results[2]);
assert(num_edges == results[3]);
assert(num_faces >= results[4]);
assert(num_volumes >= results[5]);
if (num_vertices != results[2]) return false;
if (num_edges != results[3]) return false;
if (num_faces < results[4]) return false;
if (num_volumes < results[5]) return false;
std::vector<Point_3> output_vertices;
ksr.output_partition_vertices(
std::back_inserter(output_vertices));
assert(num_vertices == output_vertices.size());
if (num_vertices != output_vertices.size()) return false;
std::vector<Segment_3> output_edges;
ksr.output_partition_edges(
std::back_inserter(output_edges));
assert(num_edges == output_edges.size());
if (num_edges != output_edges.size()) return false;
std::vector< std::vector<std::size_t> > output_faces;
ksr.output_partition_faces(
std::back_inserter(output_faces));
assert(num_faces == output_faces.size());
if (num_faces != output_faces.size()) return false;
std::vector<Surface_mesh> output_volumes;
ksr.output_partition_volumes(
std::back_inserter(output_volumes));
assert(num_volumes == output_volumes.size());
if (num_volumes != output_volumes.size()) return false;
ksr.clear();
assert(ksr.number_of_support_planes() == 0);
assert(ksr.number_of_volume_levels() == 0);
assert(ksr.number_of_vertices() == 0);
assert(ksr.number_of_edges() == 0);
assert(ksr.number_of_faces() == 0);
assert(ksr.number_of_volumes() == 0);
if (ksr.number_of_support_planes() != 0) return false;
if (ksr.number_of_volume_levels() != 0) return false;
if (ksr.number_of_vertices() != 0) return false;
if (ksr.number_of_edges() != 0) return false;
if (ksr.number_of_faces() != 0) return false;
if (ksr.number_of_volumes() != 0) return false;
std::cout << std::endl << "--ITERATION #" << iter + 1 << " END!" << std::endl;
}
time /= static_cast<double>(num_iters);
times.push_back(time);
}
assert(times.size() == ks.size());
if (times.size() != ks.size()) return false;
all_times.push_back(times);
return true;
}
int main (const int argc, const char** argv) {
template<typename Traits>
void run_all_tests() {
std::size_t num_tests = 0;
const std::size_t num_iters = 1;
const std::size_t num_iters = 3;
std::cout.precision(10);
std::vector< std::vector<double> > all_times;
// All results are precomputed for k = 1!
std::vector<int> results;
// Number of allowed intersections k.
std::vector<unsigned int> ks;
for (unsigned int k = 1; k <= 6; ++k) {
ks.push_back(k);
@ -74,87 +196,167 @@ int main (const int argc, const char** argv) {
ks.push_back(100);
// Edge case tests.
assert(run_test("data/edge-case-test/test-flat-bbox-xy.off" , ks, num_iters, num_tests)); // flat bbox / 2 coplanar in XY
assert(run_test("data/edge-case-test/test-flat-bbox-xz.off" , ks, num_iters, num_tests)); // flat bbox / 2 coplanar in XZ
assert(run_test("data/edge-case-test/test-flat-bbox-yz.off" , ks, num_iters, num_tests)); // flat bbox / 2 coplanar in YZ
assert(run_test("data/edge-case-test/test-2-polygons.off" , ks, num_iters, num_tests)); // edge touch
assert(run_test("data/edge-case-test/test-4-polygons.off" , ks, num_iters, num_tests)); // edge touch / 2 coplanar
assert(run_test("data/edge-case-test/test-5-polygons.off" , ks, num_iters, num_tests)); // edge touch / vertex touch / 2 coplanar
// flat bbox / 2 coplanar in XY
results = {7,1,12,20,11,2};
assert(run_test<Traits>("data/edge-case-test/test-flat-bbox-xy.off", ks, num_iters, results, all_times, num_tests));
// flat bbox / 2 coplanar in XZ
results = {7,1,12,20,11,2};
assert(run_test<Traits>("data/edge-case-test/test-flat-bbox-xz.off", ks, num_iters, results, all_times, num_tests));
// flat bbox / 2 coplanar in YZ
results = {7,1,12,20,11,2};
assert(run_test<Traits>("data/edge-case-test/test-flat-bbox-yz.off", ks, num_iters, results, all_times, num_tests));
// edge touch
results = {8,1,18,33,19,3};
assert(run_test<Traits>("data/edge-case-test/test-2-polygons.off" , ks, num_iters, results, all_times, num_tests));
// edge touch / 2 coplanar
results = {9,1,24,46,27,4};
assert(run_test<Traits>("data/edge-case-test/test-4-polygons.off" , ks, num_iters, results, all_times, num_tests));
// edge touch / vertex touch / 2 coplanar
results = {9,1,24,46,27,4};
assert(run_test<Traits>("data/edge-case-test/test-5-polygons.off" , ks, num_iters, results, all_times, num_tests));
// Stress tests 0.
assert(run_test("data/stress-test-0/test-1-polygon-a.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-0/test-1-polygon-b.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-0/test-1-polygon-c.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-0/test-1-polygon-d.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-0/test-2-polygons-ab.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-0/test-2-polygons-ac.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-0/test-2-polygons-ad.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-0/test-2-polygons-bc.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-0/test-2-polygons-bd.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-0/test-2-polygons-cd.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-0/test-3-polygons-abc.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-0/test-3-polygons-abd.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-0/test-3-polygons-acd.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-0/test-3-polygons-bcd.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-0/test-4-polygons-abcd.off", ks, num_iters, num_tests));
assert(run_test("data/stress-test-0/test-6-polygons.off" , ks, num_iters, num_tests));
results = {7,1,14,24,13,2};
assert(run_test<Traits>("data/stress-test-0/test-1-polygon-a.off" , ks, num_iters, results, all_times, num_tests));
results = {7,1,14,24,13,2};
assert(run_test<Traits>("data/stress-test-0/test-1-polygon-b.off" , ks, num_iters, results, all_times, num_tests));
results = {7,1,14,24,13,2};
assert(run_test<Traits>("data/stress-test-0/test-1-polygon-c.off" , ks, num_iters, results, all_times, num_tests));
results = {7,1,14,24,13,2};
assert(run_test<Traits>("data/stress-test-0/test-1-polygon-d.off" , ks, num_iters, results, all_times, num_tests));
results = {8,1,20,37,21,3};
assert(run_test<Traits>("data/stress-test-0/test-2-polygons-ab.off" , ks, num_iters, results, all_times, num_tests));
results = {8,1,20,37,21,3};
assert(run_test<Traits>("data/stress-test-0/test-2-polygons-ac.off" , ks, num_iters, results, all_times, num_tests));
results = {8,1,20,37,21,3};
assert(run_test<Traits>("data/stress-test-0/test-2-polygons-ad.off" , ks, num_iters, results, all_times, num_tests));
results = {8,1,18,32,18,3};
assert(run_test<Traits>("data/stress-test-0/test-2-polygons-bc.off" , ks, num_iters, results, all_times, num_tests));
results = {8,1,19,35,20,3};
assert(run_test<Traits>("data/stress-test-0/test-2-polygons-bd.off" , ks, num_iters, results, all_times, num_tests));
results = {8,1,19,35,21,4};
assert(run_test<Traits>("data/stress-test-0/test-2-polygons-cd.off" , ks, num_iters, results, all_times, num_tests));
results = {9,1,27,52,30,4};
assert(run_test<Traits>("data/stress-test-0/test-3-polygons-abc.off" , ks, num_iters, results, all_times, num_tests));
results = {9,1,30,60,34,4};
assert(run_test<Traits>("data/stress-test-0/test-3-polygons-abd.off" , ks, num_iters, results, all_times, num_tests));
results = {9,1,28,55,33,5};
assert(run_test<Traits>("data/stress-test-0/test-3-polygons-acd.off" , ks, num_iters, results, all_times, num_tests));
results = {9,1,26,50,30,5};
assert(run_test<Traits>("data/stress-test-0/test-3-polygons-bcd.off" , ks, num_iters, results, all_times, num_tests));
results = {10,1,38,78,46,6};
assert(run_test<Traits>("data/stress-test-0/test-4-polygons-abcd.off", ks, num_iters, results, all_times, num_tests));
results = {12,1,67,149,90,11};
assert(run_test<Traits>("data/stress-test-0/test-6-polygons.off" , ks, num_iters, results, all_times, num_tests));
// Stress tests 1.
assert(run_test("data/stress-test-1/test-1-rnd-polygons-1-4.off", ks, num_iters, num_tests));
assert(run_test("data/stress-test-1/test-2-rnd-polygons-1-4.off", ks, num_iters, num_tests));
assert(run_test("data/stress-test-1/test-3-rnd-polygons-1-4.off", ks, num_iters, num_tests));
assert(run_test("data/stress-test-1/test-4-rnd-polygons-1-4.off", ks, num_iters, num_tests));
assert(run_test("data/stress-test-1/test-5-rnd-polygons-2-4.off", ks, num_iters, num_tests));
assert(run_test("data/stress-test-1/test-6-rnd-polygons-2-4.off", ks, num_iters, num_tests));
assert(run_test("data/stress-test-1/test-7-rnd-polygons-2-4.off", ks, num_iters, num_tests));
assert(run_test("data/stress-test-1/test-8-rnd-polygons-3-4.off", ks, num_iters, num_tests));
results = {7,1,14,24,13,2};
assert(run_test<Traits>("data/stress-test-1/test-1-rnd-polygons-1-4.off", ks, num_iters, results, all_times, num_tests));
results = {7,1,14,24,13,2};
assert(run_test<Traits>("data/stress-test-1/test-2-rnd-polygons-1-4.off", ks, num_iters, results, all_times, num_tests));
results = {7,1,14,24,13,2};
assert(run_test<Traits>("data/stress-test-1/test-3-rnd-polygons-1-4.off", ks, num_iters, results, all_times, num_tests));
results = {7,1,14,24,13,2};
assert(run_test<Traits>("data/stress-test-1/test-4-rnd-polygons-1-4.off", ks, num_iters, results, all_times, num_tests));
results = {8,1,20,37,21,3};
assert(run_test<Traits>("data/stress-test-1/test-5-rnd-polygons-2-4.off", ks, num_iters, results, all_times, num_tests));
results = {8,1,19,35,20,3};
assert(run_test<Traits>("data/stress-test-1/test-6-rnd-polygons-2-4.off", ks, num_iters, results, all_times, num_tests));
results = {8,1,20,37,22,4};
assert(run_test<Traits>("data/stress-test-1/test-7-rnd-polygons-2-4.off", ks, num_iters, results, all_times, num_tests));
results = {9,1,28,56,35,6};
assert(run_test<Traits>("data/stress-test-1/test-8-rnd-polygons-3-4.off", ks, num_iters, results, all_times, num_tests));
// Stress tests 2.
assert(run_test("data/stress-test-2/test-1-rnd-polygons-1-4.off", ks, num_iters, num_tests));
assert(run_test("data/stress-test-2/test-2-rnd-polygons-1-4.off", ks, num_iters, num_tests));
assert(run_test("data/stress-test-2/test-3-rnd-polygons-1-4.off", ks, num_iters, num_tests));
assert(run_test("data/stress-test-2/test-4-rnd-polygons-1-3.off", ks, num_iters, num_tests));
assert(run_test("data/stress-test-2/test-5-rnd-polygons-2-4.off", ks, num_iters, num_tests));
assert(run_test("data/stress-test-2/test-6-rnd-polygons-3-4.off", ks, num_iters, num_tests));
results = {7,1,14,24,13,2};
assert(run_test<Traits>("data/stress-test-2/test-1-rnd-polygons-1-4.off", ks, num_iters, results, all_times, num_tests));
results = {7,1,14,24,13,2};
assert(run_test<Traits>("data/stress-test-2/test-2-rnd-polygons-1-4.off", ks, num_iters, results, all_times, num_tests));
results = {7,1,14,24,13,2};
assert(run_test<Traits>("data/stress-test-2/test-3-rnd-polygons-1-4.off", ks, num_iters, results, all_times, num_tests));
results = {7,1,14,24,13,2};
assert(run_test<Traits>("data/stress-test-2/test-4-rnd-polygons-1-3.off", ks, num_iters, results, all_times, num_tests));
results = {8,1,19,35,20,3};
assert(run_test<Traits>("data/stress-test-2/test-5-rnd-polygons-2-4.off", ks, num_iters, results, all_times, num_tests));
results = {9,1,26,50,30,5};
assert(run_test<Traits>("data/stress-test-2/test-6-rnd-polygons-3-4.off", ks, num_iters, results, all_times, num_tests));
// Stress tests 3.
assert(run_test("data/stress-test-3/test-1-rnd-polygons-2-3.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-3/test-2-rnd-polygons-2-3.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-3/test-3-rnd-polygons-2-3.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-3/test-4-rnd-polygons-2-4.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-3/test-5-rnd-polygons-1-3.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-3/test-6-rnd-polygons-2-3.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-3/test-7-rnd-polygons-2-4.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-3/test-8-rnd-polygons-2-10.off", ks, num_iters, num_tests));
assert(run_test("data/stress-test-3/test-9-rnd-polygons-4-4.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-3/test-10-rnd-polygons-5-4.off", ks, num_iters, num_tests));
results = {8,1,20,37,21,3};
assert(run_test<Traits>("data/stress-test-3/test-1-rnd-polygons-2-3.off" , ks, num_iters, results, all_times, num_tests));
results = {8,1,17,30,17,3};
assert(run_test<Traits>("data/stress-test-3/test-2-rnd-polygons-2-3.off" , ks, num_iters, results, all_times, num_tests));
results = {8,1,19,35,20,3};
assert(run_test<Traits>("data/stress-test-3/test-3-rnd-polygons-2-3.off" , ks, num_iters, results, all_times, num_tests));
results = {8,1,19,35,20,3};
assert(run_test<Traits>("data/stress-test-3/test-4-rnd-polygons-2-4.off" , ks, num_iters, results, all_times, num_tests));
results = {7,1,13,22,12,2};
assert(run_test<Traits>("data/stress-test-3/test-5-rnd-polygons-1-3.off" , ks, num_iters, results, all_times, num_tests));
results = {8,1,19,35,20,3};
assert(run_test<Traits>("data/stress-test-3/test-6-rnd-polygons-2-3.off" , ks, num_iters, results, all_times, num_tests));
results = {8,1,22,41,23,3};
assert(run_test<Traits>("data/stress-test-3/test-7-rnd-polygons-2-4.off" , ks, num_iters, results, all_times, num_tests));
results = {8,1,18,33,19,3};
assert(run_test<Traits>("data/stress-test-3/test-8-rnd-polygons-2-10.off", ks, num_iters, results, all_times, num_tests));
results = {10,1,39,82,50,7};
assert(run_test<Traits>("data/stress-test-3/test-9-rnd-polygons-4-4.off" , ks, num_iters, results, all_times, num_tests));
results = {11,1,55,119,78,13};
assert(run_test<Traits>("data/stress-test-3/test-10-rnd-polygons-5-4.off", ks, num_iters, results, all_times, num_tests));
// Stress tests 4.
assert(run_test("data/stress-test-4/test-1-rnd-polygons-2-6.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-4/test-2-rnd-polygons-3-8.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-4/test-3-rnd-polygons-4-4.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-4/test-4-rnd-polygons-4-6.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-4/test-5-rnd-polygons-6-4.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-4/test-6-rnd-polygons-5-6.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-4/test-7-rnd-polygons-7-6.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-4/test-8-rnd-polygons-7-8.off" , ks, num_iters, num_tests));
assert(run_test("data/stress-test-4/test-9-rnd-polygons-12-4.off", ks, num_iters, num_tests));
results = {8,1,20,37,21,3};
assert(run_test<Traits>("data/stress-test-4/test-1-rnd-polygons-2-6.off" , ks, num_iters, results, all_times, num_tests));
results = {9,1,29,58,36,6};
assert(run_test<Traits>("data/stress-test-4/test-2-rnd-polygons-3-8.off" , ks, num_iters, results, all_times, num_tests));
results = {10,1,37,76,48,8};
assert(run_test<Traits>("data/stress-test-4/test-3-rnd-polygons-4-4.off" , ks, num_iters, results, all_times, num_tests));
results = {10,1,37,77,46,6};
assert(run_test<Traits>("data/stress-test-4/test-4-rnd-polygons-4-6.off" , ks, num_iters, results, all_times, num_tests));
results = {12,2,83,191,133,24};
assert(run_test<Traits>("data/stress-test-4/test-5-rnd-polygons-6-4.off" , ks, num_iters, results, all_times, num_tests));
results = {11,1,50,107,71,14};
assert(run_test<Traits>("data/stress-test-4/test-6-rnd-polygons-5-6.off" , ks, num_iters, results, all_times, num_tests));
results = {13,2,104,246,160,23};
assert(run_test<Traits>("data/stress-test-4/test-7-rnd-polygons-7-6.off" , ks, num_iters, results, all_times, num_tests));
results = {13,1,69,152,100,16};
assert(run_test<Traits>("data/stress-test-4/test-8-rnd-polygons-7-8.off" , ks, num_iters, results, all_times, num_tests));
results = {18,3,250,629,449,76};
assert(run_test<Traits>("data/stress-test-4/test-9-rnd-polygons-12-4.off", ks, num_iters, results, all_times, num_tests));
// Stress tests 5.
assert(run_test("data/stress-test-5/test-1-rnd-polygons-15-6.off", ks, num_iters, num_tests));
assert(run_test("data/stress-test-5/test-2-rnd-polygons-20-4.off", ks, num_iters, num_tests));
results = {21,2,468,1224,723,67};
assert(run_test<Traits>("data/stress-test-5/test-1-rnd-polygons-15-6.off", ks, num_iters, results, all_times, num_tests));
results = {26,3,1037,2829,1697,164};
assert(run_test<Traits>("data/stress-test-5/test-2-rnd-polygons-20-4.off", ks, num_iters, results, all_times, num_tests));
// Real data tests.
assert(run_test("data/real-data-test/test-10-polygons.off", ks, num_iters, num_tests));
assert(run_test("data/real-data-test/test-15-polygons.off", ks, num_iters, num_tests));
assert(run_test("data/real-data-test/test-20-polygons.off", ks, num_iters, num_tests)); // 2 overlap and coplanar
results = {16,1,133,315,212,34};
assert(run_test<Traits>("data/real-data-test/test-10-polygons.off", ks, num_iters, results, all_times, num_tests));
results = {21,3,349,899,603,81};
assert(run_test<Traits>("data/real-data-test/test-15-polygons.off", ks, num_iters, results, all_times, num_tests));
results = {25,3,606,1607,1019,107};
assert(run_test<Traits>("data/real-data-test/test-20-polygons.off", ks, num_iters, results, all_times, num_tests));
// Still to be done!
// assert(run_test("data/edge-case-test/test-same-time.off" , ks, num_iters, num_tests)); // all arrive at the same time, fails for k = 1
// assert(run_test("data/edge-case-test/test-local-global-1.off", ks, num_iters, num_tests)); // no hanging pfaces, fails for k = 2
// assert(run_test("data/edge-case-test/test-local-global-2.off", ks, num_iters, num_tests)); // 1 hanging pface, fails for k = 3
// All arrive at the same time, fails for k = 1.
// results = {0,0,0,0,0,0};
// assert(run_test<Traits>("data/edge-case-test/test-same-time.off" , ks, num_iters, results, all_times, num_tests));
// No hanging pfaces, fails for k = 2.
// results = {0,0,0,0,0,0};
// assert(run_test<Traits>("data/edge-case-test/test-local-global-1.off", ks, num_iters, results, all_times, num_tests));
// Here, 1 hanging pface, fails for k = 3.
// results = {0,0,0,0,0,0};
// assert(run_test<Traits>("data/edge-case-test/test-local-global-2.off", ks, num_iters, results, all_times, num_tests));
std::cout << std::endl << "--OUTPUT STATS:" << std::endl;
std::cout << "* number of tests: " << num_tests << std::endl;
std::cout << "* number of iterations per test: " << num_iters << std::endl;
std::cout << "* k intersections: {";
for (const auto k : ks) {
@ -162,6 +364,33 @@ int main (const int argc, const char** argv) {
}
std::cout << "...}" << std::endl;
std::cout << std::endl << "ALL " << num_tests << " TESTS SUCCESS!" << std::endl;
if (num_tests != 0) {
std::cout << std::endl << "--TIMINGS:" << std::endl;
for (std::size_t i = 0; i < all_times.size(); ++i) {
std::cout << "* time (sec.), test #" << std::to_string(i) << ": {";
for (const double& time : all_times[i]) {
std::cout << time << ", ";
}
std::cout << "...}" << std::endl;
}
}
const auto kernel_name = boost::typeindex::type_id<Traits>().pretty_name();
if (num_tests != 0) {
std::cout << std::endl << kernel_name <<
": ALL " << num_tests << " TESTS SUCCESS!" << std::endl << std::endl;
} else {
std::cout << std::endl << kernel_name <<
": ALL " << num_tests << " TESTS FAILED!" << std::endl << std::endl;
}
}
int main(const int argc, const char** argv) {
// run_all_tests<SCF>();
// run_all_tests<SCD>();
// run_all_tests<EPECK>();
run_all_tests<EPICK>();
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,7 @@
Latest timings in Release for:
----------------------------------------
Initial timings in Release for:

View File

@ -19,7 +19,7 @@ ANSWERS:
- Merge polygons, which are at the same cell.
3. Can we avoid kinetic completely?
- Probably yes, but there is a problem of how to find the correct criteria that guarantees the volume convexity. But we can use the trick with tagging pfaces at least for all initial polygons.
- Probably yes, but there is a problem of how to find the correct criteria that guarantees the volume convexity. But we can use the trick with tagging faces at least for all initial polygons.
4. Do you have any guarantee on the number of final volumes? Is this number optimal for each k?
- No, it is super difficult.
@ -28,33 +28,34 @@ ANSWERS:
- Both are ok.
TODO:
1. better future directions, compute them exactly and identify if the lines are parallel using the segment coordinates, unify them for all types of events, the function should take two points with the directions and two fixed points and return the future point and the future direction along the edge, one direction must be the limit direction and one direction must be the cropped direction
2. precompute occupied iedges while inserting new events
3. better graphcut by inserting information, which faces are originated by the roof and facade points
4. adaptive time step, e.g. doubled in case we had three steps and did not meet any event
5. precompute as mush as possible stuff, e.g. next events
6. fix initialization using the same trick I use for adding missing faces
7. put adding missing faces and remove faces in two separate files, they can be reused when working on the subdivision
8. add the finalizer class
9. make the initializer work with the inexact kernel
10. better polygon regularizer using the global approach
11. graph cut using normals and graphcut using the LOD
12. add timing tests, accelerate the code as much as possible
13. try to merge thin volumes in case we are beyond the tolerance value when traversing the volumes
14. add interface to insert custom planes for subdivision instead of uniform sibdivision, in this case, we can avoid artifacts in the important parts of the model but still be much faster
15. try using non-uniform speed for different polygons
16. try to avoid initialization and computing the full intersection graph
17. try to avoid randomization
18. add unconstrained pvertex to ivertex event
19. better region growing maybe using the global optimization
20. add 3D global regularization
21. try to have as few as possible events
22. add free-form reconstruction
23. add a way to quickly change the k-intersection criteria
24. make the code work both with exact and inexact kernels
25. add clustering for input clouds
26. add automatic learning input parameters
27. make the code work with all edge cases
28. add missing walls (exterior and interior), add missing roofs, add missing ground
29. create LCC
30. improve output such that I could return faces iteratively
1. Better future directions, compute them exactly and identify if the lines are parallel using the segment coordinates, unify them for all types of events, the function should take two points with the directions and two fixed points and return the future point and the future direction along the edge, one direction must be the limit direction and one direction must be the cropped direction.
2. Precompute occupied iedges while inserting new events.
3. Better graphcut by inserting information, which faces are originated by the roof and facade points.
4. Adaptive time step, e.g. doubled in case we had three steps and did not meet any event.
5. Precompute as mush as possible stuff, e.g. next events.
6. Fix initialization using the same trick I use for adding missing faces.
7. Put adding missing faces and remove faces in two separate files, they can be reused when working on the subdivision.
8. Add the finalizer class.
9. Make the initializer work with the inexact kernel.
10. Better polygon regularizer using the global approach.
11. Graph cut using normals and graphcut using the LOD.
12. Add timing tests, better tests, accelerate the code as much as possible.
13. Try to merge thin volumes in case we are beyond the tolerance value when traversing the volumes.
14. Add interface to insert custom planes for subdivision instead of uniform subdivision, in this case, we can avoid artifacts in the important parts of the model but still be much faster.
15. Try using non-uniform speed for different polygons.
16. Try to avoid initialization and computing the full intersection graph.
17. Try to avoid randomization.
18. Add unconstrained pvertex to ivertex event.
19. Better region growing maybe using the global optimization.
20. Add 3D global regularization.
21. Try to have as few as possible events.
22. Add free-form reconstruction.
23. Add a way to quickly change the k-intersection criteria.
24. Make the code work both with exact and inexact kernels.
25. Add clustering for input clouds.
26. Add automatic learning input parameters.
27. Make the code work with all edge cases.
28. Add missing walls (exterior and interior), add missing roofs, add missing ground.
29. Create LCC.
30. Improve output such that I could return faces iteratively.
31. Make regularization work with exact kernel.