From d5d8cca92bcd0642d4a93c012dbc280af0a1d3c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mael=20Rouxel-Labb=C3=A9?= Date: Thu, 25 Jun 2020 12:02:01 +0200 Subject: [PATCH] Various IO compilation fixes --- ..._from_stream_vs_add_face_and_add_faces.cpp | 57 +++++++++++++------ BGL/test/BGL/test_bgl_read_write.cpp | 37 +++++------- .../Convex_hull_3/test_ch_3_ambiguity.cpp | 14 ++--- .../Optimal_bounding_box/bench_obb.cpp | 47 ++------------- .../oriented_bounding_box.h | 2 - Point_set_3/include/CGAL/Point_set_3/IO/PLY.h | 18 +++--- .../test_read_write_point_set.cpp | 5 +- .../repair_degeneracies.h | 2 +- .../scale_space.cpp | 12 ++-- .../scale_space_advancing_front.cpp | 13 ++--- .../scale_space_incremental.cpp | 9 ++- .../scale_space_manifold.cpp | 7 +-- Stream_support/include/CGAL/IO/OBJ.h | 4 +- .../include/CGAL/IO/OFF/File_scanner_OFF.h | 4 +- Stream_support/include/CGAL/IO/helpers.h | 2 +- Surface_mesh/test/Surface_mesh/SM_common.h | 2 +- .../edgewidth_surface_mesh.cpp | 15 ++--- .../path_homotopy_with_sm_and_polyhedron.cpp | 8 ++- 18 files changed, 117 insertions(+), 141 deletions(-) diff --git a/BGL/test/BGL/bench_read_from_stream_vs_add_face_and_add_faces.cpp b/BGL/test/BGL/bench_read_from_stream_vs_add_face_and_add_faces.cpp index 39ecdb7ef6a..cf084977444 100644 --- a/BGL/test/BGL/bench_read_from_stream_vs_add_face_and_add_faces.cpp +++ b/BGL/test/BGL/bench_read_from_stream_vs_add_face_and_add_faces.cpp @@ -1,11 +1,12 @@ #include #include + +#include +#include +#include + #include #include -#include -#include - -#include typedef CGAL::Simple_cartesian Kernel; typedef CGAL::Surface_mesh Mesh; @@ -25,39 +26,50 @@ int main(int argc, char** argv) { { std::cout << "Reading from stream\n"; - Mesh m; CGAL::Real_timer timer; timer.start(); - std::ifstream in((argc>1) ? argv[1] : "data/genus3.off"); - in >> m; - timer.stop(); + + Mesh m; + const char* filename = (argc>1) ? argv[1] : "data/genus3.off"; + CGAL::read_polygon_mesh(filename, m); + std::cout << " is_valid? " << CGAL::is_valid_polygon_mesh(m) << "\n"; std::cout << "Total time: " << timer.time() << std::endl << std::endl; } + //////////////////////////////// + { std::cout << "Reading from soup + iterative add_face\n"; - Mesh m; + CGAL::Real_timer timer; timer.start(); - std::ifstream in((argc>1) ? argv[1] : "data/blobby.off"); + + const char* filename = (argc>1) ? argv[1] : "data/blobby.off"; std::vector points; std::vector > faces_ids; - std::vector > triangles; - CGAL::read_OFF(in, points, faces_ids); - convert_to_vertex_triples(faces_ids, triangles); + CGAL::read_polygon_soup(filename, points, faces_ids); std::cout << " Read soup: " << timer.time() << std::endl; + + std::vector > triangles; + convert_to_vertex_triples(faces_ids, triangles); + + Mesh m; m.reserve(static_cast(points.size()), static_cast(3*triangles.size()/2), static_cast(triangles.size())); for (const Kernel::Point_3& pt : points) m.add_vertex(pt); + CGAL::Real_timer subtimer; subtimer.start(); + for (const std::array& t : triangles) CGAL::Euler::add_face(t, m); + subtimer.stop(); timer.stop(); + std::cout << " is_valid? " << CGAL::is_valid_polygon_mesh(m) << "\n"; std::cout << " time for iterative add_face: " << subtimer.time() << std::endl; std::cout << "Total time: " << timer.time() << std::endl << std::endl; @@ -65,26 +77,35 @@ int main(int argc, char** argv) //////////////////////////////// { std::cout << "Reading from soup + add_faces\n"; - Mesh m; + CGAL::Real_timer timer; timer.start(); - std::ifstream in((argc>1) ? argv[1] : "data/blobby.off"); + + const char* filename = (argc>1) ? argv[1] : "data/blobby.off"; + std::vector points; std::vector > faces_ids; - std::vector > triangles; - CGAL::read_OFF(in, points, faces_ids); - convert_to_vertex_triples(faces_ids, triangles); + CGAL::read_polygon_soup(filename, points, faces_ids); std::cout << " Read soup: " << timer.time() << std::endl; + + std::vector > triangles; + convert_to_vertex_triples(faces_ids, triangles); + + Mesh m; m.reserve(static_cast(points.size()), static_cast(3*triangles.size()/2), static_cast(triangles.size())); for (const Kernel::Point_3& pt : points) m.add_vertex(pt); + CGAL::Real_timer subtimer; subtimer.start(); + CGAL::Euler::add_faces(triangles, m); + subtimer.stop(); timer.stop(); + std::cout << " is_valid? " << CGAL::is_valid_polygon_mesh(m) << "\n"; std::cout << " time for add_faces: " << subtimer.time() << std::endl; std::cout << "Total time: " << timer.time() << std::endl; diff --git a/BGL/test/BGL/test_bgl_read_write.cpp b/BGL/test/BGL/test_bgl_read_write.cpp index bd92cd63df0..a20d8bbcf37 100644 --- a/BGL/test/BGL/test_bgl_read_write.cpp +++ b/BGL/test/BGL/test_bgl_read_write.cpp @@ -350,7 +350,7 @@ void test_bgl_OFF(const char* filename) //@todo test multi objects in a single file // test wrong inputs - std::cerr<<"Error text is expected to follow."< @@ -398,10 +398,8 @@ void test_bgl_OBJ(const std::string filename) assert(ok); assert(are_equal_meshes(fg, fg2)); } - // Test NPs - typedef typename K::Vector_3 Vector; - typedef typename boost::property_map >::type VertexNormalMap; + // Test NPs CGAL::clear(fg); ok = CGAL::read_OBJ("data/sphere.obj", fg); assert(ok); @@ -432,7 +430,7 @@ void test_bgl_OBJ(const std::string filename) } // test wrong inputs - std::cerr<<"Error text is expected to follow."< @@ -606,8 +604,6 @@ void test_bgl_STL(const std::string filename) assert(filename != "data/pig.stl" || (num_vertices(fg) == 8642 && num_faces(fg) == 16848)); assert(filename != "data/pig.stl" || cpoints.size() == 8642); - - // write with STL { std::ofstream os("tmp.stl"); @@ -631,7 +627,7 @@ void test_bgl_STL(const std::string filename) assert(num_vertices(fg) == num_vertices(fg2) && num_faces(fg) == num_faces(fg2)); } - std::cerr<<"Error text is expected to follow."< @@ -678,7 +674,7 @@ void test_bgl_GOCAD(const char* filename) // write with PM { - ok = CGAL::write_polygon_mesh("tmp.ts", fg); + ok = CGAL::write_polygon_mesh("tmp.ts", fg, CGAL::parameters::stream_precision(10)); assert(ok); Mesh fg2; @@ -708,8 +704,7 @@ void test_bgl_GOCAD(const char* filename) assert(num_faces(fg2) == 24191); } - - std::cerr<<"Error text is expected to follow."< -#include #include + #include + #include #include - typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Polyhedron_3 Polyhedron_3; -typedef K::Point_3 Point_3; -typedef CGAL::Surface_mesh Surface_mesh; - +typedef K::Point_3 Point_3; +typedef CGAL::Surface_mesh Surface_mesh; int main(int argc, char* argv[]) { - std::ifstream in( (argc>1)? argv[1] : "data/cross.off"); + const char* filename = (argc>1)? argv[1] : "data/cross.off"; Surface_mesh poly; - if(!in || !(in >> poly)) + if(!CGAL::read_polygon_mesh(filename, poly)) { std::cerr<<"Could not find a correct input file."< #include - -#include -#include -#include +#include #include #include @@ -24,51 +21,15 @@ typedef K::Point_3 Point_3; typedef CGAL::Surface_mesh Surface_mesh; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; -template -bool read_mesh(const std::string filename, - std::vector& points) -{ - std::ifstream in(filename.c_str()); - if(!in.good()) - { -// std::cerr << "Error: can't read file at " << filename << std::endl; - return false; - } - - std::vector > unused_faces; - - std::string fn(filename); - if(fn.substr(fn.find_last_of(".") + 1) == "stl") - { - if(!CGAL::read_STL(in, points, unused_faces)) - return false; - } - else if(fn.substr(fn.find_last_of(".") + 1) == "obj") - { - if(!CGAL::read_OBJ(in, points, unused_faces)) - return false; - } - else if(fn.substr(fn.find_last_of(".") + 1) == "off") - { - if(!CGAL::read_OFF(in, points, unused_faces)) - return false; - } - else - { -// std::cerr << "Error: unsupported file format: " << filename << std::endl; - return false; - } - - return true; -} - void bench_finding_obb(const std::string filename, const int iter) { CGAL::Timer timer; std::vector points; - read_mesh(filename, points); + std::vector > unused_faces; + + CGAL::read_polygon_soup(filename, points, unused_faces); std::vector ch_points; std::array obb_points1; diff --git a/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/oriented_bounding_box.h b/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/oriented_bounding_box.h index 99f8be9cc7e..66898c64a4b 100644 --- a/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/oriented_bounding_box.h +++ b/Optimal_bounding_box/include/CGAL/Optimal_bounding_box/oriented_bounding_box.h @@ -432,8 +432,6 @@ void oriented_bounding_box(const PolygonMesh& pmesh, #endif ) { - namespace PMP = CGAL::Polygon_mesh_processing; - using CGAL::parameters::choose_parameter; using CGAL::parameters::get_parameter; diff --git a/Point_set_3/include/CGAL/Point_set_3/IO/PLY.h b/Point_set_3/include/CGAL/Point_set_3/IO/PLY.h index f28354ef34c..a4fc334138f 100644 --- a/Point_set_3/include/CGAL/Point_set_3/IO/PLY.h +++ b/Point_set_3/include/CGAL/Point_set_3/IO/PLY.h @@ -344,7 +344,7 @@ bool read_PLY(std::istream& is, CGAL::Point_set_3& point_set) template bool read_PLY(const char* fname, CGAL::Point_set_3& point_set, - const std::string& comments, + std::string& comments, const CGAL_BGL_NP_CLASS& np) { const bool binary = CGAL::parameters::choose_parameter(CGAL::parameters::get_parameter(np, internal_np::use_binary_mode), true); @@ -363,7 +363,7 @@ bool read_PLY(const char* fname, } template -bool read_PLY(const char* fname, CGAL::Point_set_3& point_set, const std::string& comments) +bool read_PLY(const char* fname, CGAL::Point_set_3& point_set, std::string& comments) { return read_PLY(fname, point_set, comments, parameters::all_default()); } @@ -371,17 +371,19 @@ bool read_PLY(const char* fname, CGAL::Point_set_3& point_set, co template bool read_PLY(const char* fname, CGAL::Point_set_3& point_set, const CGAL_BGL_NP_CLASS& np) { - return read_PLY(fname, point_set, std::string(), np); + std::string unused_comments; + return read_PLY(fname, point_set, unused_comments, np); } template bool read_PLY(const char* fname, CGAL::Point_set_3& point_set) { - return read_PLY(fname, point_set, std::string(), parameters::all_default()); + std::string unused_comments; + return read_PLY(fname, point_set, unused_comments, parameters::all_default()); } template -bool read_PLY(const std::string& fname, CGAL::Point_set_3& point_set, const std::string& comments) +bool read_PLY(const std::string& fname, CGAL::Point_set_3& point_set, std::string& comments) { return read_PLY(fname.c_str(), point_set, comments, parameters::all_default()); } @@ -389,13 +391,15 @@ bool read_PLY(const std::string& fname, CGAL::Point_set_3& point_ template bool read_PLY(const std::string& fname, CGAL::Point_set_3& point_set, const CGAL_BGL_NP_CLASS& np) { - return read_PLY(fname.c_str(), point_set, std::string(), np); + std::string unused_comments; + return read_PLY(fname.c_str(), point_set, unused_comments, np); } template bool read_PLY(const std::string& fname, CGAL::Point_set_3& point_set) { - return read_PLY(fname.c_str(), point_set, std::string(), parameters::all_default()); + std::string unused_comments; + return read_PLY(fname.c_str(), point_set, unused_comments, parameters::all_default()); } #ifndef CGAL_NO_DEPRECATED_CODE diff --git a/Point_set_processing_3/test/Point_set_processing_3/test_read_write_point_set.cpp b/Point_set_processing_3/test/Point_set_processing_3/test_read_write_point_set.cpp index b25f9807fcc..d0d150980fb 100644 --- a/Point_set_processing_3/test/Point_set_processing_3/test_read_write_point_set.cpp +++ b/Point_set_processing_3/test/Point_set_processing_3/test_read_write_point_set.cpp @@ -3,7 +3,10 @@ #include #include #include -#include // Just to try and create ambiguities + +// Just to try and create ambiguities +#include +#include #include diff --git a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h index 2b23c5db8b2..62958206773 100644 --- a/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h +++ b/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/repair_degeneracies.h @@ -27,7 +27,7 @@ #ifdef CGAL_PMP_REMOVE_DEGENERATE_FACES_DEBUG #include -#include +#include #endif #include diff --git a/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space.cpp b/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space.cpp index e91f6f8787a..be02efbc6a2 100644 --- a/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space.cpp +++ b/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space.cpp @@ -16,15 +16,16 @@ typedef Reconstruction::Facet_const_iterator Facet_iterator; int main(int argc, char** argv) { - if (argc!=2){ + if (argc != 2) + { std::cerr << "Error, no input file provided\n"; return 1; } - // Read the data. - std::vector points; - std::ifstream in(argv[1]); + std::cerr << "Reading " << std::flush; - if( !in || !CGAL::read_points( in, std::back_inserter( points ) ) ) { + std::vector points; + if(!CGAL::read_points(argv[1], std::back_inserter(points))) + { std::cerr << "Error: cannot read file" << std::endl; return EXIT_FAILURE; } @@ -33,6 +34,7 @@ int main(int argc, char** argv) std::cerr << "Reconstruction "; CGAL::Timer t; t.start(); + // Construct the mesh in a scale space. Reconstruction reconstruct (points.begin(), points.end()); reconstruct.increase_scale(4); diff --git a/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space_advancing_front.cpp b/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space_advancing_front.cpp index 4d8438ee965..23a392617a0 100644 --- a/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space_advancing_front.cpp +++ b/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space_advancing_front.cpp @@ -23,17 +23,16 @@ typedef Reconstruction::Facet_const_iterator Facet_iterator; int main(int argc, char** argv) { - if (argc!=2){ + if (argc != 2) + { std::cerr << "Error, no input file provided\n"; return 1; } - // Read the data. - Point_set points; - std::ifstream in(argv[1]); - std::cerr << "Reading " << std::flush; - in >> points; - if (points.empty()) + // Read the data. + std::cerr << "Reading " << std::flush; + Point_set points; + if(!CGAL::read_point_set(argv[1], points)) { std::cerr << "Error: cannot read file" << std::endl; return EXIT_FAILURE; diff --git a/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space_incremental.cpp b/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space_incremental.cpp index 964eb5ae1a0..0adee0d8fda 100644 --- a/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space_incremental.cpp +++ b/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space_incremental.cpp @@ -32,16 +32,15 @@ void dump_reconstruction(const Reconstruction& reconstruct, std::string name) int main(int argc, char* argv[]) { - // Read the data. - std::vector points; - if (argc!=2){ + if (argc != 2) + { std::cerr << "Error, no input file provided\n"; return 1; } - std::ifstream in(argv[1]); std::cout << "Reading " << std::flush; - if( !in || !CGAL::read_points(in, std::back_inserter(points))) + std::vector points; + if(!CGAL::read_points(argv[1], std::back_inserter(points))) { std::cerr << "Error: cannot read file" << std::endl; return EXIT_FAILURE; diff --git a/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space_manifold.cpp b/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space_manifold.cpp index 0a1f223af6f..cfa6f39723c 100644 --- a/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space_manifold.cpp +++ b/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space_manifold.cpp @@ -28,11 +28,9 @@ int main(int argc, char* argv[]) return 1; } - // Read the data. - std::vector points; - std::ifstream in(argv[1]); std::cerr << "Reading " << std::flush; - if(!in || !CGAL::read_points(in, std::back_inserter(points))) + std::vector points; + if(!CGAL::read_points(argv[1], std::back_inserter(points))) { std::cerr << "Error: cannot read file" << std::endl; return EXIT_FAILURE; @@ -42,6 +40,7 @@ int main(int argc, char* argv[]) Timer t; t.start(); + // Construct the mesh in a scale space. Reconstruction reconstruct(points.begin(), points.end() ); Smoother smoother(10, 200 ); diff --git a/Stream_support/include/CGAL/IO/OBJ.h b/Stream_support/include/CGAL/IO/OBJ.h index 00e52b32555..913a55d64f7 100644 --- a/Stream_support/include/CGAL/IO/OBJ.h +++ b/Stream_support/include/CGAL/IO/OBJ.h @@ -75,7 +75,7 @@ bool read_OBJ(std::istream& is, { if(!first_o) { - if(maxi == offset_idx -1 && mini == offset_idx + 1) + if(maxi == static_cast(offset_idx -1 ) && mini == static_cast(offset_idx + 1)) { if(verbose) std::cerr << "No face detected." << std::endl; @@ -158,7 +158,7 @@ bool read_OBJ(std::istream& is, std::cout<<"WARNING: normals were found in this file, but were discarded."<(offset_idx - 1) && mini == static_cast(offset_idx + 1)) { if(verbose) std::cerr << "No face detected." << std::endl; diff --git a/Stream_support/include/CGAL/IO/OFF/File_scanner_OFF.h b/Stream_support/include/CGAL/IO/OFF/File_scanner_OFF.h index 1a4916a2edb..f5c452e20b3 100644 --- a/Stream_support/include/CGAL/IO/OFF/File_scanner_OFF.h +++ b/Stream_support/include/CGAL/IO/OFF/File_scanner_OFF.h @@ -347,6 +347,7 @@ public: void scan_texture(float& x, float& y, float& w) { + w = 1; if(has_textures()) { if(binary()) @@ -946,10 +947,7 @@ public: //if the value is of float type, convert it into an int if(is_float) - { - const char* s = color_info.c_str(); rgb[index] = static_cast(atof(color_info.c_str())*255); - } //else stores the value else diff --git a/Stream_support/include/CGAL/IO/helpers.h b/Stream_support/include/CGAL/IO/helpers.h index 0f4f09ddec1..f261337bacd 100644 --- a/Stream_support/include/CGAL/IO/helpers.h +++ b/Stream_support/include/CGAL/IO/helpers.h @@ -44,7 +44,7 @@ void fill_point(const double x, const double y, const double z, const double w, //////////////////////////////////////////////////////////////////////////////////////////////////// -static std::string get_file_extension(const std::string fname) +static inline std::string get_file_extension(const std::string fname) { std::string::size_type dot(fname.rfind(".")); if(dot == std::string::npos) diff --git a/Surface_mesh/test/Surface_mesh/SM_common.h b/Surface_mesh/test/Surface_mesh/SM_common.h index 0e28add7563..1dc68f0094d 100644 --- a/Surface_mesh/test/Surface_mesh/SM_common.h +++ b/Surface_mesh/test/Surface_mesh/SM_common.h @@ -117,7 +117,7 @@ struct Surface_fixture_3 { struct Cube_fixture { - Cube_fixture() { CGAL::read_polygon_mesh(m, "cube.off"); } + Cube_fixture() { CGAL::read_polygon_mesh("cube.off", m); } Sm m; diff --git a/Surface_mesh_topology/examples/Surface_mesh_topology/edgewidth_surface_mesh.cpp b/Surface_mesh_topology/examples/Surface_mesh_topology/edgewidth_surface_mesh.cpp index 6c5626c6cce..a78ffce8e4f 100644 --- a/Surface_mesh_topology/examples/Surface_mesh_topology/edgewidth_surface_mesh.cpp +++ b/Surface_mesh_topology/examples/Surface_mesh_topology/edgewidth_surface_mesh.cpp @@ -1,13 +1,15 @@ #include #include -#include + #include #include #include #include -using Mesh =CGAL::Surface_mesh::Point_3>; -using Path_on_surface=CGAL::Surface_mesh_topology::Path_on_surface; +#include + +using Mesh = CGAL::Surface_mesh::Point_3>; +using Path_on_surface = CGAL::Surface_mesh_topology::Path_on_surface; double cycle_length(const Mesh& mesh, const Path_on_surface& cycle) { // Compute the length of the given cycle. @@ -31,14 +33,13 @@ int main(int argc, char* argv[]) { std::string filename(argc==1?"data/3torus.off":argv[1]); bool draw=(argc<3?false:(std::string(argv[2])=="-draw")); - std::ifstream inp(filename); - if (inp.fail()) + + Mesh sm; + if(!CGAL::read_polygon_mesh(filename, sm)) { std::cout<<"Cannot read file '"<>sm; std::cout<<"File '"< cst(sm, true); diff --git a/Surface_mesh_topology/examples/Surface_mesh_topology/path_homotopy_with_sm_and_polyhedron.cpp b/Surface_mesh_topology/examples/Surface_mesh_topology/path_homotopy_with_sm_and_polyhedron.cpp index 2e62fde7600..aaba6843a74 100644 --- a/Surface_mesh_topology/examples/Surface_mesh_topology/path_homotopy_with_sm_and_polyhedron.cpp +++ b/Surface_mesh_topology/examples/Surface_mesh_topology/path_homotopy_with_sm_and_polyhedron.cpp @@ -1,7 +1,9 @@ +#include #include #include #include +#include #include #include #include @@ -40,13 +42,13 @@ void test(const FaceGraph& mesh, bool draw, const char* title) /////////////////////////////////////////////////////////////////////////////// int main(int argc, char** argv) { - std::string file=(argc==1?"data/elephant.off":argv[1]); - bool draw=(argc>2?std::string(argv[2])=="-draw":false); + const char* file = (argc == 1) ? "data/elephant.off" : argv[1]; + bool draw = (argc>2) ? std::string(argv[2])=="-draw" : false; seed=static_cast(CGAL::get_default_random().get_int(0,INT_MAX)); { LCC_3_cmap lcc; - if (!CGAL::read_polygon_mesh(file, lcc)) + if (!CGAL::load_off(lcc, file)) { std::cout<<"ERROR reading file "<