// Copyright (c) 1997,2005 // 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$ // SPDX-License-Identifier: LGPL-3.0+ // // // Author(s) : Lutz Kettner // Ralf Osbild #ifndef CGAL_IO_SCANNER_OFF_H #define CGAL_IO_SCANNER_OFF_H 1 #include #include #include #include #include #include namespace CGAL { // The Facet_iterator's value type is vector // that contains the vertex indices. template class I_Scanner_OFF_vertex_iterator { public: typedef std::input_iterator_tag iterator_category; typedef Pt value_type; typedef std::ptrdiff_t difference_type; typedef const Pt* pointer; typedef const Pt& reference; private: File_scanner_OFF* m_scan; std::size_t m_cnt; Pt m_point; void next_vertex() { CGAL_assertion( m_scan != NULL); if ( m_cnt < m_scan->size_of_vertices()) { file_scan_vertex( *m_scan, m_point); m_scan->skip_to_next_vertex( m_cnt); ++m_cnt; } else m_cnt = m_scan->size_of_vertices() + 1; } public: typedef Pt Point; typedef File_scanner_OFF Scanner; typedef I_Scanner_OFF_vertex_iterator Self; I_Scanner_OFF_vertex_iterator(std::size_t cnt) : m_scan(0), m_cnt(cnt+1) {} I_Scanner_OFF_vertex_iterator( Scanner& s, int cnt) : m_scan(&s), m_cnt(cnt) { next_vertex(); } std::size_t count() const { return m_cnt; } bool operator==( const Self& i) const { return m_cnt == i.m_cnt; } bool operator!=( const Self& i) const { return m_cnt != i.m_cnt; } Self& operator++() { next_vertex(); return *this; } Self operator++(int) { Self tmp = *this; ++(*this); return tmp; } const Point& operator*() const { CGAL_assertion( m_scan != NULL); return m_point; } const Point* operator->() const { return & operator*(); } }; template class I_Scanner_OFF_vertex_and_normals_iterator { public: typedef Pt Point; typedef Nrm Normal; typedef File_scanner_OFF Scanner; typedef I_Scanner_OFF_vertex_and_normals_iterator Self; typedef std::input_iterator_tag iterator_category; typedef std::pair value_type; typedef std::ptrdiff_t difference_type; typedef const value_type* pointer; typedef const value_type& reference; private: File_scanner_OFF* m_scan; std::size_t m_cnt; value_type m_current; void next() { CGAL_assertion( m_scan != NULL); if ( m_cnt < m_scan->size_of_vertices()) { file_scan_vertex( *m_scan, m_current.first); if ( m_scan->has_normals()) file_scan_normal( *m_scan, m_current.second); m_scan->skip_to_next_vertex( m_cnt); ++m_cnt; } else m_cnt = m_scan->size_of_vertices() + 1; } public: I_Scanner_OFF_vertex_and_normals_iterator( int cnt) : m_scan(0), m_cnt(cnt+1) {} I_Scanner_OFF_vertex_and_normals_iterator( Scanner& s, int cnt) : m_scan(&s), m_cnt(cnt) { next(); } std::size_t count() const { return m_cnt; } bool operator==( const Self& i) const { return m_cnt == i.m_cnt; } bool operator!=( const Self& i) const { return m_cnt != i.m_cnt; } Self& operator++() { next(); return *this; } Self operator++(int) { Self tmp = *this; ++(*this); return tmp; } reference operator*() const { CGAL_assertion( m_scan != NULL); return m_current; } pointer operator->() const { return & operator*(); } }; class I_Scanner_OFF_facet_iterator { public: typedef std::input_iterator_tag iterator_category; typedef std::vector value_type; typedef std::ptrdiff_t difference_type; typedef value_type* pointer; typedef value_type& reference; private: File_scanner_OFF* m_scan; std::size_t m_cnt; value_type m_indices; void next_facet() { CGAL_assertion( m_scan != NULL); if ( m_cnt < m_scan->size_of_facets()) { m_indices.erase( m_indices.begin(), m_indices.end()); std::size_t no; m_scan->scan_facet( no, m_cnt); m_indices.reserve( no); std::size_t index = (std::numeric_limits::max)(); // A huge value helps to detect a potential // error in the function scan_facet_vertex_index for (std::size_t i = 0; i < no; ++i) { m_scan->scan_facet_vertex_index( index, m_cnt); m_indices.push_back( index); } m_scan->skip_to_next_facet( m_cnt); ++ m_cnt; } else m_cnt = m_scan->size_of_facets() + 1; } public: value_type::size_type size_of_indices () const // RO { return m_indices.size(); } typedef value_type::size_type indices_size_type; // RO public: typedef File_scanner_OFF Scanner; typedef I_Scanner_OFF_facet_iterator Self; typedef value_type::iterator iterator; I_Scanner_OFF_facet_iterator( std::size_t cnt) : m_scan(0), m_cnt(cnt+1) {} I_Scanner_OFF_facet_iterator( Scanner& s, std::size_t cnt) : m_scan(&s), m_cnt(cnt) { next_facet(); } std::size_t count() const { return m_cnt; } bool operator==( const Self& i) const { return m_cnt == i.m_cnt; } bool operator!=( const Self& i) const { return m_cnt != i.m_cnt; } Self& operator++() { next_facet(); return *this; } Self operator++(int) { Self tmp = *this; ++(*this); return tmp; } value_type& operator*() { CGAL_assertion( m_scan != NULL); return m_indices; } const value_type& operator*() const { CGAL_assertion( m_scan != NULL); return m_indices; } value_type* operator->() { return & operator*(); } const value_type* operator->() const { return & operator*(); } }; // The distance function is implemented to work in // constant time for both iterators. template inline void distance( const I_Scanner_OFF_vertex_iterator& first, const I_Scanner_OFF_vertex_iterator& last, Distance& n) { n = Distance( last.count() - first.count()); } template inline void distance( const I_Scanner_OFF_facet_iterator& first, const I_Scanner_OFF_facet_iterator& last, Distance& n) { n = Distance( last.count() - first.count()); } template inline std::ptrdiff_t distance( const I_Scanner_OFF_vertex_iterator& first, const I_Scanner_OFF_vertex_iterator& last) { return last.count() - first.count(); } inline std::ptrdiff_t distance( const I_Scanner_OFF_facet_iterator& first, const I_Scanner_OFF_facet_iterator& last) { return last.count() - first.count(); } template class Scanner_OFF { File_scanner_OFF m_scan; public: typedef typename Kernel::Point_3 Point; typedef Point Pt; typedef typename Kernel::Vector_3 Normal; typedef Scanner_OFF Self; typedef I_Scanner_OFF_vertex_iterator Vertex_iterator; typedef I_Scanner_OFF_vertex_and_normals_iterator Vertex_and_normals_iterator; typedef I_Scanner_OFF_facet_iterator Facet_iterator; typedef I_Scanner_OFF_facet_iterator::iterator Index_iterator; Scanner_OFF( std::istream& in, bool verbose = false) : m_scan( in, verbose) {} Scanner_OFF( std::istream& in, const File_header_OFF& header) : m_scan( in, header) {} std::size_t size_of_vertices() const { return m_scan.size_of_vertices(); } std::size_t size_of_halfedges() const { return m_scan.size_of_halfedges();} std::size_t size_of_facets() const { return m_scan.size_of_facets(); } bool verbose() const { return m_scan.verbose(); } bool skel() const { return m_scan.skel(); } bool off() const { return m_scan.off(); } bool binary() const { return m_scan.binary(); } bool ascii() const { return m_scan.ascii(); } bool has_colors() const { return m_scan.has_colors(); } bool has_normals() const { return m_scan.has_normals(); } File_header_OFF& header() { return m_scan; } const File_header_OFF& header() const { return m_scan; } Vertex_iterator vertices_begin(){ return Vertex_iterator( m_scan,0);} Vertex_iterator vertices_end() { return Vertex_iterator( size_of_vertices()); } Facet_iterator facets_begin() { return Facet_iterator( m_scan,0); } Facet_iterator facets_end() { return Facet_iterator( size_of_facets()); } Vertex_and_normals_iterator vertices_and_normals_begin(){ return Vertex_and_normals_iterator( m_scan,0); } Vertex_and_normals_iterator vertices_and_normals_end() { return Vertex_and_normals_iterator( size_of_vertices()); } }; } //namespace CGAL #endif // CGAL_IO_SCANNER_OFF_H // // EOF //