mirror of https://github.com/CGAL/cgal
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:
commit
2167d4ffef
|
|
@ -96,6 +96,16 @@ Release date: June 2020
|
|||
does not allow any intersection, except for the configuration of two constraints having a single
|
||||
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
|
||||
|
||||
- Improved the performance of the kd-tree in some cases:
|
||||
|
|
|
|||
|
|
@ -406,6 +406,11 @@ struct Update_vertex
|
|||
typedef typename Tr2::Vertex V2;
|
||||
typedef typename Tr2::Point Point;
|
||||
|
||||
V2 operator()(const V1&)
|
||||
{
|
||||
return V2();
|
||||
}
|
||||
|
||||
bool operator()(const V1& v1, V2& v2)
|
||||
{
|
||||
v2.set_point(Point(v1.point()));
|
||||
|
|
@ -418,7 +423,7 @@ struct Update_vertex
|
|||
const Sp_index sp_index = boost::get<Sp_index>(index);
|
||||
v2.set_index((std::max)(sp_index.first, sp_index.second));
|
||||
}
|
||||
break;
|
||||
break;
|
||||
default:// -1, 0, 1, 3
|
||||
v2.set_index(boost::get<int>(v1.index()));
|
||||
}
|
||||
|
|
@ -427,7 +432,9 @@ struct Update_vertex
|
|||
}; // end struct Update_vertex
|
||||
|
||||
struct Update_cell {
|
||||
|
||||
typedef Fake_mesh_domain::Surface_patch_index Sp_index;
|
||||
|
||||
template <typename C1, typename C2>
|
||||
bool operator()(const C1& c1, C2& c2) {
|
||||
c2.set_subdomain_index(c1.subdomain_index());
|
||||
|
|
@ -442,7 +449,6 @@ struct Update_cell {
|
|||
}
|
||||
}; // end struct Update_cell
|
||||
|
||||
#include <CGAL/Triangulation_file_input.h>
|
||||
|
||||
template <typename Tr1, typename Tr2>
|
||||
struct Update_vertex_from_CDT_3 {
|
||||
|
|
@ -452,24 +458,28 @@ struct Update_vertex_from_CDT_3 {
|
|||
typedef typename Tr2::Vertex V2;
|
||||
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_dimension(2);
|
||||
v2.set_special(false);
|
||||
return true;
|
||||
}
|
||||
}; // end struct Update_vertex
|
||||
|
||||
struct Update_cell_from_CDT_3 {
|
||||
|
||||
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);
|
||||
for(int i = 0; i < 4; ++i) {
|
||||
c2.set_surface_patch_index(i, c1.constrained_facet[i]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}; // 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(CGAL::file_input<
|
||||
if(c3t3.triangulation().file_input<
|
||||
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();
|
||||
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);
|
||||
else CGAL::set_ascii_mode(is);
|
||||
std::istream& f_is = CGAL::file_input<
|
||||
std::istream& f_is = c3t3.triangulation().file_input<
|
||||
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();
|
||||
return f_is.good();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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:
|
||||
- `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:
|
||||
- `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()`.
|
||||
*/
|
||||
|
|
@ -1024,17 +1024,52 @@ a precise indication on the kind of invalidity encountered.
|
|||
\cgalDebugEnd
|
||||
*/
|
||||
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`
|
||||
*/
|
||||
istream& operator>> (istream& is, TriangulationDataStructure_3 & tds);
|
||||
|
||||
/*!
|
||||
/*! \ingroup PkgIOTDS3
|
||||
Writes `tds` into the stream `os`
|
||||
*/
|
||||
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 */
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
/// \defgroup PkgTDS3Classes Classes
|
||||
/// \ingroup PkgTDS3Ref
|
||||
|
||||
/// \defgroup PkgIOTDS3 I/O for a Triangulation_data_structure_3
|
||||
/// \ingroup PkgTDS3Ref
|
||||
/*!
|
||||
\addtogroup PkgTDS3Ref
|
||||
\todo check generated documentation
|
||||
|
|
|
|||
|
|
@ -189,6 +189,7 @@ public:
|
|||
|
||||
return hf ^ 419 * hs;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//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:
|
||||
|
||||
// Change the orientation of the cell by swapping indices 0 and 1.
|
||||
|
|
@ -1550,6 +1618,7 @@ private:
|
|||
// counts but does not check
|
||||
bool count_cells(size_type &i, bool verbose = false, int level = 0) const;
|
||||
// counts AND checks the validity
|
||||
|
||||
};
|
||||
|
||||
#ifdef CGAL_TDS_USE_RECURSIVE_CREATE_STAR_3
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ if ( CGAL_FOUND )
|
|||
|
||||
find_package( TBB QUIET )
|
||||
create_single_source_cgal_program( "test_triangulation_tds_3.cpp" )
|
||||
create_single_source_cgal_program( "test_io_tds3.cpp" )
|
||||
if(TBB_FOUND)
|
||||
CGAL_target_use_TBB(test_triangulation_tds_3)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -1538,6 +1538,7 @@ for faces of maximal dimension instead of cells.
|
|||
/// @{
|
||||
|
||||
/*!
|
||||
\ingroup PkgIOTriangulation3
|
||||
Reads the underlying combinatorial triangulation from `is` by
|
||||
calling the corresponding input operator of the triangulation data
|
||||
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);
|
||||
|
||||
/*!
|
||||
* \ingroup PkgIOTriangulation3
|
||||
Writes the triangulation `t` into `os`.
|
||||
*/
|
||||
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
|
||||
/// @{
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@
|
|||
/// \defgroup PkgDrawTriangulation3 Draw a Triangulation 3
|
||||
/// \ingroup PkgTriangulation3Ref
|
||||
|
||||
/// \defgroup PkgIOTriangulation3 I/O for a Triangulation 3
|
||||
/// \ingroup PkgTriangulation3Ref
|
||||
|
||||
/*!
|
||||
\addtogroup PkgTriangulation3Ref
|
||||
\cgalPkgDescriptionBegin{3D Triangulations,PkgTriangulation3}
|
||||
|
|
@ -121,5 +124,8 @@ is opposite to the vertex with the same index. See
|
|||
|
||||
- \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
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -2196,8 +2196,80 @@ public:
|
|||
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_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 >
|
||||
std::istream& operator>> (std::istream& is, Triangulation_3<GT, Tds, Lds>& tr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ if ( CGAL_FOUND )
|
|||
create_single_source_cgal_program( "test_simplex_3.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_io_triangulation_3.cpp" )
|
||||
|
||||
if(TBB_FOUND)
|
||||
foreach(target
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
Loading…
Reference in New Issue