diff --git a/BGL/test/BGL/test_bgl_read_write.cpp b/BGL/test/BGL/test_bgl_read_write.cpp index 139b45d05b5..0e10539dc19 100644 --- a/BGL/test/BGL/test_bgl_read_write.cpp +++ b/BGL/test/BGL/test_bgl_read_write.cpp @@ -1,32 +1,33 @@ #include +#include #include -#include #include #include #include #include -#include #if defined(CGAL_USE_OPENMESH) - #include #include #include - #endif -#include +#include +#include +#include -#include -#include #include #include typedef CGAL::Simple_cartesian Kernel; +typedef Kernel::Point_2 Point_2; typedef Kernel::Point_3 Point; +typedef Kernel::Vector_3 Vector; + +typedef CGAL::Exact_predicates_inexact_constructions_kernel EPICK; typedef CGAL::Polyhedron_3 Polyhedron; @@ -41,706 +42,751 @@ typedef OpenMesh::PolyMesh_ArrayKernelT #endif -template -void fill_soup(PointRange& points, PolygonRange& polygons) +template +bool are_equal_meshes(const Mesh& fg1, const VPM1 vpm1, const Mesh& fg2, const VPM2 vpm2) { - points.resize(4); - polygons.resize(4); - points[0] = Point(0, 0, 0); - points[1] = Point(1, 1, 0); - points[2] = Point(2, 0, 1); - points[3] = Point(3, 0, 0); - std::vector poly(3); - poly[0] = 0; - poly[1] = 1; - poly[2] = 2; - polygons[0] = poly; - poly[0] = 3; - poly[1] = 1; - poly[2] = 0; - polygons[1] = poly; - poly[0] = 3; - poly[1] = 2; - poly[2] = 1; - polygons[2] = poly; - poly[0] = 3; - poly[1] = 0; - poly[2] = 2; - polygons[3] = poly; + typedef typename boost::property_traits::value_type P; + + if(num_vertices(fg1) != num_vertices(fg2) || + num_halfedges(fg1) != num_halfedges(fg2) || + num_edges(fg1) != num_edges(fg2) || + num_faces(fg1) != num_faces(fg2)) + return false; + + std::set

