// Copyright (c) 1997 // Utrecht University (The Netherlands), // ETH Zurich (Switzerland), // INRIA Sophia-Antipolis (France), // Max-Planck-Institute Saarbruecken (Germany), // and Tel-Aviv University (Israel). All rights reserved. // // This file is part of CGAL (www.cgal.org); you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 3 of the License, // or (at your option) any later version. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // // // Author(s) : Lutz Kettner #ifndef CGAL_IO_FILE_SCANNER_OFF_H #define CGAL_IO_FILE_SCANNER_OFF_H 1 #include #include #include #include #include #include #include #include namespace CGAL { class CGAL_EXPORT File_scanner_OFF : public File_header_OFF { std::istream& m_in; bool normals_read; void skip_comment() { m_in >> skip_comment_OFF; } public: File_scanner_OFF( std::istream& in, bool verbose = false) : File_header_OFF(verbose), m_in(in), normals_read(false) { in >> static_cast( *this); } File_scanner_OFF( std::istream& in, const File_header_OFF& header) : File_header_OFF(header), m_in(in), normals_read(false) {} std::istream& in() { return m_in; } // The scan_vertex() routine is provided for multiple // coordinate types to support parameterized polytopes. void scan_vertex( float& x, float& y, float& z) { if ( binary()) { I_Binary_read_big_endian_float32( m_in, x); I_Binary_read_big_endian_float32( m_in, y); I_Binary_read_big_endian_float32( m_in, z); if ( is_homogeneous()) { float w; I_Binary_read_big_endian_float32( m_in, w); x /= w; y /= w; z /= w; } } else { skip_comment(); m_in >> x >> y >> z; if ( is_homogeneous()) { float w; m_in >> w; x /= w; y /= w; z /= w; } } } void scan_vertex( double& x, double& y, double& z) { if ( binary()) { float f; I_Binary_read_big_endian_float32( m_in, f); x = f; I_Binary_read_big_endian_float32( m_in, f); y = f; I_Binary_read_big_endian_float32( m_in, f); z = f; if ( is_homogeneous()) { I_Binary_read_big_endian_float32( m_in, f); x /= f; y /= f; z /= f; } } else { skip_comment(); m_in >> x >> y >> z; if ( is_homogeneous()) { double w; m_in >> w; x /= w; y /= w; z /= w; } } } void scan_vertex( int& x, int& y, int& z) { if ( binary()) { float fx, fy, fz; I_Binary_read_big_endian_float32( m_in, fx); I_Binary_read_big_endian_float32( m_in, fy); I_Binary_read_big_endian_float32( m_in, fz); if ( is_homogeneous()) { float fw; I_Binary_read_big_endian_float32( m_in, fw); x = int( fx / fw); y = int( fy / fw); z = int( fz / fw); } else { x = int(fx); y = int(fy); z = int(fz); } } else { skip_comment(); if ( is_homogeneous()) { double fx, fy, fz, fw; m_in >> fx >> fy >> fz >> fw; x = int( fx / fw); y = int( fy / fw); z = int( fz / fw); } else { double d; m_in >> d; x = int(d); m_in >> d; y = int(d); m_in >> d; z = int(d); } } } void scan_vertex( float& x, float& y, float& z, float& w) { w = 1; if ( binary()) { I_Binary_read_big_endian_float32( m_in, x); I_Binary_read_big_endian_float32( m_in, y); I_Binary_read_big_endian_float32( m_in, z); if ( is_homogeneous()) I_Binary_read_big_endian_float32( m_in, w); } else { skip_comment(); m_in >> x >> y >> z; if ( is_homogeneous()) m_in >> w; } } void scan_vertex( double& x, double& y, double& z, double& w) { w = 1; if ( binary()) { float f; I_Binary_read_big_endian_float32( m_in, f); x = f; I_Binary_read_big_endian_float32( m_in, f); y = f; I_Binary_read_big_endian_float32( m_in, f); z = f; if ( is_homogeneous()) { I_Binary_read_big_endian_float32( m_in, f); w = f; } } else { skip_comment(); m_in >> x >> y >> z; if ( is_homogeneous()) m_in >> w; } } void scan_vertex( int& x, int& y, int& z, int& w) { w = 1; if ( binary()) { float f; I_Binary_read_big_endian_float32( m_in, f); x = int(f); I_Binary_read_big_endian_float32( m_in, f); y = int(f); I_Binary_read_big_endian_float32( m_in, f); z = int(f); if ( is_homogeneous()) { I_Binary_read_big_endian_float32( m_in, f); w = int(f); } } else { skip_comment(); double d; m_in >> d; x = int(d); m_in >> d; y = int(d); m_in >> d; z = int(d); if ( is_homogeneous()) { m_in >> d; w = int(d); } } } void scan_normal( float& x, float& y, float& z) { if ( has_normals()) { normals_read = true; if ( binary()) { I_Binary_read_big_endian_float32( m_in, x); I_Binary_read_big_endian_float32( m_in, y); I_Binary_read_big_endian_float32( m_in, z); if ( is_homogeneous()) { float w; I_Binary_read_big_endian_float32( m_in, w); x /= w; y /= w; z /= w; } } else { m_in >> x >> y >> z; if ( is_homogeneous()) { float w; m_in >> w; x /= w; y /= w; z /= w; } } } } void scan_normal( double& x, double& y, double& z) { if ( has_normals()) { normals_read = true; if ( binary()) { float fx, fy, fz; I_Binary_read_big_endian_float32( m_in, fx); I_Binary_read_big_endian_float32( m_in, fy); I_Binary_read_big_endian_float32( m_in, fz); if ( is_homogeneous()) { float fw; I_Binary_read_big_endian_float32( m_in, fw); x = fx / fw; y = fy / fw; z = fz / fw; } else { x = fx; y = fy; z = fz; } } else { if ( is_homogeneous()) { float fx, fy, fz, fw; m_in >> fx >> fy >> fz >> fw; x = fx / fw; y = fy / fw; z = fz / fw; } else m_in >> x >> y >> z; } } } void scan_normal( int& x, int& y, int& z) { if ( has_normals()) { normals_read = true; if ( binary()) { float fx, fy, fz; I_Binary_read_big_endian_float32( m_in, fx); I_Binary_read_big_endian_float32( m_in, fy); I_Binary_read_big_endian_float32( m_in, fz); if ( is_homogeneous()) { float fw; I_Binary_read_big_endian_float32( m_in, fw); x = int( fx / fw); y = int( fy / fw); z = int( fz / fw); } else { x = int(fx); y = int(fy); z = int(fz); } } else { if ( is_homogeneous()) { float fx, fy, fz, fw; m_in >> fx >> fy >> fz >> fw; x = int( fx / fw); y = int( fy / fw); z = int( fz / fw); } else { double d; m_in >> d; x = int(d); m_in >> d; y = int(d); m_in >> d; z = int(d); } } } } void scan_normal( float& x, float& y, float& z, float& w) { w = 1; if ( has_normals()) { normals_read = true; if ( binary()) { I_Binary_read_big_endian_float32( m_in, x); I_Binary_read_big_endian_float32( m_in, y); I_Binary_read_big_endian_float32( m_in, z); if ( is_homogeneous()) I_Binary_read_big_endian_float32( m_in, w); } else { m_in >> x >> y >> z; if ( is_homogeneous()) m_in >> w; } } } void scan_normal( double& x, double& y, double& z, double& w) { w = 1; if ( has_normals()) { normals_read = true; if ( binary()) { float f; I_Binary_read_big_endian_float32( m_in, f); x = f; I_Binary_read_big_endian_float32( m_in, f); y = f; I_Binary_read_big_endian_float32( m_in, f); z = f; if ( is_homogeneous()) { I_Binary_read_big_endian_float32( m_in, f); w = f; } } else { m_in >> x >> y >> z; if ( is_homogeneous()) m_in >> w; } } } void scan_normal( int& x, int& y, int& z, int& w) { w = 1; if ( has_normals()) { normals_read = true; if ( binary()) { float f; I_Binary_read_big_endian_float32( m_in, f); x = int(f); I_Binary_read_big_endian_float32( m_in, f); y = int(f); I_Binary_read_big_endian_float32( m_in, f); z = int(f); if ( is_homogeneous()) { I_Binary_read_big_endian_float32( m_in, f); w = int(f); } } else { double d; m_in >> d; x = int(d); m_in >> d; y = int(d); m_in >> d; z = int(d); if ( is_homogeneous()) { m_in >> d; w = int(d); } } } } void skip_to_next_vertex( std::size_t current_vertex); void scan_facet( std::size_t& size, std::size_t CGAL_assertion_code(current_facet)) { CGAL_assertion( current_facet < size_of_facets()); if ( binary()){ boost::int32_t i32; I_Binary_read_big_endian_integer32( m_in, i32); size = i32; } else { skip_comment(); m_in >> size; } } void scan_facet_vertex_index( std::size_t& index, std::size_t current_facet) { if ( binary()){ boost::int32_t i32; I_Binary_read_big_endian_integer32( m_in, i32); index = i32; } else m_in >> index; if( m_in.fail()) { if ( verbose()) { std::cerr << " " << std::endl; std::cerr << "File_scanner_OFF::" << std::endl; std::cerr << "scan_facet_vertex_index(): input error: " "cannot read OFF file beyond facet " << current_facet << "." << std::endl; } set_off_header( false); return; } bool error = index < index_offset(); index -= index_offset(); if(error || (index >= size_of_vertices())) { m_in.clear( std::ios::failbit); if ( verbose()) { std::cerr << " " << std::endl; std::cerr << "File_scanner_OFF::" << std::endl; std::cerr << "scan_facet_vertex_index(): input error: " "facet " << current_facet << ": vertex index " << index + index_offset() << ": is out of range." << std::endl; } set_off_header( false); return; } } void skip_to_next_facet( std::size_t current_facet); }; template < class Point> inline Point& file_scan_vertex( File_scanner_OFF& scanner, Point& p) { typedef typename Point::R R; typedef typename R::RT RT; double x, y, z, w; scanner.scan_vertex( x, y, z, w); if ( w == 1) p = Point( RT(x), RT(y), RT(z)); else p = Point( RT(x), RT(y), RT(z), RT(w)); return p; } template < class Vector> inline Vector& file_scan_normal( File_scanner_OFF& scanner, Vector& v) { typedef typename Vector::R R; typedef typename R::RT RT; double x, y, z, w; scanner.scan_normal( x, y, z, w); if ( w == 1) v = Vector( RT(x), RT(y), RT(z)); else v = Vector( RT(x), RT(y), RT(z), RT(w)); return v; } } //namespace CGAL #endif // CGAL_IO_FILE_SCANNER_OFF_H // // EOF //