Merge pull request #4454 from maxGimeno/TDS-file_input-maxGimeno

Triangulation_3: Add a function to file_input() with a similar API to the advanced copy_tds()
This commit is contained in:
Sebastien Loriot 2020-04-08 16:09:36 +02:00 committed by GitHub
commit 2167d4ffef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 398 additions and 120 deletions

View File

@ -96,6 +96,16 @@ Release date: June 2020
does not allow any intersection, except for the configuration of two constraints having a single does not allow any intersection, except for the configuration of two constraints having a single
common endpoints, for convience. common endpoints, for convience.
### 3D Triangulations
- The free function `CGAL::file_input()` and the member function `CGAL::Triangulation_3::file_input()`
have been added. The first allows to load a `Triangulation_3` from an input stream, using functors to create vertices and cells.
The second is simply the member function version of the first one.
### 3D Triangulation Data Structure
- The free function `CGAL::file_input()` and the member function `CGAL::TDS_3::file_input()`
have been added. The first allows to load a `TDS_3` from an input stream, using functors to create vertices and cells.
The second is simply the member function version of the first one.
### dD Spatial Searching ### dD Spatial Searching
- Improved the performance of the kd-tree in some cases: - Improved the performance of the kd-tree in some cases:

View File

@ -406,6 +406,11 @@ struct Update_vertex
typedef typename Tr2::Vertex V2; typedef typename Tr2::Vertex V2;
typedef typename Tr2::Point Point; typedef typename Tr2::Point Point;
V2 operator()(const V1&)
{
return V2();
}
bool operator()(const V1& v1, V2& v2) bool operator()(const V1& v1, V2& v2)
{ {
v2.set_point(Point(v1.point())); v2.set_point(Point(v1.point()));
@ -418,7 +423,7 @@ struct Update_vertex
const Sp_index sp_index = boost::get<Sp_index>(index); const Sp_index sp_index = boost::get<Sp_index>(index);
v2.set_index((std::max)(sp_index.first, sp_index.second)); v2.set_index((std::max)(sp_index.first, sp_index.second));
} }
break; break;
default:// -1, 0, 1, 3 default:// -1, 0, 1, 3
v2.set_index(boost::get<int>(v1.index())); v2.set_index(boost::get<int>(v1.index()));
} }
@ -427,7 +432,9 @@ struct Update_vertex
}; // end struct Update_vertex }; // end struct Update_vertex
struct Update_cell { struct Update_cell {
typedef Fake_mesh_domain::Surface_patch_index Sp_index; typedef Fake_mesh_domain::Surface_patch_index Sp_index;
template <typename C1, typename C2> template <typename C1, typename C2>
bool operator()(const C1& c1, C2& c2) { bool operator()(const C1& c1, C2& c2) {
c2.set_subdomain_index(c1.subdomain_index()); c2.set_subdomain_index(c1.subdomain_index());
@ -442,7 +449,6 @@ struct Update_cell {
} }
}; // end struct Update_cell }; // end struct Update_cell
#include <CGAL/Triangulation_file_input.h>
template <typename Tr1, typename Tr2> template <typename Tr1, typename Tr2>
struct Update_vertex_from_CDT_3 { struct Update_vertex_from_CDT_3 {
@ -452,24 +458,28 @@ struct Update_vertex_from_CDT_3 {
typedef typename Tr2::Vertex V2; typedef typename Tr2::Vertex V2;
typedef typename Tr2::Point Point; typedef typename Tr2::Point Point;
bool operator()(const V1& v1, V2& v2) V2 operator()(const V1&)
{
return V2();
}
void operator()(const V1& v1, V2& v2)
{ {
v2.set_point(Point(v1.point())); v2.set_point(Point(v1.point()));
v2.set_dimension(2); v2.set_dimension(2);
v2.set_special(false); v2.set_special(false);
return true;
} }
}; // end struct Update_vertex }; // end struct Update_vertex
struct Update_cell_from_CDT_3 { struct Update_cell_from_CDT_3 {
typedef Fake_mesh_domain::Surface_patch_index Sp_index; typedef Fake_mesh_domain::Surface_patch_index Sp_index;
template <typename C1, typename C2>
bool operator()(const C1& c1, C2& c2) { template <typename C1,typename C2>
void operator()(const C1& c1, C2& c2) {
c2.set_subdomain_index(1); c2.set_subdomain_index(1);
for(int i = 0; i < 4; ++i) { for(int i = 0; i < 4; ++i) {
c2.set_surface_patch_index(i, c1.constrained_facet[i]); c2.set_surface_patch_index(i, c1.constrained_facet[i]);
} }
return true;
} }
}; // end struct Update_cell }; // end struct Update_cell
@ -500,11 +510,10 @@ try_load_a_cdt_3(std::istream& is, C3t3& c3t3)
} }
} }
if(binary) CGAL::set_binary_mode(is); if(binary) CGAL::set_binary_mode(is);
if(CGAL::file_input< if(c3t3.triangulation().file_input<
Fake_CDT_3, Fake_CDT_3,
C3t3::Triangulation,
Update_vertex_from_CDT_3<Fake_CDT_3, C3t3::Triangulation>, Update_vertex_from_CDT_3<Fake_CDT_3, C3t3::Triangulation>,
Update_cell_from_CDT_3>(is, c3t3.triangulation())) Update_cell_from_CDT_3>(is))
{ {
c3t3.rescan_after_load_of_triangulation(); c3t3.rescan_after_load_of_triangulation();
std::cerr << "Try load a CDT_3... DONE"; std::cerr << "Try load a CDT_3... DONE";
@ -544,11 +553,10 @@ try_load_other_binary_format(std::istream& is, C3t3& c3t3)
} }
if(binary) CGAL::set_binary_mode(is); if(binary) CGAL::set_binary_mode(is);
else CGAL::set_ascii_mode(is); else CGAL::set_ascii_mode(is);
std::istream& f_is = CGAL::file_input< std::istream& f_is = c3t3.triangulation().file_input<
Fake_c3t3::Triangulation, Fake_c3t3::Triangulation,
C3t3::Triangulation,
Update_vertex<Fake_c3t3::Triangulation, C3t3::Triangulation>, Update_vertex<Fake_c3t3::Triangulation, C3t3::Triangulation>,
Update_cell>(is, c3t3.triangulation()); Update_cell>(is);
c3t3.rescan_after_load_of_triangulation(); c3t3.rescan_after_load_of_triangulation();
return f_is.good(); return f_is.good();

View File

@ -1,103 +0,0 @@
// Copyright (c) 1997-2010 INRIA Sophia-Antipolis (France).
// Copyright (c) 2011 GeometryFactory Sarl (France)
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you may redistribute it under
// the terms of the Q Public License version 1.0.
// See the file LICENSE.QPL distributed with CGAL.
//
// 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) : Laurent Rineau
//
// Adapted from operator>>(std::istream&, Triangulation_3&) from
// <CGAL/Triangulation_3.h>
#ifndef CGAL_TRIANGULATION_FILE_INPUT_3_H
#define CGAL_TRIANGULATION_FILE_INPUT_3_H
#include <CGAL/basic.h>
namespace CGAL {
template <typename Tr1,
typename Tr2,
typename Update_vertex,
typename Update_cell>
std::istream& file_input(std::istream& is, Tr2 &tr,
Update_vertex update_vertex = Update_vertex(),
Update_cell update_cell = Update_cell())
// reads
// the dimension
// the number of finite vertices
// the non combinatorial information on vertices (point, etc)
// the number of cells
// the cells by the indices of their vertices in the preceding list
// of vertices, plus the non combinatorial information on each cell
// the neighbors of each cell by their index in the preceding list of cells
// when dimension < 3 : the same with faces of maximal dimension
{
typedef Tr2 Triangulation;
typedef typename Triangulation::Vertex_handle Vertex_handle;
typedef typename Triangulation::Cell_handle Cell_handle;
typedef typename Tr1::Vertex Vertex1;
typedef typename Tr1::Cell Cell1;
tr.clear();
tr.tds().cells().clear();
std::size_t n;
int d;
if(is_ascii(is))
is >> d >> n;
else {
read(is, d);
read(is, n);
}
if(!is) return is;
tr.tds().set_dimension(d);
std::vector< Vertex_handle > V(n+1);
V[0] = tr.infinite_vertex();
// the infinite vertex is numbered 0
for (std::size_t i=1; i <= n; i++) {
V[i] = tr.tds().create_vertex();
Vertex1 v;
if(!(is >> v)) return is;
if(!update_vertex(v, *V[i])) {
is.setstate(std::ios_base::failbit);
return is;
}
}
std::vector< Cell_handle > C;
std::size_t m;
tr.tds().read_cells(is, V, m, C);
for (std::size_t j=0 ; j < m; j++) {
Cell1 c;
if(!(is >> c)) return is;
if(!update_cell(c, *(C[j]))) {
is.setstate(std::ios_base::failbit);
return is;
}
}
CGAL_triangulation_assertion( tr.is_valid(false) );
return is;
}
} // end namespace CGAL
#endif // CGAL_TRIANGULATION_FILE_INPUT_3_H

View File

@ -254,10 +254,10 @@ otherwise `Vertex_handle()` is returned.
- A model of `ConvertVertex` must provide two operator()'s that are responsible for converting the source vertex `v_src` into the target vertex: - A model of `ConvertVertex` must provide two operator()'s that are responsible for converting the source vertex `v_src` into the target vertex:
- `Vertex operator()(const TDS_src::Vertex& v_src) const;` This operator is used to create the vertex from `v_src`. - `Vertex operator()(const TDS_src::Vertex& v_src) const;` This operator is used to create the vertex from `v_src`.
- `void operator()(const TDS_src::Vertex& v_src, Vertex& v_tgt) const;` This operator is meant to be used in case heavy data should transferred to `v_tgt`. - `void operator()(const TDS_src::Vertex& v_src, Vertex& v_tgt) const;` This operator is meant to be used in case heavy data should be transferred to `v_tgt`.
- A model of ConvertCell must provide two operator()'s that are responsible for converting the source cell `c_src` into the target cell: - A model of ConvertCell must provide two operator()'s that are responsible for converting the source cell `c_src` into the target cell:
- `Cell operator()(const TDS_src::Cell& c_src) const;` This operator is used to create the cell from `c_src`. - `Cell operator()(const TDS_src::Cell& c_src) const;` This operator is used to create the cell from `c_src`.
- `void operator()(const TDS_src::Cell& c_src, Cell& c_tgt) const;` This operator is meant to be used in case heavy data should transferred to `c_tgt`. - `void operator()(const TDS_src::Cell& c_src, Cell& c_tgt) const;` This operator is meant to be used in case heavy data should be transferred to `c_tgt`.
\pre The optional argument `v` is a vertex of `tds_src` or is `Vertex_handle()`. \pre The optional argument `v` is a vertex of `tds_src` or is `Vertex_handle()`.
*/ */
@ -1024,17 +1024,52 @@ a precise indication on the kind of invalidity encountered.
\cgalDebugEnd \cgalDebugEnd
*/ */
bool is_valid(Cell_handle c, bool verbose = false) const; bool is_valid(Cell_handle c, bool verbose = false) const;
/// @}
/// \name I/O
/// @{
/*! /*!
\ingroup PkgIOTDS3
Reads a combinatorial triangulation from `is` and assigns it to `tds` Reads a combinatorial triangulation from `is` and assigns it to `tds`
*/ */
istream& operator>> (istream& is, TriangulationDataStructure_3 & tds); istream& operator>> (istream& is, TriangulationDataStructure_3 & tds);
/*! /*! \ingroup PkgIOTDS3
Writes `tds` into the stream `os` Writes `tds` into the stream `os`
*/ */
ostream& operator<< (ostream& os, const TriangulationDataStructure_3 & tds); ostream& operator<< (ostream& os, const TriangulationDataStructure_3 & tds);
/*! \ingroup PkgIOTDS3
The tds streamed in `is`, of original type `TDS_src`, is written into the triangulation data structure. As the vertex and cell
types might be different and incompatible, the creation of new cells and vertices
is made thanks to the functors `convert_vertex` and `convert_cell`, that convert
vertex and cell types. For each vertex `v_src` in `is`, the corresponding
vertex `v_tgt` in the triangulation data structure is a copy of the vertex returned by `convert_vertex(v_src)`.
The same operations are done for cells with the functor convert_cell, except cells
in the triangulation data structure are created using the default constructor, and then filled with the data
contained in the stream.
- A model of `ConvertVertex` must provide two `operator()`s that are responsible
for converting the source vertex `v_src` into the target vertex:
- `Vertex operator()(const TDS_src::Vertex& v_src) const;` This operator is
used to create the vertex from `v_src`.
- `void operator()(const TDS_src::Vertex& v_src, Vertex& v_tgt) const;` This
operator is meant to be used in case heavy data should be transferred to `v_tgt`.
- A model of ConvertCell must provide an operator() that is responsible for
converting the source cell `c_src` into the target cell:
- `void operator()(const TDS_src::Cell& c_src, Cell& c_tgt) const;` This operator
is meant to be used in case heavy data should be transferred to `c_tgt`.
\note The triangulation data structure contained in `is` can be obtained with the `operator>>` of a `TriangulationDataStructure_3`.
*/
template <typename TDS_src,
typename ConvertVertex,
typename ConvertCell>
std::istream& file_input(std::istream& is,
ConvertVertex convert_vertex,
ConvertCell convert_cell);
/// @} /// @}
}; /* end TriangulationDataStructure_3 */ }; /* end TriangulationDataStructure_3 */