fg1_points, fg2_points; + for(auto v : vertices(fg1)) + fg1_points.insert(get(vpm1, v)); + + for(auto v : vertices(fg2)) + fg2_points.insert(get(vpm2, v)); + + if(fg1_points != fg2_points) // @fixme this will break for precision reasons, so replace with tests like in stream_support + return false; + + // @todo test that combinatorics are equal + + return true; } -void test_polygon_soup_io() +template +bool are_equal_meshes(const Mesh& fg1, const Mesh& fg2) { - std::vector points; - std::vector > polygons; - fill_soup(points, polygons); - std::string filenames[5] = {"soup.obj", "soup.off", "soup.stl", "soup.ts", "soup.ply"}; - - for(const std::string& name : filenames) - CGAL_assertion(CGAL::write_polygon_soup(name, points, polygons)); - - for(const std::string& name : filenames) - { - points.clear(); - polygons.clear(); - CGAL_assertion(CGAL::read_polygon_soup(name, points, polygons)); - CGAL_assertion(points.size() == 4); - CGAL_assertion(polygons.size() == 4); - } -} - -template -void test_polygon_mesh_io() -{ - Mesh fg; - CGAL::make_tetrahedron(Point(0, 0, 0), Point(1, 1, 0), - Point(2, 0, 1), Point(3, 0, 0), fg); - - std::string filenames[6] = {"mesh.obj", "mesh.off", "mesh.stl", "mesh.ts", "mesh.ply", "mesh.vtp"}; - - for(const std::string& name : filenames) - { - CGAL_assertion(CGAL::write_polygon_mesh(name, fg)); - } - - for(const std::string& name : filenames) - { - fg.clear(); - CGAL_assertion(CGAL::read_polygon_mesh(name, fg)); - CGAL_assertion(num_vertices(fg) == 4); - CGAL_assertion(num_faces(fg) == 4); - } + return are_equal_meshes(fg1, get(CGAL::vertex_point, fg1), fg2, get(CGAL::vertex_point, fg2)); } template void test_bgl_OFF(const char* filename) { - Mesh sm; - std::ifstream in(filename); - CGAL::read_OFF(in,sm); - sm.clear(); - CGAL::read_polygon_mesh(filename, sm); - - CGAL::write_OFF(std::cout, sm); -} - -//todo check the result. -template -void test_bgl_OFF_with_np() -{ + // read with OFF Mesh fg; - std::ifstream in("data/full.off"); + std::ifstream is(filename); + bool ok = CGAL::read_OFF(is, fg); + assert(ok); + assert(num_vertices(fg) != 0 && num_faces(fg) != 0); - typedef typename boost::property_map >::type VertexNormalMap; - VertexNormalMap vnm = get(CGAL::dynamic_vertex_property_t(), fg); - - typedef typename boost::property_map >::type VertexColorMap; - VertexColorMap vcm = get(CGAL::dynamic_vertex_property_t(), fg); - - typedef typename boost::property_map >::type VertexTextureMap; - VertexTextureMap vtm = get(CGAL::dynamic_vertex_property_t(), fg); - - typedef typename boost::property_map >::type FaceColorMap; - FaceColorMap fcm = get(CGAL::dynamic_face_property_t(), fg); - - bool ok = CGAL::read_OFF(in, fg, CGAL::parameters::vertex_normal_map(vnm) - .vertex_color_map(vcm) - .vertex_texture_map(vtm) - .face_color_map(fcm)); - CGAL_assertion(ok); - - fg.clear(); - vnm = get(CGAL::dynamic_vertex_property_t(), fg); - ok = CGAL::read_polygon_mesh("data/full.off", fg, CGAL::parameters::vertex_normal_map(vnm) - .vertex_color_map(vcm) - .vertex_texture_map(vtm) - .face_color_map(fcm)); - CGAL_assertion(ok); - - ok = CGAL::write_OFF(std::cout, fg, CGAL::parameters::vertex_normal_map(vnm) - .vertex_color_map(vcm) - .vertex_texture_map(vtm) - .face_color_map(fcm)); - CGAL_assertion(ok); -} - -void test_soup_off(const char* filename) -{ - std::vector points; - std::vector > polygons; - std::ifstream in(filename); - - CGAL::read_OFF(in,points, polygons); - CGAL::write_OFF(std::cout, points, polygons); -} - -template -bool test_bgl_OBJ() -{ - Mesh fg; - CGAL::make_tetrahedron(Point(0, 0, 0), Point(1, 1, 0), - Point(2, 0, 1), Point(3, 0, 0), fg); - - std::ostringstream out; - CGAL::write_OBJ(out, fg); - - std::istringstream in(out.str()); - - fg.clear(); - CGAL::read_OBJ(in, fg); - CGAL_assertion(num_vertices(fg) == 4); - CGAL_assertion(num_faces(fg) == 4); - - fg.clear(); - CGAL::read_polygon_mesh("data/sphere.obj", fg); - CGAL_assertion(num_vertices(fg) == 162); - CGAL_assertion(num_faces(fg) == 320); - - return true; -} - -template -bool test_bgl_OBJ_with_np() -{ - Mesh fg, fg2; - CGAL::make_tetrahedron(Point(0, 0, 0), Point(1, 1, 0), - Point(2, 0, 1), Point(3, 0, 0), fg); - - typedef typename boost::property_map >::type VertexNormalMap; - VertexNormalMap vnm = get(CGAL::dynamic_vertex_property_t(), fg); - VertexNormalMap vnm2 = get(CGAL::dynamic_vertex_property_t(), fg2); - - for(const auto& v : vertices(fg)) - put(vnm, v, Kernel::Vector_3(0.0,1.0,0.0)); - - std::ostringstream out; - CGAL::write_OBJ(out, fg, CGAL::parameters::vertex_normal_map(vnm)); - - std::istringstream in(out.str()); - CGAL::read_OBJ(in, fg2, CGAL::parameters::vertex_normal_map(vnm2)); - CGAL_assertion(num_vertices(fg2) == 4); - CGAL_assertion(num_faces(fg2) == 4); - - CGAL_assertion(num_vertices(fg) == num_vertices(fg2)); - typename boost::graph_traits::vertex_iterator vit, vit2; - for(vit = vertices(fg).begin(), vit2 = vertices(fg2).begin(); vit != vertices(fg).end(); ++vit, ++vit2) + // write with OFF { - CGAL_assertion(get(vnm, *vit) == get(vnm2, *vit2)); + ok = CGAL::write_OFF(std::cout, fg); + assert(ok); + + std::ofstream os("tmp.off"); + ok = CGAL::write_OFF(os, fg); + assert(ok); + + Mesh fg2; + ok = CGAL::read_OFF("tmp.off", fg2); + assert(ok); + assert(are_equal_meshes(fg, fg2)); } - return true; + // write with PM + { + ok = CGAL::write_polygon_mesh("tmp.off", fg); + assert(ok); + + Mesh fg2; + ok = CGAL::read_polygon_mesh("tmp.off", fg2); + assert(ok); + assert(are_equal_meshes(fg, fg2)); + } + + // Test [STCN]OFF + typedef typename boost::property_map >::type VertexNormalMap; + typedef typename boost::property_map >::type VertexColorMap; + typedef typename boost::property_map >::type VertexTextureMap; + typedef typename boost::property_map >::type FaceColorMap; + + // COFF + { + clear(fg); + VertexColorMap vcm = get(CGAL::dynamic_vertex_property_t(), fg); + FaceColorMap fcm = get(CGAL::dynamic_face_property_t(), fg); + + ok = CGAL::read_OFF("data/mesh_with_colors.off", fg, CGAL::parameters::vertex_color_map(vcm) + .face_color_map(fcm)); + assert(ok); + assert(num_vertices(fg) == 8 && num_faces(fg) == 4); + + for(const auto v : vertices(fg)) + assert(get(vcm, v) != CGAL::Color()); + + for(const auto f : faces(fg)) + assert(get(fcm, f) != CGAL::Color()); + + // write with OFF + { + std::ofstream os("tmp.off"); + ok = CGAL::write_OFF("tmp.off", fg, CGAL::parameters::vertex_color_map(vcm) + .face_color_map(fcm)); + assert(ok); + + Mesh fg2; + VertexColorMap vcm2 = get(CGAL::dynamic_vertex_property_t(), fg2); + FaceColorMap fcm2 = get(CGAL::dynamic_face_property_t(), fg2); + + ok = CGAL::read_polygon_mesh("tmp.off", fg2, CGAL::parameters::vertex_color_map(vcm2) + .face_color_map(fcm2)); + assert(ok); + assert(are_equal_meshes(fg, fg2)); + + for(const auto v : vertices(fg2)) + assert(get(vcm2, v) != CGAL::Color()); + + for(const auto f : faces(fg2)) + assert(get(fcm2, f) != CGAL::Color()); + } + + // write with PM + { + ok = CGAL::write_polygon_mesh("tmp.off", fg, CGAL::parameters::vertex_color_map(vcm)); + assert(ok); + + Mesh fg2; + VertexColorMap vcm2 = get(CGAL::dynamic_vertex_property_t(), fg2); + + ok = CGAL::read_polygon_mesh("tmp.off", fg2, CGAL::parameters::vertex_color_map(vcm2)); + assert(ok); + assert(are_equal_meshes(fg, fg2)); + + for(const auto v : vertices(fg2)) + assert(get(vcm2, v) != CGAL::Color()); + } + } + + // NOFF + { + clear(fg); + VertexNormalMap vnm = get(CGAL::dynamic_vertex_property_t(), fg); + + ok = CGAL::read_OFF("data/mesh_with_normals.off", fg, CGAL::parameters::vertex_normal_map(vnm)); + assert(ok); + + for(const auto v : vertices(fg)) + assert(get(vnm, v) != CGAL::NULL_VECTOR); + + // write with OFF + { + std::ofstream os("tmp.off"); + ok = CGAL::write_OFF("tmp.off", fg, CGAL::parameters::vertex_normal_map(vnm)); + assert(ok); + + Mesh fg2; + VertexNormalMap vnm2 = get(CGAL::dynamic_vertex_property_t(), fg2); + + ok = CGAL::read_polygon_mesh("tmp.off", fg2, CGAL::parameters::vertex_normal_map(vnm2)); + assert(ok); + assert(are_equal_meshes(fg, fg2)); + + for(const auto v : vertices(fg2)) + assert(get(vnm2, v) != CGAL::NULL_VECTOR); + } + + // write with PM + { + ok = CGAL::write_polygon_mesh("tmp.off", fg, CGAL::parameters::vertex_normal_map(vnm)); + assert(ok); + + Mesh fg2; + VertexNormalMap vnm2 = get(CGAL::dynamic_vertex_property_t(), fg2); + + ok = CGAL::read_polygon_mesh("tmp.off", fg2, CGAL::parameters::vertex_normal_map(vnm2)); + assert(ok); + assert(are_equal_meshes(fg, fg2)); + + for(const auto v : vertices(fg2)) + assert(get(vnm2, v) != CGAL::NULL_VECTOR); + } + } + + // STCNOFF + { + clear(fg); + std::ifstream is("data/full.off"); + + VertexNormalMap vnm = get(CGAL::dynamic_vertex_property_t(), fg); + VertexColorMap vcm = get(CGAL::dynamic_vertex_property_t(), fg); + VertexTextureMap vtm = get(CGAL::dynamic_vertex_property_t(), fg); + FaceColorMap fcm = get(CGAL::dynamic_face_property_t(), fg); + + ok = CGAL::read_OFF(is, fg, CGAL::parameters::vertex_normal_map(vnm) + .vertex_color_map(vcm) + .vertex_texture_map(vtm) + .face_color_map(fcm)); + assert(ok); + assert(num_vertices(fg) != 0 && num_faces(fg) != 0); + + for(const auto v : vertices(fg)) + { + assert(get(vnm, v) != CGAL::NULL_VECTOR); + assert(get(vcm, v) != CGAL::Color()); + assert(get(vtm, v) != Point_2()); + } + + for(const auto f : faces(fg)) + assert(get(fcm, f) != CGAL::Color()); + + // write with OFF + { + std::ofstream os("tmp.off"); + ok = CGAL::write_OFF("tmp.off", fg, CGAL::parameters::vertex_normal_map(vnm) + .vertex_color_map(vcm) + .vertex_texture_map(vtm) + .face_color_map(fcm)); + assert(ok); + + Mesh fg2; + VertexNormalMap vnm2 = get(CGAL::dynamic_vertex_property_t(), fg2); + VertexColorMap vcm2 = get(CGAL::dynamic_vertex_property_t(), fg2); + VertexTextureMap vtm2 = get(CGAL::dynamic_vertex_property_t(), fg2); + FaceColorMap fcm2 = get(CGAL::dynamic_face_property_t(), fg2); + + ok = CGAL::read_polygon_mesh("tmp.off", fg2, CGAL::parameters::vertex_normal_map(vnm2) + .vertex_color_map(vcm2) + .vertex_texture_map(vtm2) + .face_color_map(fcm2)); + assert(ok); + assert(are_equal_meshes(fg, fg2)); + + for(const auto v : vertices(fg2)) + { + assert(get(vnm2, v) != CGAL::NULL_VECTOR); + assert(get(vcm2, v) != CGAL::Color()); + assert(get(vtm2, v) != Point_2()); + } + + for(const auto f : faces(fg2)) + assert(get(fcm2, f) != CGAL::Color()); + } + + // write with PM + { + ok = CGAL::write_polygon_mesh("tmp.off", fg, CGAL::parameters::vertex_normal_map(vnm)); + assert(ok); + + Mesh fg2; + VertexNormalMap vnm2 = get(CGAL::dynamic_vertex_property_t(), fg2); + VertexColorMap vcm2 = get(CGAL::dynamic_vertex_property_t(), fg2); + VertexTextureMap vtm2 = get(CGAL::dynamic_vertex_property_t(), fg2); + FaceColorMap fcm2 = get(CGAL::dynamic_face_property_t(), fg2); + + ok = CGAL::read_polygon_mesh("tmp.off", fg2, CGAL::parameters::vertex_normal_map(vnm2) + .vertex_color_map(vcm2) + .vertex_texture_map(vtm2) + .face_color_map(fcm2)); + assert(ok); + assert(are_equal_meshes(fg, fg2)); + + for(const auto v : vertices(fg2)) + { + assert(get(vnm2, v) != CGAL::NULL_VECTOR); + assert(get(vcm2, v) != CGAL::Color()); + assert(get(vtm2, v) != Point_2()); + } + + for(const auto f : faces(fg2)) + assert(get(fcm2, f) != CGAL::Color()); + } + } + + // test wrong inputs + ok = CGAL::read_OFF("data/mesh_that_doesnt_exist.off", fg); + assert(!ok); + ok = CGAL::read_OFF("data/invalid_cut.off", fg); // cut in half + assert(!ok); + ok = CGAL::read_OFF("data/invalid_header.off", fg); // wrong header (NOFF but no normals) + assert(!ok); + ok = CGAL::read_OFF("data/invalid_nv.off", fg); // wrong number of points + assert(!ok); + ok = CGAL::read_OFF("data/sphere.obj", fg); + assert(!ok); + ok = CGAL::read_OFF("data/pig.stl", fg); + assert(!ok); } -void test_bgl_soup_obj() +template +void test_bgl_OBJ(const std::string filename) { - std::vector points; - std::vector > polygons; - fill_soup(points, polygons); + Mesh fg; + + std::ifstream is(filename); + bool ok = CGAL::read_OBJ(is, fg); + assert(ok); + assert(filename != "data/sphere.obj" || (num_vertices(fg) == 162 && num_faces(fg) == 320)); + + // write with OBJ + { + ok = CGAL::write_OBJ(std::cout, fg); + + std::ofstream os("tmp.obj"); + ok = CGAL::write_OBJ(os, fg); + assert(ok); + + Mesh fg2; + ok = CGAL::read_OBJ("tmp.obj", fg2); + assert(ok); + assert(are_equal_meshes(fg, fg2)); + } + + // write with PM + { + ok = CGAL::write_polygon_mesh("tmp.obj", fg); + assert(ok); + + Mesh fg2; + ok = CGAL::read_polygon_mesh("tmp.obj", fg2); + assert(ok); + assert(are_equal_meshes(fg, fg2)); + } + + // Test NPs + typedef typename boost::property_map >::type VertexNormalMap; + + clear(fg); + VertexNormalMap vnm = get(CGAL::dynamic_vertex_property_t(), fg); + + ok = CGAL::read_OBJ("data/90089.obj", fg, CGAL::parameters::vertex_normal_map(vnm)); + assert(ok); + assert(num_vertices(fg) == 434 && num_faces(fg) == 864); + + for(const auto v : vertices(fg)) + assert(get(vnm, v) != CGAL::NULL_VECTOR); + + // write with OBJ + { + std::ofstream os("tmp.obj"); + ok = CGAL::write_OBJ("tmp.obj", fg, CGAL::parameters::vertex_normal_map(vnm)); + assert(ok); + + Mesh fg2; + VertexNormalMap vnm2 = get(CGAL::dynamic_vertex_property_t(), fg2); + + ok = CGAL::read_polygon_mesh("tmp.obj", fg2, CGAL::parameters::vertex_normal_map(vnm2)); + assert(ok); + assert(are_equal_meshes(fg, fg2)); + + for(const auto v : vertices(fg2)) + assert(get(vnm2, v) != CGAL::NULL_VECTOR); + } + + // write with PM + { + ok = CGAL::write_polygon_mesh("tmp.obj", fg, CGAL::parameters::vertex_normal_map(vnm)); + assert(ok); + + Mesh fg2; + VertexNormalMap vnm2 = get(CGAL::dynamic_vertex_property_t(), fg2); + + ok = CGAL::read_polygon_mesh("tmp.obj", fg2, CGAL::parameters::vertex_normal_map(vnm2)); + assert(ok); + assert(are_equal_meshes(fg, fg2)); + + for(const auto v : vertices(fg2)) + assert(get(vnm2, v) != CGAL::NULL_VECTOR); + } + + // test wrong inputs + ok = CGAL::read_OBJ("data/mesh_that_doesnt_exist.obj", fg); + assert(!ok); + ok = CGAL::read_OBJ("data/invalid_cut.obj", fg); // cut in half + assert(!ok); + ok = CGAL::read_OBJ("data/invalid_nv.obj", fg); // broken formatting + assert(!ok); + ok = CGAL::read_OBJ("data/genus3.obj", fg); // wrong extension + assert(!ok); + ok = CGAL::read_OBJ("data/pig.stl", fg); + assert(!ok); +} + +template +void test_bgl_PLY(const std::string filename, + bool binary = false) +{ + Mesh fg; + std::ifstream is(filename); + if(binary) + CGAL::set_mode(is, CGAL::IO::BINARY); + + bool ok = CGAL::read_PLY(is, fg); + assert(ok); + assert(filename != "data/colored_tetra.ply" || (num_vertices(fg) == 4 && num_faces(fg) == 4)); + + // write with PLY + { + ok = CGAL::write_PLY(std::cout, fg); + assert(ok); + + std::ofstream os("tmp.ply"); + if(binary) + CGAL::set_mode(os, CGAL::IO::BINARY); + + ok = CGAL::write_PLY(os, fg); + assert(ok); + + ok = CGAL::write_PLY(os, fg, "test"); + assert(ok); + + Mesh fg2; + if(binary) + { + ok = CGAL::read_PLY("tmp.ply", fg2); + } + else + { + std::ifstream is(filename); + ok = CGAL::read_PLY("tmp.ply", fg2); + } + + assert(ok); + assert(are_equal_meshes(fg, fg2)); + } + + // test NPs + typedef typename boost::property_map >::type VertexColorMap; + typedef typename boost::property_map >::type FaceColorMap; + + clear(fg); + VertexColorMap vcm = get(CGAL::dynamic_vertex_property_t(), fg); + FaceColorMap fcm = get(CGAL::dynamic_face_property_t(), fg); + + std::ifstream is_c("data/colored_tetra.ply"); // ASCII + ok = CGAL::read_PLY(is_c, fg, CGAL::parameters::vertex_color_map(vcm) + .face_color_map(fcm)); + assert(ok); + assert(num_vertices(fg) == 4 && num_faces(fg) == 4); + + for(const auto v : vertices(fg)) + assert(get(vcm, v) != CGAL::Color()); + + for(const auto f : faces(fg)) + assert(get(fcm, f) != CGAL::Color()); + + // write with PLY + { + std::ofstream os("tmp.ply"); + if(binary) + CGAL::set_mode(os, CGAL::IO::BINARY); + + ok = CGAL::write_PLY("tmp.ply", fg, CGAL::parameters::vertex_color_map(vcm) + .face_color_map(fcm)); + assert(ok); + + Mesh fg2; + VertexColorMap vcm2 = get(CGAL::dynamic_vertex_property_t(), fg2); + FaceColorMap fcm2 = get(CGAL::dynamic_face_property_t(), fg2); + + std::ifstream is_rpm("tmp.ply"); + if(binary) + CGAL::set_mode(is_rpm, CGAL::IO::BINARY); + ok = CGAL::read_PLY(is_c, fg, CGAL::parameters::vertex_color_map(vcm2) + .face_color_map(fcm2)); + assert(ok); + assert(are_equal_meshes(fg, fg2)); + + for(const auto v : vertices(fg2)) + assert(get(vcm2, v) != CGAL::Color()); + + for(const auto f : faces(fg2)) + assert(get(fcm2, f) != CGAL::Color()); + } + + // write with PM + { + std::ofstream os("tmp.ply"); + if(binary) + CGAL::set_mode(os, CGAL::IO::BINARY); + ok = CGAL::write_polygon_mesh("tmp.ply", fg, CGAL::parameters::vertex_color_map(vcm) + .face_color_map(fcm)); + assert(ok); + + Mesh fg2; + VertexColorMap vcm2 = get(CGAL::dynamic_vertex_property_t(), fg2); + FaceColorMap fcm2 = get(CGAL::dynamic_face_property_t(), fg2); + + ok = CGAL::read_polygon_mesh("tmp.ply", fg2, CGAL::parameters::vertex_color_map(vcm2) + .face_color_map(fcm2)); + assert(ok); + assert(are_equal_meshes(fg, fg2)); + + for(const auto v : vertices(fg2)) + assert(get(vcm2, v) != CGAL::Color()); + + for(const auto f : faces(fg2)) + assert(get(fcm2, f) != CGAL::Color()); + } + + // test wrong inputs + ok = CGAL::read_PLY("data/mesh_that_doesnt_exist.ply", fg); + assert(!ok); + ok = CGAL::read_PLY("data/invalid_cut.ply", fg); // cut in half + assert(!ok); + ok = CGAL::read_PLY("data/invalid_nv.ply", fg); // broken formatting + assert(!ok); + ok = CGAL::read_PLY("data/cube.off", fg); + assert(!ok); + ok = CGAL::read_PLY("data/pig.stl", fg); + assert(!ok); +} + +template +struct Custom_VPM +{ + typedef Custom_VPM Self; + + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + + typedef vertex_descriptor key_type; + typedef EPICK::Point_3 value_type; + typedef value_type& reference; + typedef boost::lvalue_property_map_tag category; + + Custom_VPM(std::map& points) : points(points) { } + + friend void put(const Self& m, const key_type& k, const value_type& v) { m.points[k] = value_type(v.x(), v.y(), v.z()); } + friend reference get(const Self& m, const key_type& k) { return m.points[k]; } + + std::map& points; +}; + +template +void test_bgl_STL(const std::string filename) +{ + Mesh fg; + + bool ok = CGAL::read_STL(filename, fg); + assert(ok); + ok = CGAL::write_STL("tmp.stl", fg); + assert(ok); + + clear(fg); + + std::map::vertex_descriptor, EPICK::Point_3> cpoints; + Custom_VPM cvpm(cpoints); + + std::ifstream is(filename); + ok = CGAL::read_STL(is, fg, CGAL::parameters::vertex_point_map(cvpm)); + assert(ok); + assert(filename != "data/sphere.stl" || (num_vertices(fg) == 162 && num_faces(fg) == 320)); + assert(filename != "data/sphere.stl" || cpoints.size() == 162); + + // write with STL + { + ok = CGAL::write_STL(std::cout, fg, CGAL::parameters::vertex_point_map(cvpm)); + assert(ok); + + std::ofstream os("tmp.stl"); + ok = CGAL::write_STL(os, fg, CGAL::parameters::vertex_point_map(cvpm)); + assert(ok); + + Mesh fg2; + ok = CGAL::read_STL("tmp.stl", fg2, CGAL::parameters::vertex_point_map(cvpm)); + assert(ok); + assert(num_vertices(fg) == num_vertices(fg2) && num_faces(fg) == num_faces(fg2)); + } + + // write with PM + { + ok = CGAL::write_polygon_mesh("tmp.stl", fg, CGAL::parameters::vertex_point_map(cvpm)); + assert(ok); + + Mesh fg2; + ok = CGAL::read_polygon_mesh("tmp.stl", fg2, CGAL::parameters::vertex_point_map(cvpm)); + assert(ok); + assert(num_vertices(fg) == num_vertices(fg2) && num_faces(fg) == num_faces(fg2)); + } + + // @todo test wrong inputs (see tests of other formats) +} + +template +void test_bgl_GOCAD(const char* filename) +{ + Mesh fg; + std::ifstream is(filename); + bool ok = CGAL::read_GOCAD(is, fg); + assert(ok); + assert(num_vertices(fg) != 0 && num_faces(fg) != 0); + + clear(fg); + std::pair name_and_color; + ok = CGAL::read_GOCAD(is, name_and_color, fg); + assert(ok); + assert(num_vertices(fg) != 0 && num_faces(fg) != 0); + + // write with GOCAD + { + ok = CGAL::write_GOCAD(std::cout, fg); + assert(ok); + + std::ofstream os("tmp.ts"); + bool ok = CGAL::write_GOCAD(os, "tetrahedron", fg); + assert(ok); + + Mesh fg2; + std::pair cnn; + ok = CGAL::read_GOCAD("tmp.ts", cnn, fg2); + assert(ok); + assert(are_equal_meshes(fg, fg2)); + assert(cnn.first == "tetrahedron"); + } + + // write with PM + { + ok = CGAL::write_polygon_mesh("tmp.off", fg); + assert(ok); + + Mesh fg2; + ok = CGAL::read_polygon_mesh("tmp.off", fg2); + assert(ok); + assert(are_equal_meshes(fg, fg2)); + } + + // test NPs + typedef typename boost::property_map::type VertexPointMap; + + VertexPointMap vpm = get(CGAL::vertex_point, fg); std::ostringstream out; - CGAL::write_OBJ(out, points, polygons); + ok = CGAL::write_GOCAD(out, "tetrahedron", fg, CGAL::parameters::vertex_point_map(vpm)); + assert(ok); - points.clear(); - polygons.clear(); + { + Mesh fg2; + VertexPointMap vpm2 = get(CGAL::vertex_point, fg2); + std::istringstream is(out.str()); + std::pair cnn; + ok = CGAL::read_GOCAD(is, cnn, fg2, CGAL::parameters::vertex_point_map(vpm2)); + assert(ok); + assert(cnn.second.empty()); + assert(num_vertices(fg2) == 4); + assert(num_faces(fg2) == 4); + } - std::istringstream in(out.str()); - CGAL::read_OBJ(in,points, polygons); - CGAL_assertion(points.size() == 4); - CGAL_assertion(polygons.size() == 4); + // @todo test wrong inputs (see tests of other formats) } #ifdef CGAL_USE_VTK template -bool test_bgl_vtp(bool binary = false) +void test_bgl_VTP(const char* filename, // @fixme not finished + const bool binary = false) { Mesh fg; CGAL::make_tetrahedron(Point(0, 0, 0), Point(1, 1, 0), Point(2, 0, 1), Point(3, 0, 0), fg); std::ofstream os("tetrahedron.vtp"); - CGAL::write_VTP(os, fg, CGAL::parameters::use_binary_mode(binary)); - if(!os) - { - std::cerr << "vtp writing failed." << std::endl; - return false; - } + bool ok = CGAL::write_VTP(os, fg, CGAL::parameters::use_binary_mode(binary)); + assert(ok); - os.close(); Mesh fg2; - if(!CGAL::read_polygon_mesh("tetrahedron.vtp", fg2)) - { - std::cerr << "vtp reading failed." << std::endl; - return false; - } - - if(num_vertices(fg) != num_vertices(fg2) || num_faces(fg) != num_faces(fg2)) - { - std::cerr << "Coherence problem. Wrong number of vertices or faces." << std::endl; - return false; - } - - return true; + ok = CGAL::read_polygon_mesh("tetrahedron.vtp", fg2); + assert(ok); + assert(are_equal_meshes(fg, fg2)); } template<> -bool test_bgl_vtp(bool binary) +void test_bgl_VTP(const char* filename, + const bool binary) { Polyhedron fg; CGAL::make_tetrahedron(Point(0, 0, 0), Point(1, 1, 0), Point(2, 0, 1), Point(3, 0, 0), fg); typedef boost::property_map >::type VertexIdMap; - VertexIdMap vid = get(CGAL::dynamic_vertex_property_t(), fg); + VertexIdMap vid = get(CGAL::dynamic_vertex_property_t(), fg); std::size_t id = 0; for(auto v : vertices(fg)) - put(vid,v, id++); + put(vid, v, id++); std::ofstream os("tetrahedron.vtp"); - CGAL::write_VTP(os, fg, CGAL::parameters::vertex_index_map(vid).use_binary_mode(binary)); - if(!os) - { - std::cerr << "vtp writing failed." << std::endl; - return false; - } - os.close(); + bool ok = CGAL::write_VTP(os, fg, CGAL::parameters::vertex_index_map(vid).use_binary_mode(binary)); + assert(ok); Polyhedron fg2; - if(!CGAL::read_polygon_mesh("tetrahedron.vtp", fg2)) - { - std::cerr << "vtp reading failed." << std::endl; - return false; - } + ok = CGAL::read_polygon_mesh("tetrahedron.vtp", fg2); + assert(ok); - if(num_vertices(fg) != num_vertices(fg2) || num_faces(fg) != num_faces(fg2)) - { - std::cerr << "Coherence problem. Wrong number of vertices or faces." << std::endl; - return false; - } - - return true; -} - -bool test_soup_vtp(bool binary = false) -{ - //generate a test file - std::vector points; - std::vector > polys; - fill_soup(points, polys); - - std::ofstream os("tetrahedron_soup.vtp"); - CGAL::write_VTP(os, points, polys, CGAL::parameters::use_binary_mode(binary)); - if(!os) - { - std::cerr << "vtp writing failed." << std::endl; - return false; - } - os.close(); - - std::vector soup_points; - std::vector > soup_polygons; - CGAL::read_VTP("tetrahedron_soup.vtp", soup_points, soup_polygons); - if(4 != soup_points.size() || 4 != soup_polygons.size()) - { - std::cerr << "Coherence problem. Wrong number of vertices or faces." << std::endl; - return false; - } - - return true; -} - -#endif - -template -bool test_bgl_gocad() -{ - FaceGraph fg; - CGAL::make_tetrahedron(Point(0, 0, 0), Point(1, 1, 0), - Point(2, 0, 1), Point(3, 0, 0), fg); - - std::ostringstream out; - CGAL::write_GOCAD(out, "tetrahedron", fg); - if(out.fail()) - { - std::cerr << "Tetrahedron writing failed." << std::endl; - return false; - } - - FaceGraph fg2; - std::istringstream in(out.str()); - std::pair cnn; - CGAL::read_GOCAD(in, cnn, fg2); - if(cnn.first != "tetrahedron") - { - std::cerr << "reading error: tetrahedron != " < cnn; - CGAL::read_GOCAD(in, cnn, fg2, CGAL::parameters::vertex_point_map(vpm2)); - if(cnn.first != "tetrahedron") - { - std::cerr << "reading error: tetrahedron != " < soup_points; - std::vector > soup_polygons; - CGAL::read_GOCAD("tetrahedron.ts", soup_points, soup_polygons); - if(4 != soup_points.size() - || 4 != soup_polygons.size()) - { - std::cerr << "Coherence problem. Wrong number of vertices or faces." << std::endl; - return false; - } - - return true; -} - -template -bool test_bgl_stl() -{ - FaceGraph fg; - CGAL::make_tetrahedron(Point(0, 0, 0), Point(1, 1, 0), - Point(2, 0, 1), Point(3, 0, 0), fg); - std::ostringstream out; - CGAL::write_STL(out, fg); - if(out.fail()) - { - std::cerr << "Tetrahedron writing failed." << std::endl; - return false; - } - FaceGraph fg2; - std::istringstream in(out.str()); - if(!CGAL::read_STL(in, fg2)){ - std::cerr << "Tetrahedron reading failed." << std::endl; - return false; - } - - if(num_vertices(fg2) != 4){ - std::cerr << "Wrong number of vertices: 4 != " << num_vertices(fg2) << std::endl; - return false; - } - - if(num_faces(fg2) != 4) - { - std::cerr << "Wrong number of faces: 4 != " << num_faces(fg2) << std::endl; - return false; - } - - return true; -} - -template -bool test_bgl_PLY(bool binary = false) -{ - FaceGraph fg; - CGAL::make_tetrahedron(Point(0, 0, 0), Point(1, 1, 0), - Point(2, 0, 1), Point(3, 0, 0), fg); - std::ostringstream out; - - if(binary) - CGAL::set_mode(out, CGAL::IO::BINARY); - - CGAL::write_PLY(out, fg, "hello"); - if(out.fail()) - { - std::cerr << "Tetrahedron writing failed." << std::endl; - return false; - } - std::istringstream in(out.str()); - - if(binary) - CGAL::set_mode(in, CGAL::IO::BINARY); - - fg.clear(); - if(!CGAL::read_PLY(in, fg)) - { - std::cerr << "Tetrahedron reading failed." << std::endl; - return false; - } - CGAL_assertion(num_vertices(fg) == 4); - CGAL_assertion(num_faces(fg) == 4); - - return true; -} - -template -bool test_bgl_PLY_with_np(bool binary) -{ - FaceGraph fg; - CGAL::make_tetrahedron(Point(0, 0, 0), Point(1, 1, 0), - Point(2, 0, 1), Point(3, 0, 0), fg); - - typedef typename boost::property_map >::type VertexColorMap; - typedef typename boost::property_map >::type FaceColorMap; - FaceColorMap fcm = get(CGAL::dynamic_face_property_t(), fg); - VertexColorMap vcm = get(CGAL::dynamic_vertex_property_t(), fg); - - auto fit = faces(fg).begin(); - put(fcm,*fit++,CGAL::Color(155,0,0)); - put(fcm,*fit++,CGAL::Color(0,155,0)); - put(fcm,*fit++,CGAL::Color(0,0,155)); - put(fcm,*fit++,CGAL::Color(155,0,155)); - - auto vit = vertices(fg).begin(); - put(vcm,*vit++,CGAL::Color(255,0,0)); - put(vcm,*vit++,CGAL::Color(0,255,0)); - put(vcm,*vit++,CGAL::Color(0,0,255)); - put(vcm,*vit++,CGAL::Color(255,0,255)); - std::ostringstream out; - - if(binary) - CGAL::set_mode(out, CGAL::IO::BINARY); - - CGAL::write_PLY(out, fg, "hello", CGAL::parameters::vertex_color_map(vcm).face_color_map(fcm)); - if(out.fail()) - { - std::cerr << "Tetrahedron writing failed." << std::endl; - return false; - } - - std::istringstream in(out.str()); - if(binary) - CGAL::set_mode(in, CGAL::IO::BINARY); - - fg.clear(); - - VertexColorMap vcm2 = get(CGAL::dynamic_vertex_property_t(), fg); - FaceColorMap fcm2 = get(CGAL::dynamic_face_property_t(), fg); - if(!CGAL::read_PLY(in, fg, CGAL::parameters::vertex_color_map(vcm2).face_color_map(fcm2))){ - std::cerr << "Tetrahedron reading failed." << std::endl; - return false; - } - CGAL_assertion(num_vertices(fg) == 4); - CGAL_assertion(num_faces(fg) == 4); - - vit = vertices(fg).begin(); - CGAL_assertion(get(vcm2, *vit++) == CGAL::Color(255,0,0)); - CGAL_assertion(get(vcm2, *vit++) == CGAL::Color(0,255,0)); - CGAL_assertion(get(vcm2, *vit++) == CGAL::Color(0,0,255)); - CGAL_assertion(get(vcm2, *vit++) == CGAL::Color(255,0,255)); - - fit = faces(fg).begin(); - CGAL_assertion(get(fcm2,*fit++)==CGAL::Color(155,0,0)); - CGAL_assertion(get(fcm2,*fit++)==CGAL::Color(0,155,0)); - CGAL_assertion(get(fcm2,*fit++)==CGAL::Color(0,0,155)); - CGAL_assertion(get(fcm2,*fit++)==CGAL::Color(155,0,155)); - - return true; + assert(are_equal_meshes(fg, fg2)); } +#endif // CGAL_USE_VTK int main(int argc, char** argv) { - test_polygon_soup_io(); - test_polygon_mesh_io(); - test_polygon_mesh_io(); - test_polygon_mesh_io(); - // OFF - const char* filename = (argc>1) ? argv[1] : "data/prim.off"; - test_bgl_OFF(filename); - test_bgl_OFF(filename); - test_bgl_OFF(filename); + const char* off_file = (argc > 1) ? argv[1] : "data/prim.off"; + test_bgl_OFF(off_file); + test_bgl_OFF(off_file); + test_bgl_OFF(off_file); #ifdef CGAL_USE_OPENMESH - test_bgl_OFF(filename); + test_bgl_OFF(off_file); #endif - // polyhedron's overload doesn't care for any np that is not vpm - test_bgl_OFF_with_np(); - test_bgl_OFF_with_np(); - test_bgl_OFF_with_np(); -#ifdef CGAL_USE_OPENMESH - test_bgl_OFF_with_np(); -#endif - test_soup_off(filename); - // OBJ - test_bgl_OBJ(); - test_bgl_OBJ(); - test_bgl_OBJ(); - test_bgl_soup_obj(); + const char* obj_file = (argc > 2) ? argv[2] : "data/sphere.obj"; + test_bgl_OBJ(obj_file); + test_bgl_OBJ(obj_file); + test_bgl_OBJ(obj_file); #ifdef CGAL_USE_OPENMESH - test_bgl_OBJ(); -#endif - - test_bgl_OBJ_with_np(); - test_bgl_OBJ_with_np(); - test_bgl_OBJ_with_np(); -#ifdef CGAL_USE_OPENMESH - test_bgl_OBJ_with_np(); + test_bgl_OBJ(obj_file); #endif // PLY - if(!test_bgl_PLY()) - return EXIT_FAILURE; - if(!test_bgl_PLY(true)) - return EXIT_FAILURE; - if(!test_bgl_PLY()) - return EXIT_FAILURE; - if(!test_bgl_PLY(true)) - return EXIT_FAILURE; + const char* ply_file_ascii = (argc > 3) ? argv[3] : "data/colored_tetra.ply"; + test_bgl_PLY(ply_file_ascii, false); + test_bgl_PLY(ply_file_ascii, false); - if(!test_bgl_PLY_with_np(false)) - return EXIT_FAILURE; - if(!test_bgl_PLY_with_np(true)) - return EXIT_FAILURE; - if(!test_bgl_PLY_with_np(false)) - return EXIT_FAILURE; - if(!test_bgl_PLY_with_np(true)) - return EXIT_FAILURE; - - // GOCAD - if(!test_bgl_gocad()) - return EXIT_FAILURE; - if(!test_bgl_gocad()) - return EXIT_FAILURE; - if(!test_bgl_gocad()) - return EXIT_FAILURE; - if(!test_bgl_gocad_with_np()) - return EXIT_FAILURE; - if(!test_bgl_gocad_with_np()) - return EXIT_FAILURE; - if(!test_bgl_gocad_with_np()) - return EXIT_FAILURE; - if(!test_soup_gocad()) - return EXIT_FAILURE; + const char* ply_file = (argc > 3) ? argv[3] : "data/colored_tetra.ply"; + test_bgl_PLY(ply_file, true); + test_bgl_PLY(ply_file, true); // STL - if(!test_bgl_stl()) - return EXIT_FAILURE; - if(!test_bgl_stl()) - return EXIT_FAILURE; - if(!test_bgl_stl()) - return EXIT_FAILURE; + const char* stl_file = (argc > 4) ? argv[4] : "data/pig.stl"; + test_bgl_STL(stl_file); + test_bgl_STL(stl_file); + test_bgl_STL(stl_file); +#ifdef CGAL_USE_OPENMESH + test_bgl_STL(stl_file); +#endif + + // GOCAD + const char* gocad_file = (argc > 5) ? argv[5] : "data/2016206_MHT_surface.ts"; + test_bgl_GOCAD(gocad_file); + test_bgl_GOCAD(gocad_file); + test_bgl_GOCAD(gocad_file); +#ifdef CGAL_USE_OPENMESH + test_bgl_GOCAD(gocad_file); +#endif // VTP #ifdef CGAL_USE_VTK - if(!test_bgl_vtp(false)) - return EXIT_FAILURE; - if(!test_bgl_vtp(false)) - return EXIT_FAILURE; - if(!test_bgl_vtp(false)) - return EXIT_FAILURE; - if(!test_soup_vtp(false)) - return EXIT_FAILURE; + const char* vtp_file = (argc > 6) ? argv[6] : "data/prim.off"; // @fixme put a VTP file - if(!test_bgl_vtp(true)) - return EXIT_FAILURE; - if(!test_bgl_vtp(true)) - return EXIT_FAILURE; - if(!test_bgl_vtp(true)) - return EXIT_FAILURE; - if(!test_soup_vtp(true)) - return EXIT_FAILURE; + test_bgl_VTP(vtp_file, false); + test_bgl_VTP(vtp_file, false); + test_bgl_VTP(vtp_file, false); + + test_bgl_VTP(vtp_file, true); + test_bgl_VTP(vtp_file, true); + test_bgl_VTP(vtp_file, true); #endif return EXIT_SUCCESS;