View File

@ -6,6 +6,8 @@
/// \defgroup PkgTDS3Classes Classes /// \defgroup PkgTDS3Classes Classes
/// \ingroup PkgTDS3Ref /// \ingroup PkgTDS3Ref
/// \defgroup PkgIOTDS3 I/O for a Triangulation_data_structure_3
/// \ingroup PkgTDS3Ref
/*! /*!
\addtogroup PkgTDS3Ref \addtogroup PkgTDS3Ref
\todo check generated documentation \todo check generated documentation

View File

@ -189,6 +189,7 @@ public:
return hf ^ 419 * hs; return hf ^ 419 * hs;
} }
}; };
static const int maximal_nb_of_facets_of_small_hole = 128; static const int maximal_nb_of_facets_of_small_hole = 128;
@ -1521,6 +1522,73 @@ public:
return s <= maximal_nb_of_facets_of_small_hole; return s <= maximal_nb_of_facets_of_small_hole;
} }
//IO
template <typename TDS_src,
typename ConvertVertex,
typename ConvertCell>
std::istream& file_input(std::istream& is,
ConvertVertex convert_vertex = ConvertVertex(),
ConvertCell convert_cell = ConvertCell())
{
// reads
// the dimension
// the number of finite vertices
// the non combinatorial information on vertices (point, etc)
// the number of cells
// the cells by the indices of their vertices in the preceding list
// of vertices, plus the non combinatorial information on each cell
// the neighbors of each cell by their index in the preceding list of cells
// when dimension < 3 : the same with faces of maximal dimension
// If this is used for a TDS, the vertices are processed from 0 to n.
// Else, we make V[0] the infinite vertex and work from 1 to n+1.
typedef typename Tds::Vertex_handle Vertex_handle;
typedef typename Tds::Cell_handle Cell_handle;
typedef typename TDS_src::Vertex Vertex1;
typedef typename TDS_src::Cell Cell1;
clear();
cells().clear();
std::size_t n;
int d;
if(is_ascii(is))
is >> d >> n;
else {
read(is, d);
read(is, n);
}
if(!is) return is;
set_dimension(d);
std::size_t V_size = n;
std::vector< Vertex_handle > V(V_size);
// the infinite vertex is numbered 0
for (std::size_t i=0 ; i < V_size; ++i) {
Vertex1 v;
if(!(is >> v)) return is;
Vertex_handle vh=create_vertex( convert_vertex(v) );
V[i] = vh;
convert_vertex(v, *V[i]);
}
std::vector< Cell_handle > C;
std::size_t m;
read_cells(is, V, m, C);
for (std::size_t j=0 ; j < m; j++) {
Cell1 c;
if(!(is >> c)) return is;
convert_cell(c, *C[j]);
}
CGAL_triangulation_assertion(is_valid(false));
return is;
}
private: private:
// Change the orientation of the cell by swapping indices 0 and 1. // Change the orientation of the cell by swapping indices 0 and 1.
@ -1550,6 +1618,7 @@ private:
// counts but does not check // counts but does not check
bool count_cells(size_type &i, bool verbose = false, int level = 0) const; bool count_cells(size_type &i, bool verbose = false, int level = 0) const;
// counts AND checks the validity // counts AND checks the validity
}; };
#ifdef CGAL_TDS_USE_RECURSIVE_CREATE_STAR_3 #ifdef CGAL_TDS_USE_RECURSIVE_CREATE_STAR_3

View File

@ -10,6 +10,7 @@ if ( CGAL_FOUND )
find_package( TBB QUIET ) find_package( TBB QUIET )
create_single_source_cgal_program( "test_triangulation_tds_3.cpp" ) create_single_source_cgal_program( "test_triangulation_tds_3.cpp" )
create_single_source_cgal_program( "test_io_tds3.cpp" )
if(TBB_FOUND) if(TBB_FOUND)
CGAL_target_use_TBB(test_triangulation_tds_3) CGAL_target_use_TBB(test_triangulation_tds_3)
endif() endif()

View File

@ -0,0 +1,78 @@
#include <fstream>
#include <cassert>
#include <CGAL/Triangulation_data_structure_3.h>
#include <CGAL/Triangulation_vertex_base_with_info_3.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Cartesian_converter.h>
typedef CGAL::Triangulation_data_structure_3<> Tds;
typedef Tds::size_type size_type;
typedef Tds::Cell_handle Cell_handle;
typedef Tds::Vertex_handle Vertex_handle;
template <typename T1, typename T2>
struct Update_vertex
{
typedef typename T1::Vertex V1;
typedef typename T2::Vertex V2;
V2 operator()(const V1&)
{
return V2();
}
void operator()(const V1&, V2&)
{
}
}; // end struct Update_vertex
template <typename T1, typename T2>
struct Update_cell
{
typedef typename T1::Cell C1;
typedef typename T2::Cell C2;
C2 operator()(const C1&)
{
return C2();
}
void operator()(const C1&, C2&)
{
}
}; // end struct Update_vertex
int main()
{
Tds T;
std::vector<Vertex_handle> PV(7);
PV[0] = T.insert_increase_dimension();
// each of the following insertions of vertices increases the dimension
for ( int i=1; i<5; i++ ) {
PV[i] = T.insert_increase_dimension(PV[0]);
}
// we now have a simplex in dimension 4
// cell incident to PV[0]
Cell_handle c = PV[0]->cell();
int ind=0;
// PV[0] is the vertex of index ind in c
// insertion of a new vertex in the facet opposite to PV[0]
PV[5] = T.insert_in_facet(c, ind);
// insertion of a new vertex in c
PV[6] = T.insert_in_cell(c);
std::ofstream out("tr");
out << T;
out.close();
Tds T2;
std::ifstream in("tr");
T2.file_input<Tds,Update_vertex<Tds, Tds>, Update_cell<Tds, Tds> >(in);
in.close();
return 0;
}

View File

@ -1538,6 +1538,7 @@ for faces of maximal dimension instead of cells.
/// @{ /// @{
/*! /*!
\ingroup PkgIOTriangulation3
Reads the underlying combinatorial triangulation from `is` by Reads the underlying combinatorial triangulation from `is` by
calling the corresponding input operator of the triangulation data calling the corresponding input operator of the triangulation data
structure class (note that the infinite vertex is numbered 0), and the structure class (note that the infinite vertex is numbered 0), and the
@ -1550,12 +1551,44 @@ of the vertex and cell types. Assigns the resulting triangulation to
istream& operator>> (istream& is, Triangulation_3 &t); istream& operator>> (istream& is, Triangulation_3 &t);
/*! /*!
* \ingroup PkgIOTriangulation3
Writes the triangulation `t` into `os`. Writes the triangulation `t` into `os`.
*/ */
ostream& operator<< (ostream& os, const Triangulation_3 &t); ostream& operator<< (ostream& os, const Triangulation_3 &t);
/// @} /*!
\ingroup PkgIOTriangulation3
The triangulation streamed in `is`, of original type `Tr_src`, is written into the triangulation. As the vertex and cell
types might be different and incompatible, the creation of new cells and vertices
is made thanks to the functors `convert_vertex` and `convert_cell`, that convert
vertex and cell types. For each vertex `v_src` in `is`, the corresponding
vertex `v_tgt` in the triangulation is a copy of the vertex returned by `convert_vertex(v_src)`.
The same operations are done for cells with the functor convert_cell, except cells
in the triangulation are created using the default constructor, and then filled with the data
contained in the stream.
- A model of `ConvertVertex` must provide two `operator()`s that are responsible
for converting the source vertex `v_src` into the target vertex:
- `Vertex operator()(const Tr_src::Vertex& v_src) const;` This operator is
used to create the vertex from `v_src`.
- `void operator()(const Tr_src::Vertex& v_src, Vertex& v_tgt) const;` This
operator is meant to be used in case heavy data should be transferred to `v_tgt`.
- A model of ConvertCell must provide an operator() that is responsible for
converting the source cell `c_src` into the target cell:
- `void operator()(const Tr_src::Cell& c_src, Cell& c_tgt) const;` This operator
is meant to be used in case data should be transferred to `c_tgt`.
\note The triangulation contained in `is` can be obtained with the `operator>>` of a `Triangulation_3`.
*/
template <typename Tr_src,
typename ConvertVertex,
typename ConvertCell>
std::istream& file_input(std::istream& is,
ConvertVertex convert_vertex = ConvertVertex(),
ConvertCell convert_cell = ConvertCell());
/// @}
///
/// \name Concurrency /// \name Concurrency
/// @{ /// @{

View File

@ -21,6 +21,9 @@
/// \defgroup PkgDrawTriangulation3 Draw a Triangulation 3 /// \defgroup PkgDrawTriangulation3 Draw a Triangulation 3
/// \ingroup PkgTriangulation3Ref /// \ingroup PkgTriangulation3Ref
/// \defgroup PkgIOTriangulation3 I/O for a Triangulation 3
/// \ingroup PkgTriangulation3Ref
/*! /*!
\addtogroup PkgTriangulation3Ref \addtogroup PkgTriangulation3Ref
\cgalPkgDescriptionBegin{3D Triangulations,PkgTriangulation3} \cgalPkgDescriptionBegin{3D Triangulations,PkgTriangulation3}
@ -121,5 +124,8 @@ is opposite to the vertex with the same index. See
- \link PkgDrawTriangulation3 CGAL::draw<T3>() \endlink - \link PkgDrawTriangulation3 CGAL::draw<T3>() \endlink
\cgalCRPSection{I/O}
- \link PkgIOTriangulation3 CGAL:Triangulation_3::file_input<Tr_src, ConvertVertex, ConvertCell>()\endlink
- \link PkgIOTriangulation3 CGAL::file_input<Tr_src, Tr_tgt, ConvertVertex, ConvertCell>()\endlink
*/ */

View File

@ -2196,8 +2196,80 @@ public:
bool is_valid(bool verbose = false, int level = 0) const; bool is_valid(bool verbose = false, int level = 0) const;
bool is_valid(Cell_handle c, bool verbose = false, int level = 0) const; bool is_valid(Cell_handle c, bool verbose = false, int level = 0) const;
bool is_valid_finite(Cell_handle c, bool verbose = false, int level=0) const; bool is_valid_finite(Cell_handle c, bool verbose = false, int level=0) const;
//IO
template <typename Tr_src,
typename ConvertVertex,
typename ConvertCell>
std::istream& file_input(std::istream& is,
ConvertVertex convert_vertex = ConvertVertex(),
ConvertCell convert_cell = ConvertCell())
{
// reads
// the dimension
// the number of finite vertices
// the non combinatorial information on vertices (point, etc)
// the number of cells
// the cells by the indices of their vertices in the preceding list
// of vertices, plus the non combinatorial information on each cell
// the neighbors of each cell by their index in the preceding list of cells
// when dimension < 3 : the same with faces of maximal dimension
// If this is used for a TDS, the vertices are processed from 0 to n.
// Else, we make V[0] the infinite vertex and work from 1 to n+1.
typedef Self Triangulation;
typedef typename Triangulation::Vertex_handle Vertex_handle;
typedef typename Triangulation::Cell_handle Cell_handle;
typedef typename Tr_src::Vertex Vertex1;
typedef typename Tr_src::Cell Cell1;
clear();
tds().cells().clear();
std::size_t n;
int d;
if(is_ascii(is))
is >> d >> n;
else {
read(is, d);
read(is, n);
}
if(!is) return is;
tds().set_dimension(d);
std::size_t V_size = n+1;
std::vector< Vertex_handle > V(V_size);
// the infinite vertex is numbered 0
V[0] = infinite_vertex();
for (std::size_t i = 1; i < V_size; ++i) {
Vertex1 v;
if(!(is >> v)) return is;
Vertex_handle vh=tds().create_vertex( convert_vertex(v) );
V[i] = vh;
convert_vertex(v, *V[i]);
}
std::vector< Cell_handle > C;
std::size_t m;
tds().read_cells(is, V, m, C);
for (std::size_t j=0 ; j < m; j++) {
Cell1 c;
if(!(is >> c)) return is;
convert_cell(c, *C[j]);
}
CGAL_triangulation_assertion( is_valid(false) );
return is;
}
}; };
template < class GT, class Tds, class Lds > template < class GT, class Tds, class Lds >
std::istream& operator>> (std::istream& is, Triangulation_3<GT, Tds, Lds>& tr) std::istream& operator>> (std::istream& is, Triangulation_3<GT, Tds, Lds>& tr)
{ {

View File

@ -28,6 +28,7 @@ if ( CGAL_FOUND )
create_single_source_cgal_program( "test_simplex_3.cpp" ) create_single_source_cgal_program( "test_simplex_3.cpp" )
create_single_source_cgal_program( "test_static_filters.cpp" ) create_single_source_cgal_program( "test_static_filters.cpp" )
create_single_source_cgal_program( "test_triangulation_3.cpp" ) create_single_source_cgal_program( "test_triangulation_3.cpp" )
create_single_source_cgal_program( "test_io_triangulation_3.cpp" )
if(TBB_FOUND) if(TBB_FOUND)
foreach(target foreach(target

View File

@ -0,0 +1,66 @@
#include <fstream>
#include <cassert>
#include <CGAL/Triangulation_3.h>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Cartesian_converter.h>
typedef CGAL::Simple_cartesian<double> K1;
typedef CGAL::Exact_predicates_inexact_constructions_kernel K2;
typedef CGAL::Triangulation_3<K1> Tr1;
typedef CGAL::Triangulation_3<K2> Tr2;
template <typename T1, typename T2>
struct Update_vertex
{
typedef typename T1::Vertex V1;
typedef typename T2::Vertex V2;
typedef typename T2::Point Point;
V2 operator()(const V1&)
{
return V2();
}
void operator()(const V1& v1, V2& v2)
{
CGAL::Cartesian_converter<K1, K2> c;
v2.set_point(Point(c(v1.point())));
}
}; // end struct Update_vertex
struct Update_cell {
template <typename C1, typename C2>
void operator()(const C1&, C2&) {}
}; // end struct Update_cell
int main()
{
// construction from a list of points :
std::list<Tr1::Point> L;
L.push_back(Tr1::Point(0,0,0));
L.push_back(Tr1::Point(1,0,0));
L.push_back(Tr1::Point(0,1,0));
L.push_back(Tr1::Point(0,0,1));
Tr1 T1(L.begin(), L.end());
std::ofstream out("tr");
out << T1;
out.close();
Tr2 T2;
std::ifstream in("tr");
T2.file_input<Tr1,Update_vertex<Tr1, Tr2>, Update_cell>(in);
in.close();
assert(T2.is_valid());
Tr2::Point_iterator pit = T2.points_begin();
assert(*(pit)++ == Tr2::Point(0,0,0));
assert(*(pit)++ == Tr2::Point(1,0,0));
assert(*(pit)++ == Tr2::Point(0,1,0));
assert(*(pit)++ == Tr2::Point(0,0,1));
std::cout << "done" << std::endl;
return 0;
}