Merge branch 'CGAL_IO-maxGimeno-old' into CGAL_IO-maxGimeno

This commit is contained in:
Mael Rouxel-Labbé 2020-01-17 12:34:08 +01:00
commit d620198049
145 changed files with 4921 additions and 3536 deletions

View File

@ -192,6 +192,10 @@ the vertices, edges, facets and cells of the different types
(`EXTERIOR`, `SINGULAR`, `REGULAR` or
`INTERIOR`).
\subsection AlphaShape3DIO Input/Output
It is possible to export a 3D alpha shape to a `std::ostream` or to a `Geomview_stream`
using the `operator<<`. More information in the references of `Alpha_shape_3`.
\section AlphaShape3D_ConceptAndModels Concepts and Models
We currently do not specify concepts for the underlying triangulation

View File

@ -588,9 +588,9 @@ model, the properties they support, and any possible caveats that a
user might encounter.
- \link BGLSMGT `boost::graph_traits< CGAL::Surface_mesh<P> >` \endlink
- \link BGLPolyGT `boost::graph_traits< CGAL::Polyhedron_3<T> >` \endlink
- \link BGLPolyGT `boost::graph_traits< CGAL::Polyhedron_3<K> >` \endlink
- \link BGLLCCGT `boost::graph_traits< CGAL::Linear_cell_complex_for_combinatorial_map<...> >` \endlink
- \link BGLSeam_meshGT `boost::graph_traits< CGAL::Seam_mesh<T> >` \endlink
- \link BGLSeam_meshGT `boost::graph_traits< CGAL::Seam_mesh<G> >` \endlink
- \link BGLT2GT `boost::graph_traits< CGAL::Triangulation_2<GT, TDS> >` \endlink
- \link BGLArgtGT `boost::graph_traits< CGAL::Arrangement_2<T,DC> >` \endlink
- \link BGLOMPAK `boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >` \endlink

View File

@ -24,7 +24,16 @@
#include <CGAL/boost/graph/helpers.h>
#include <CGAL/boost/graph/named_params_helper.h>
#include <CGAL/boost/graph/Named_function_parameters.h>
#include <CGAL/boost/graph/properties.h>
#include <CGAL/Kernel_traits.h>
#ifdef CGAL_USE_VTK
#include <CGAL/IO/VTK/vtk_internals.h>
#endif
#include <CGAL/IO/write_vtk.h>
#include <CGAL/internal/Generic_facegraph_builder.h>
#include <CGAL/IO/STL/STL_reader.h>
#include <CGAL/IO/OBJ/OBJ_reader.h>
#include <CGAL/IO/OBJ/File_writer_wavefront.h>
namespace CGAL {
/*!
@ -36,6 +45,7 @@ namespace CGAL {
* If this parameter is omitted, an internal property map for
* `CGAL::vertex_point_t` should be available in `FaceGraph`\cgalParamEnd
* \cgalNamedParamsEnd
* \see \ref IOStreamWRL
*/
template <typename FaceGraph, typename NamedParameters>
bool write_wrl(std::ostream& os,
@ -124,6 +134,7 @@ bool write_wrl(std::ostream& os,
* \cgalNamedParamsEnd
\sa Overloads of this function for specific models of the concept `FaceGraph`.
\see \ref IOStreamOFF
*/
template <typename FaceGraph, typename NamedParameters>
@ -168,7 +179,7 @@ bool write_off(std::ostream& os,
\ingroup PkgBGLIOFct
writes the graph `g` in the OFF format into a file named `fname`.
\sa Overloads of this function for specific models of the concept `FaceGraph`.
\see \ref IOStreamOFF
*/
template <typename FaceGraph, typename NamedParameters>
bool write_off(const char* fname,
@ -247,6 +258,7 @@ inline std::string next_non_comment(std::istream& is)
\sa Overloads of this function for specific models of the concept `FaceGraph`.
\pre The data must represent a 2-manifold
\attention The graph `g` is not cleared, and the data from the stream are added.
\see \ref IOStreamOFF
*/
template <typename FaceGraph, typename NamedParameters>
@ -322,6 +334,7 @@ bool read_off(std::istream& is,
\sa Overloads of this function for specific models of the concept `FaceGraph`.
\pre The data must represent a 2-manifold
\attention The graph `g` is not cleared, and the data from the stream are added.
\see \ref IOStreamOFF
*/
template <typename FaceGraph, typename NamedParameters>
@ -404,6 +417,177 @@ bool write_inp(std::ostream& os,
return write_inp(os, g, name, type, parameters::all_default());
}
namespace GOCAD_internal{
//Use CRTP to gain access to the protected members without getters/setters.
template <class Facegraph, class P>
class GOCAD_builder : public CGAL::internal::IO::Generic_facegraph_builder<Facegraph, P, GOCAD_builder<Facegraph, P> >
{
typedef GOCAD_builder<Facegraph, P> Self;
typedef CGAL::internal::IO::Generic_facegraph_builder<Facegraph, P, Self> Base;
typedef typename Base::Point_3 Point_3;
typedef typename Base::Points_3 Points_3;
typedef typename Base::Facet Facet;
typedef typename Base::Surface Surface;
public:
GOCAD_builder(std::istream& is_)
:Base(is_){}
void do_construct(Facegraph& graph)
{
typedef typename boost::graph_traits<Facegraph>::vertex_descriptor
vertex_descriptor;
std::vector<vertex_descriptor> vertices(this->meshPoints.size());
for(std::size_t id = 0; id < this->meshPoints.size(); ++id)
{
vertices[id] = add_vertex( this->meshPoints[id], graph);
}
// graph.begin_surface( meshPoints.size(), mesh.size());
typedef typename Points_3::size_type size_type;
for(size_type i=0; i < this->mesh.size(); i++){
std::array<vertex_descriptor, 3> face;
face[0] = vertices[this->mesh[i][0]];
face[1] = vertices[this->mesh[i][1]];
face[2] = vertices[this->mesh[i][2]];
CGAL::Euler::add_face(face, graph);
}
}
void
read(std::istream& input, Points_3& points, Surface& surface)
{
int offset = 0;
char c;
std::string s, tface("TFACE");
int i,j,k;
Point_3 p;
bool vertices_read = false;
while(input >> s){
if(s == tface){
break;
}
std::string::size_type idx;
if((idx = s.find("name")) != std::string::npos){
std::istringstream str(s.substr(idx+5));
str >> this->name;
}
if((idx = s.find("color")) != std::string::npos){
std::istringstream str(s.substr(idx+6));
str >> this->color;
}
}
std::getline(input, s);
while(input.get(c)){
if((c == 'V')||(c == 'P')){
input >> s >> i >> p;
if(! vertices_read){
vertices_read = true;
offset -= i; // Some files start with index 0 others with 1
}
points.push_back(p);
} else if(vertices_read && (c == 'T')){
input >> c >> c >> c >> i >> j >> k;
typename Base::Facet new_face(3);
new_face[0] = offset+i;
new_face[1] = offset+j;
new_face[2] = offset+k;
surface.push_back(new_face);
} else if(c == 'E'){
break;
}
std::getline(input, s);
}
}
};
}//end GOCAD_internal
/*!
\ingroup PkgBGLIOFct
reads the graph `face_graph` from data in the TS format.
`name` and `color` will be filled according to the values contained in the file.
\pre The data must represent a 2-manifold
\attention The graph `face_graph` is not cleared, and the data from the stream are added.
\see \ref IOStreamGocad
*/
template <typename FaceGraph>
bool
read_gocad(FaceGraph& face_graph, std::istream& in, std::string& name, std::string& color)
{
//typedef typename Polyhedron::HalfedgeDS HDS;
typedef typename boost::property_traits<typename boost::property_map<FaceGraph, CGAL::vertex_point_t>::type>::value_type Point_3;
GOCAD_internal::GOCAD_builder<FaceGraph, Point_3> builder(in);
builder(face_graph);
name=builder.name;
color=builder.color;
return in.good() && face_graph.is_valid();
}
/*!
\ingroup PkgBGLIOFct
writes the graph `face_graph` in the TS format into `os`. `name` is the
mandatory name that will be assigned to `face_graph`in the file.
\see \ref IOStreamGocad
*/
template <typename FaceGraph>
bool
write_gocad(FaceGraph& face_graph, std::ostream& os, const std::string& name)
{
os << "GOCAD TSurf 1\n"
"HEADER {\n"
"name:";
os << name << std::endl;
os << "*border:on\n"
"*border*bstone:on\n"
"}\n"
"GOCAD_ORIGINAL_COORDINATE_SYSTEM\n"
"NAME Default\n"
"AXIS_NAME \"X\" \"Y\" \"Z\"\n"
"AXIS_UNIT \"m\" \"m\" \"m\"\n"
"ZPOSITIVE Elevation\n"
"END_ORIGINAL_COORDINATE_SYSTEM\n"
"TFACE\n";
os.precision(16);
typedef typename boost::property_map<FaceGraph, CGAL::vertex_point_t>::type VPMap;
VPMap vpmap = get(CGAL::vertex_point, face_graph);
std::map<typename boost::graph_traits<FaceGraph>::vertex_descriptor, int> id_map;
{
typename boost::graph_traits<FaceGraph>::vertex_iterator it, end;
it = vertices(face_graph).begin();
end = vertices(face_graph).end();
int i=0;
for(; it != end; ++it){
id_map[*it] = i;
os << "VRTX " << i << " " << get(vpmap, *it) << "\n";
++i;
}
}
{
typename boost::graph_traits<FaceGraph>::face_iterator it, end;
it = faces(face_graph).begin();
end = faces(face_graph).end();
for(; it != end; ++it){
os << "TRGL " << id_map[target(prev(halfedge(*it, face_graph), face_graph), face_graph)] << " "
<< id_map[target(halfedge(*it, face_graph), face_graph)] << " "
<< id_map[target(next(halfedge(*it, face_graph), face_graph), face_graph)] << "\n";
}
}
os << "END" << std::endl;
return true;
}
namespace internal {
namespace write_vtp {
@ -438,7 +622,7 @@ write_polys(std::ostream& os,
offsets.push_back(off);
for(vertex_descriptor v :
vertices_around_face(halfedge(*fit, mesh), mesh))
connectivity_table.push_back(V[v]);
connectivity_table.push_back(get(V, v));
}
write_vector<std::size_t>(os,connectivity_table);
write_vector<std::size_t>(os,offsets);
@ -492,7 +676,7 @@ write_polys_tag(std::ostream& os,
{
for(vertex_descriptor v :
vertices_around_face(halfedge(*fit, mesh), mesh))
os << V[v] << " ";
os << get(V, v) << " ";
}
os << " </DataArray>\n";
}
@ -642,6 +826,7 @@ write_polys_points(std::ostream& os,
* `CGAL::vertex_index_t` must be available in `TriangleMesh`.
* \cgalParamEnd
* \cgalNamedParamsEnd
* \see \ref IOStreamVTK
*/
template<class TriangleMesh,
class NamedParameters>
@ -687,6 +872,348 @@ void write_vtp(std::ostream& os,
write_vtp(os, mesh, CGAL::parameters::all_default());
}
#ifdef CGAL_USE_VTK
namespace VTK_internal{
template <typename FaceGraph>
bool vtkPointSet_to_polygon_mesh(vtkPointSet* poly_data,
FaceGraph& face_graph)
{
typedef typename boost::property_map<FaceGraph, CGAL::vertex_point_t>::type VPMap;
typedef typename boost::property_map_value<FaceGraph, CGAL::vertex_point_t>::type Point_3;
typedef typename boost::graph_traits<FaceGraph>::vertex_descriptor vertex_descriptor;
VPMap vpmap = get(CGAL::vertex_point, face_graph);
// get nb of points and cells
vtkIdType nb_points = poly_data->GetNumberOfPoints();
vtkIdType nb_cells = poly_data->GetNumberOfCells();
//extract points
std::vector<vertex_descriptor> vertex_map(nb_points);
for (vtkIdType i = 0; i<nb_points; ++i)
{
double coords[3];
poly_data->GetPoint(i, coords);
vertex_descriptor v = add_vertex(face_graph);
put(vpmap, v, Point_3(coords[0], coords[1], coords[2]));
vertex_map[i]=v;
}
//extract cells
for (vtkIdType i = 0; i<nb_cells; ++i)
{
int cell_type = poly_data->GetCellType(i);
if(cell_type != 5
&& cell_type != 7
&& cell_type != 9) //only supported cells are triangles, quads and polygons
continue;
vtkCell* cell_ptr = poly_data->GetCell(i);
vtkIdType nb_vertices = cell_ptr->GetNumberOfPoints();
if (nb_vertices < 3)
return false;
std::vector<vertex_descriptor> vr(nb_vertices);
for (vtkIdType k=0; k<nb_vertices; ++k){
vtkIdType id = cell_ptr->GetPointId(k);
vr[k]=vertex_map[id];
}
CGAL::Euler::add_face(vr, face_graph);
}
return true;
}
} //end VTK_internal
template<class FaceGraph>
bool read_vtp(const char* filename, FaceGraph& face_graph)
{
vtkSmartPointer<vtkPointSet> data;
if(!CGAL::read_vtp_file(filename, data))
{
return false;
}
return VTK_internal::vtkPointSet_to_polygon_mesh(data, face_graph);
}
#endif //CGAL_USE_VTK
#ifdef DOXYGEN_RUNNING
/*! \ingroup PkgBGLIOFct
* \brief reads a PolyData in the VTP format into a triangulated surface mesh.
*
* \tparam FaceGraph a model of `FaceListGraph`.
*
* \param filename the path to the file that will be read.
* \param face_graph the output mesh.
*
* \pre \cgal needs to be configured with the VTK Libraries for this function to be available.
*/
template<class FaceGraph>
bool read_vtp(const char* filename, FaceGraph& face_graph);
#endif
/*!
\ingroup PkgBGLIOFct
writes the graph `tm` in the stream `out` in the STL format.
\pre The graph must contain only triangle faces.
\see \ref IOStreamSTL
*/
template <class TriangleMesh>
std::ostream&
write_STL(const TriangleMesh& tm, std::ostream& out)
{
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::property_map<TriangleMesh, boost::vertex_point_t>::const_type Vpm;
typedef typename boost::property_traits<Vpm>::reference Point_3_ref;
typedef typename boost::property_traits<Vpm>::value_type Point_3;
typedef typename Kernel_traits<Point_3>::Kernel::Vector_3 Vector_3;
Vpm vpm = get(boost::vertex_point, tm);
if (get_mode(out) == IO::BINARY)
{
out << "FileType: Binary ";
const boost::uint32_t N32 = static_cast<boost::uint32_t>(faces(tm).size());
out.write(reinterpret_cast<const char *>(&N32), sizeof(N32));
for(face_descriptor f : faces(tm))
{
halfedge_descriptor h = halfedge(f, tm);
Point_3_ref p = get(vpm, target(h, tm));
Point_3_ref q = get(vpm, target(next(h, tm), tm));
Point_3_ref r = get(vpm, source(h, tm));
Vector_3 n = collinear(p,q,r) ? Vector_3(1,0,0):
unit_normal(p,q,r);
const float coords[12]={
static_cast<float>(n.x()), static_cast<float>(n.y()), static_cast<float>(n.z()),
static_cast<float>(p.x()), static_cast<float>(p.y()), static_cast<float>(p.z()),
static_cast<float>(q.x()), static_cast<float>(q.y()), static_cast<float>(q.z()),
static_cast<float>(r.x()), static_cast<float>(r.y()), static_cast<float>(r.z()) };
for (int i=0; i<12; ++i)
out.write(reinterpret_cast<const char *>(&coords[i]), sizeof(coords[i]));
out << " ";
}
}
else
{
out << "solid\n";
for(face_descriptor f : faces(tm))
{
halfedge_descriptor h = halfedge(f, tm);
Point_3_ref p = get(vpm, target(h, tm));
Point_3_ref q = get(vpm, target(next(h, tm), tm));
Point_3_ref r = get(vpm, source(h, tm));
Vector_3 n = collinear(p,q,r) ? Vector_3(1,0,0):
unit_normal(p,q,r);
out << "facet normal " << n << "\nouter loop\n";
out << "vertex " << p << "\n";
out << "vertex " << q << "\n";
out << "vertex " << r << "\n";
out << "endloop\nendfacet\n";
}
out << "endsolid\n";
}
return out;
}
namespace STL_internal
{
//Use CRTP to gain access to the protected members without getters/setters.
template <class Facegraph, class P>
class STL_builder : public CGAL::internal::IO::Generic_facegraph_builder<Facegraph, P, STL_builder<Facegraph, P> >
{
typedef STL_builder<Facegraph, P> Self;
typedef CGAL::internal::IO::Generic_facegraph_builder<Facegraph, P, Self> Base;
typedef typename Base::Point_3 Point_3;
typedef typename Base::Points_3 Points_3;
typedef typename Base::Facet Facet;
typedef typename Base::Surface Surface;
public:
STL_builder(std::istream& is_)
:Base(is_){}
void do_construct(Facegraph& graph)
{
typedef typename boost::graph_traits<Facegraph>::vertex_descriptor
vertex_descriptor;
std::vector<vertex_descriptor> vertices(this->meshPoints.size());
for(std::size_t id = 0; id < this->meshPoints.size(); ++id)
{
vertices[id] = add_vertex( this->meshPoints[id], graph);
}
// graph.begin_surface( meshPoints.size(), mesh.size());
typedef typename Points_3::size_type size_type;
for(size_type i=0; i < this->mesh.size(); i++){
std::array<vertex_descriptor, 3> face;
face[0] = vertices[this->mesh[i][0]];
face[1] = vertices[this->mesh[i][1]];
face[2] = vertices[this->mesh[i][2]];
CGAL::Euler::add_face(face, graph);
}
}
void
read(std::istream& input, Points_3& points, Surface& surface)
{
read_STL(input, points, surface);
}
};
} // end STL_internal
/*!
\ingroup PkgBGLIOFct
reads the graph `tm` from the stream `in` in the STL format.
\returns `true` if the resulting mesh is valid.
\pre The data must represent a 2-manifold
\see \ref IOStreamSTL
*/
template <class TriangleMesh>
bool
read_STL(TriangleMesh& tm, std::istream& in)
{
//typedef typename Polyhedron::HalfedgeDS HDS;
typedef typename boost::property_traits<typename boost::property_map<TriangleMesh, CGAL::vertex_point_t>::type>::value_type Point_3;
STL_internal::STL_builder<TriangleMesh, Point_3> builder(in);
builder(tm);
bool ok = in.good() || in.eof();
ok &= tm.is_valid();
return ok;
}
namespace OBJ_internal
{
//Use CRTP to gain access to the protected members without getters/setters.
template <class Facegraph, class P>
class OBJ_builder : public CGAL::internal::IO::Generic_facegraph_builder<Facegraph, P, OBJ_builder<Facegraph, P> >
{
typedef OBJ_builder<Facegraph, P> Self;
typedef CGAL::internal::IO::Generic_facegraph_builder<Facegraph, P, Self> Base;
typedef typename Base::Point_3 Point_3;
typedef typename Base::Points_3 Points_3;
typedef typename Base::Facet Facet;
typedef typename Base::Surface Surface;
public:
OBJ_builder(std::istream& is_)
:Base(is_){}
void do_construct(Facegraph& graph)
{
typedef typename boost::graph_traits<Facegraph>::vertex_descriptor
vertex_descriptor;
std::vector<vertex_descriptor> vertices(this->meshPoints.size());
for(std::size_t id = 0; id < this->meshPoints.size(); ++id)
{
vertices[id] = add_vertex( this->meshPoints[id], graph);
}
typedef typename Points_3::size_type size_type;
for(size_type i=0; i < this->mesh.size(); i++){
std::vector<vertex_descriptor> face(this->mesh[i].size());
for(std::size_t j=0; j< face.size(); ++j)
face[j] = vertices[this->mesh[i][j]];
CGAL::Euler::add_face(face, graph);
}
}
void
read(std::istream& input, Points_3& points, Surface& surface)
{
read_OBJ(input, points, surface);
}
};
} // end STL_internal
/*!
\ingroup PkgBGLIOFct
reads the graph `tm` from the stream `in` in the OBJ format.
\returns `true` if the resulting mesh is valid.
\pre The data must represent a 2-manifold
\see \ref IOStreamOBJ
*/
template <class TriangleMesh>
bool
read_OBJ(TriangleMesh& tm, std::istream& in)
{
//typedef typename Polyhedron::HalfedgeDS HDS;
typedef typename boost::property_traits<typename boost::property_map<TriangleMesh, CGAL::vertex_point_t>::type>::value_type Point_3;
OBJ_internal::OBJ_builder<TriangleMesh, Point_3> builder(in);
builder(tm);
bool ok = in.good() || in.eof();
ok &= tm.is_valid();
return ok;
}
/*!
\ingroup PkgBGLIOFct
writes the graph `face_graph` in the OBJ format.
\returns `true` if writing was successful.
\see \ref IOStreamOBJ
*/
template <typename FaceGraph>
bool
write_OBJ(const FaceGraph& face_graph, std::ostream& os)
{
// writes M to `out' in the format provided by `writer'.
CGAL::File_writer_wavefront writer;
typedef typename boost::graph_traits<FaceGraph >::vertex_iterator VCI;
typedef typename boost::graph_traits<FaceGraph >::face_iterator FCI;
typedef typename boost::property_map<FaceGraph, CGAL::vertex_point_t>::type VPmap;
VPmap map = get(CGAL::vertex_point, face_graph);
// Print header.
writer.write_header( os,
num_vertices(face_graph),
num_halfedges(face_graph),
num_faces(face_graph));
std::map<typename boost::graph_traits<FaceGraph>::vertex_descriptor, std::size_t> index_map;
auto hint = index_map.begin();
std::size_t id = 0;
for( VCI vi = vertices(face_graph).begin(); vi != vertices(face_graph).end(); ++vi) {
writer.write_vertex( ::CGAL::to_double( get(map, *vi).x()),
::CGAL::to_double( get(map, *vi).y()),
::CGAL::to_double( get(map, *vi).z()));
hint = index_map.insert(hint, std::make_pair(*vi, id++));
}
writer.write_facet_header();
for( FCI fi = faces(face_graph).begin(); fi != faces(face_graph).end(); ++fi) {
CGAL::Halfedge_around_face_circulator<FaceGraph> hc(halfedge(*fi, face_graph), face_graph);
auto hc_end = hc;
std::size_t n = circulator_size( hc);
CGAL_assertion( n >= 3);
writer.write_facet_begin( n);
do {
writer.write_facet_vertex_index(index_map[target(*hc, face_graph)]);
++hc;
} while( hc != hc_end);
writer.write_facet_end();
}
writer.write_footer();
return os.good();
}
} // namespace CGAL
#endif // CGAL_BOOST_GRAPH_IO_H

View File

@ -10,7 +10,8 @@ project( BGL_Tests )
# CGAL and its components
find_package( CGAL QUIET COMPONENTS )
find_package(VTK QUIET COMPONENTS
vtkCommonCore vtkIOCore vtkIOLegacy vtkIOXML vtkFiltersCore vtkFiltersSources)
if ( NOT CGAL_FOUND )
message(STATUS "This project requires the CGAL library, and will not be compiled.")
@ -32,11 +33,10 @@ if ( OpenMesh_FOUND )
include( UseOpenMesh )
add_definitions( -DCGAL_USE_OPENMESH )
else()
message(STATUS "Examples that use OpenMesh will not be compiled.")
message(STATUS "Tests that use OpenMesh will not be compiled.")
endif()
# include for local package
# Creating entries for all .cpp/.C files with "main" routine
@ -108,3 +108,19 @@ if(OpenMesh_FOUND)
target_link_libraries( test_Properties PRIVATE ${OPENMESH_LIBRARIES})
target_link_libraries( test_bgl_read_write PRIVATE ${OPENMESH_LIBRARIES})
endif()
if (VTK_FOUND)
if(VTK_USE_FILE)
include(${VTK_USE_FILE})
endif()
if ("${VTK_VERSION_MAJOR}" GREATER "5" OR VTK_VERSION VERSION_GREATER 5)
if(TARGET VTK::CommonCore)
set(VTK_LIBRARIES VTK::CommonCore VTK::IOCore VTK::IOLegacy VTK::IOXML VTK::FiltersCore VTK::FiltersSources)
endif()
if(VTK_LIBRARIES)
add_definitions(-DCGAL_USE_VTK)
target_link_libraries( test_bgl_read_write PRIVATE ${VTK_LIBRARIES})
else()
message(STATUS "Tests that use VTK will not be compiled.")
endif()
endif()
endif() #VTK_FOUND

View File

@ -7,6 +7,7 @@
#include <CGAL/Linear_cell_complex_for_bgl_combinatorial_map_helper.h>
#include <CGAL/boost/graph/graph_traits_Linear_cell_complex_for_combinatorial_map.h>
#include <CGAL/boost/graph/helpers.h>
#if defined(CGAL_USE_OPENMESH)
@ -17,6 +18,7 @@
#endif
#include <CGAL/boost/graph/io.h>
#include <CGAL/IO/STL/STL_writer.h>
#include <iostream>
#include <fstream>
@ -47,17 +49,186 @@ void test_bgl_read_write(const char* filename)
CGAL::write_off(std::cout, sm);
}
#ifdef CGAL_USE_VTK
template<typename Mesh>
bool test_bgl_vtp()
{
Mesh fg;
CGAL::make_tetrahedron(Point(0, 0, 0), Point(1, 1, 0),
Point(2, 0, 1), Point(3, 0, 0), fg);
std::ofstream os("tetrahedron.vtp");
CGAL::write_vtp(os, fg);
if(!os)
{
std::cerr<<"vtp writing failed."<<std::endl;
return false;
}
os.close();
Mesh fg2;
if(!CGAL::read_vtp("tetrahedron.vtp", fg2))
{
std::cerr<<"vtp reading failed."<<std::endl;
return false;
}
if(num_vertices(fg) != num_vertices(fg2)
|| num_faces(fg) != num_faces(fg2))
{
std::cerr<<"Coherence problem. Wrong number of vertices or faces."<<std::endl;
std::cerr<<num_faces(fg)<<" != "<<num_faces(fg2)<<std::endl;
return false;
}
return true;
}
template<>
bool test_bgl_vtp<Polyhedron>()
{
Polyhedron fg;
CGAL::make_tetrahedron(Point(0, 0, 0), Point(1, 1, 0),
Point(2, 0, 1), Point(3, 0, 0), fg);
typedef boost::property_map<Polyhedron, CGAL::dynamic_vertex_property_t<std::size_t> >::type VertexIdMap;
VertexIdMap vid = get(CGAL::dynamic_vertex_property_t<std::size_t>(), fg);
std::size_t id = 0;
for(auto v : vertices(fg))
put(vid,v, id++);
std::ofstream os("tetrahedron.vtp");
CGAL::write_vtp(os, fg, CGAL::parameters::vertex_index_map(vid));
if(!os)
{
std::cerr<<"vtp writing failed."<<std::endl;
return false;
}
os.close();
Polyhedron fg2;
if(!CGAL::read_vtp("tetrahedron.vtp", fg2))
{
std::cerr<<"vtp reading failed."<<std::endl;
return false;
}
if(num_vertices(fg) != num_vertices(fg2)
|| num_faces(fg) != num_faces(fg2))
{
std::cerr<<"Coherence problem. Wrong number of vertices or faces."<<std::endl;
return false;
}
return true;
}
#endif
template<class FaceGraph>
bool test_gocad()
{
FaceGraph fg;
CGAL::make_tetrahedron(Point(0, 0, 0), Point(1, 1, 0),
Point(2, 0, 1), Point(3, 0, 0), fg);
std::ostringstream out;
CGAL::write_gocad(fg, out, "tetrahedron");
if(out.fail())
{
std::cerr<<"Tetrahedron writing failed."<<std::endl;
return false;
}
FaceGraph fg2;
std::istringstream in( out.str());
std::string name, color;
CGAL::read_gocad(fg2, in, name, color);
if(name != "tetrahedron"){
std::cerr<<"reading error: tetrahedron != "<<name<<std::endl;
return 1;
}
if( !color.empty()){
std::cerr<<"reading error: there should be no color."<<std::endl;
return 1;
}
if(in.fail()){
std::cerr<<"Tetrahedron reading failed."<<std::endl;
return false;
}
if(num_vertices(fg2) != 4){
std::cerr<<"Wrong number of vertices: 4 != "<<num_vertices(fg2)<<std::endl;
return false;
}
if(num_faces(fg2) != 4)
{
std::cerr<<"Wrong number of faces: 4 != "<<num_faces(fg2)<<std::endl;
return false;
}
return true;
}
template<class FaceGraph>
bool test_STL()
{
FaceGraph fg;
CGAL::make_tetrahedron(Point(0, 0, 0), Point(1, 1, 0),
Point(2, 0, 1), Point(3, 0, 0), fg);
std::ostringstream out;
CGAL::write_STL(fg, out);
if(out.fail())
{
std::cerr<<"Tetrahedron writing failed."<<std::endl;
return false;
}
FaceGraph fg2;
std::istringstream in( out.str());
if(!CGAL::read_STL(fg2, in)){
std::cerr<<"Tetrahedron reading failed."<<std::endl;
return false;
}
if(num_vertices(fg2) != 4){
std::cerr<<"Wrong number of vertices: 4 != "<<num_vertices(fg2)<<std::endl;
return false;
}
if(num_faces(fg2) != 4)
{
std::cerr<<"Wrong number of faces: 4 != "<<num_faces(fg2)<<std::endl;
return false;
}
return true;
}
int main(int argc, char** argv)
{
const char* filename=(argc>1)?argv[1]:"data/prim.off";
//OFF
test_bgl_read_write<Polyhedron>(filename);
test_bgl_read_write<SM>(filename);
test_bgl_read_write<LCC>(filename);
#ifdef CGAL_USE_OPENMESH
test_bgl_read_write<OMesh>(filename);
#endif
//GOCAD
if(!test_gocad<Polyhedron>())
return 1;
if(!test_gocad<SM>())
return 1;
if(!test_gocad<LCC>())
return 1;
//STL
if(!test_STL<Polyhedron>())
return 1;
if(!test_STL<SM>())
return 1;
if(!test_STL<LCC>())
return 1;
//VTP
#ifdef CGAL_USE_VTK
if(!test_bgl_vtp<Polyhedron>())
return 1;
if(!test_bgl_vtp<SM>())
return 1;
if(!test_bgl_vtp<LCC>())
return 1;
#endif
return EXIT_SUCCESS;
}

View File

@ -896,6 +896,42 @@ table.doxtable th {
padding-top: 5px;
}
table.iotable caption {
caption-side: top;
}
table.iotable {
border-collapse:collapse;
margin-top: 4px;
margin-bottom: 4px;
}
table.iotable td, table.iotable th {
border: 1px solid #2D4068;
padding: 3px 7px 2px;
}
table.iotable th a,table.iotable th a:visited {
color: #FFFFFF;
text-decoration: underline;
}
table.iotable th {
background-color: #374F7F;
color: #FFFFFF;
font-size: 110%;
padding-bottom: 4px;
padding-top: 5px;
}
table.iotable th a, table.iotable th a:visited {
font-weight: bold;
color: #FFFFFF;
text-decoration: underline;
}
table.fieldtable {
/*width: 100%;*/
margin-bottom: 10px;
@ -909,6 +945,7 @@ table.fieldtable {
box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
}
.fieldtable td, .fieldtable th {
padding: 3px 7px 2px;
}

View File

@ -896,6 +896,43 @@ table.doxtable th {
padding-top: 5px;
}
table.iotable caption {
caption-side: top;
}
table.iotable {
border-collapse:collapse;
margin-top: 4px;
margin-bottom: 4px;
}
table.iotable td, table.iotable th {
border: 1px solid #2D4068;
padding: 3px 7px 2px;
}
table.iotable th a,table.iotable th a:visited {
color: #FFFFFF;
text-decoration: underline;
}
table.iotable th {
background-color: #374F7F;
color: #FFFFFF;
font-size: 110%;
padding-bottom: 4px;
padding-top: 5px;
}
table.iotable th a, table.iotable th a:visited {
font-weight: bold;
color: #FFFFFF;
text-decoration: underline;
}
table.fieldtable {
/*width: 100%;*/
margin-bottom: 10px;

View File

@ -762,6 +762,43 @@ table.doxtable th {
padding-top: 5px;
}
table.iotable caption {
caption-side: top;
}
table.iotable {
border-collapse:collapse;
margin-top: 4px;
margin-bottom: 4px;
}
table.iotable td, table.iotable th {
border: 1px solid #2D4068;
padding: 3px 7px 2px;
}
table.iotable th a,table.iotable th a:visited {
color: #FFFFFF;
text-decoration: underline;
}
table.iotable th {
background-color: #374F7F;
color: #FFFFFF;
font-size: 110%;
padding-bottom: 4px;
padding-top: 5px;
}
table.iotable th a, table.iotable th a:visited {
font-weight: bold;
color: #FFFFFF;
text-decoration: underline;
}
table.fieldtable {
width: 100%;
margin-bottom: 10px;

View File

@ -15,81 +15,12 @@
#ifndef CGAL_ALPHA_SHAPE_3_VRML_2_OSTREAM_H
#define CGAL_ALPHA_SHAPE_3_VRML_2_OSTREAM_H
#include <CGAL/disable_warnings.h>
#include <CGAL/basic.h>
#include <CGAL/IO/VRML_2_ostream.h>
#ifdef CGAL_ALPHA_SHAPE_3_H
namespace CGAL {
template <class Dt >
VRML_2_ostream&
operator<<(VRML_2_ostream& os,
Alpha_shape_3<Dt> &as)
{
// Finite vertices coordinates.
Alpha_shape_3<Dt>::Alpha_shape_vertices_iterator Vlist_it,
Vlist_begin = as.alpha_shape_vertices_begin(),
Vlist_end = as.alpha_shape_vertices_end();
std::map<Alpha_shape_3<Dt>::Vertex_handle, int> V;
int number_of_vertex = 0;
for( Vlist_it = Vlist_begin; Vlist_it != Vlist_end; Vlist_it++) {
V[*Vlist_it] = number_of_vertex++;
}
typename Alpha_shape_3<Dt>::Alpha_shape_facets_iterator Flist_it,
Flist_begin = as.alpha_shape_facets_begin(),
Flist_end = as.alpha_shape_facets_end();
std::map<Alpha_shape_3<Dt>::Facet, int> F;
int number_of_facets = 0;
for( Flist_it = Flist_begin; Flist_it != Flist_end; Flist_it++) {
F[*Flist_it] = number_of_facets++;
}
const char *Indent = " ";
os << " Group {\n"
" children [\n"
" Shape {\n"
" appearance USE A1\n"
" geometry\n"
" IndexedFaceSet {\n"
" coord Coordinate {\n"
" point [ \n"
<< Indent << " ";
for( Vlist_it = Vlist_begin; Vlist_it != Vlist_end; Vlist_it++) {
os << CGAL::to_double((*Vlist_it)->point().x()) << " ";
os << CGAL::to_double((*Vlist_it)->point().y()) << " ";
os << CGAL::to_double((*Vlist_it)->point().z()) << ",\n" << Indent << " ";
}
os << "\n ]\n"
" } # coord\n"
" solid FALSE\n"
<< Indent << "coordIndex [\n";
// Finite facets indices.
for( Flist_it = Flist_begin; Flist_it != Flist_end; Flist_it++){
os << Indent << " ";
for (int i=0; i<4; i++)
if (i != (*Flist_it).second){
os << V[(*Flist_it).first->vertex(i)];
os << ", ";
}
if (Flist_it != Flist_end)
os << "-1,\n";
else
os << "-1 \n";
}
os << Indent << "]\n";
" } #IndexedFaceSet\n"
" } #Shape\n"
" ] #children\n"
" } #Group\n";
return os;
}
} //namespace CGAL
#endif // CGAL_ALPHA_SHAPE_3_H
#define CGAL_DEPRECATED_HEADER "<CGAL/IO/Alpha_shape_3_VRML_2_ostream.h>"
#define CGAL_REPLACEMENT_HEADER "<CGAL/IO/VRML/Alpha_shape_3_VRML_2_ostream.h>"
#include <CGAL/internal/deprecation_warning.h>
#include <CGAL/IO/VRML/Alpha_shape_3_VRML_2_ostream.h>
#include <CGAL/enable_warnings.h>
#endif CGAL_ALPHA_SHAPE_3_VRML_2_OSTREAM_H

View File

@ -19,108 +19,12 @@
#ifndef CGAL_IO_INVENTOR_OSTREAM_H
#define CGAL_IO_INVENTOR_OSTREAM_H
#include <CGAL/basic.h>
#include <iostream>
#include <CGAL/disable_warnings.h>
// OpenInventor and VRML 1.0 are quite similar formats, so
// output operators could be shared if they use the following
// base class, which is common for both output streams.
namespace CGAL {
class Inventor_ostream_base {
private:
std::ostream* m_os;
public:
Inventor_ostream_base() : m_os(0) {}
Inventor_ostream_base(std::ostream& o) : m_os(&o) {}
~Inventor_ostream_base() { close(); }
void open(std::ostream& o) { m_os = &o; }
void close() {
if ( m_os)
os() << std::endl;
m_os = 0;
}
explicit operator bool ()
{
return m_os && !m_os->fail();
}
std::ostream& os() {
// The behaviour if m_os == 0 could be changed to return
// cerr or a file handle to /dev/null. The latter one would
// mimick the behaviour that one can still use a stream with
// an invalid stream, but without producing any output.
CGAL_assertion( m_os != 0 );
return *m_os;
}
};
class Inventor_ostream : public Inventor_ostream_base
{
public:
Inventor_ostream() {}
Inventor_ostream(std::ostream& o) : Inventor_ostream_base(o) {
header();
}
void open(std::ostream& o) {
Inventor_ostream_base::open(o);
header();
}
private:
void header() {
os() << "#Inventor V2.0 ascii" << std::endl;
os() << "# File written with the help of the CGAL Library"
<< std::endl;
}
};
} //namespace CGAL
#endif // CGAL_IO_INVENTOR_OSTREAM_H
#ifdef CGAL_TETRAHEDRON_3_H
#ifndef CGAL_INVENTOR_TETRAHEDRON_3
#define CGAL_INVENTOR_TETRAHEDRON_3
namespace CGAL {
template <class R >
Inventor_ostream&
operator<<(Inventor_ostream& os,
const Tetrahedron_3<R > &t)
{
const char *Indent = " ";
os.os() << "\n Separator {";
os.os() << "\n Coordinate3 { \n"
<< Indent << "point [\n"
<< Indent << " "
<< CGAL::to_double(t[0].x()) << " "
<< CGAL::to_double(t[0].y()) << " "
<< CGAL::to_double(t[0].z()) << " ,\n"
<< Indent << " "
<< CGAL::to_double(t[1].x()) << " "
<< CGAL::to_double(t[1].y()) << " "
<< CGAL::to_double(t[1].z()) << " ,\n"
<< Indent << " "
<< CGAL::to_double(t[2].x()) << " "
<< CGAL::to_double(t[2].y()) << " "
<< CGAL::to_double(t[2].z()) << " ,\n"
<< Indent << " "
<< CGAL::to_double(t[3].x()) << " "
<< CGAL::to_double(t[3].y()) << " "
<< CGAL::to_double(t[3].z()) << " ]"
<< "\n } #Coordinate3" ;
os.os() << "\n IndexedFaceSet {"
<< Indent << "coordIndex [ 0,1,2,-1, 1,3,2,-1,\n"
<< Indent << " 0,2,3,-1, 0,3,1,-1 ]\n"
<< "\n } #IndexedFaceSet"
<< "\n } #Separator\n";
return os;
}
} //namespace CGAL
#define CGAL_DEPRECATED_HEADER "<CGAL/IO/Inventor_ostream.h>"
#define CGAL_REPLACEMENT_HEADER "<CGAL/IO/VRML/Inventor_ostream.h>"
#include <CGAL/internal/deprecation_warning.h>
#include <CGAL/IO/VRML/Inventor_ostream.h>
#include <CGAL/enable_warnings.h>
#endif // CGAL_INVENTOR_TETRAHEDRON_3
#endif // CGAL_TETRAHEDRON_3_H

View File

@ -19,82 +19,12 @@
#ifndef CGAL_IO_VRML_1_OSTREAM_H
#define CGAL_IO_VRML_1_OSTREAM_H
#include <CGAL/basic.h>
#include <iostream>
#include <CGAL/disable_warnings.h>
// Declare the common base class for OpenInventor and VRML 1.0 format.
#include <CGAL/IO/Inventor_ostream.h>
// OpenInventor and VRML 1.0 are quite similar formats, so
// output operators could be shared if they use the common
// base class Inventor_ostream_base, which is common for
// both output streams.
namespace CGAL {
class VRML_1_ostream : public Inventor_ostream_base {
public:
VRML_1_ostream() {}
VRML_1_ostream(std::ostream& o) : Inventor_ostream_base(o) {
header();
}
void open(std::ostream& o) {
Inventor_ostream_base::open(o);
header();
}
private:
void header() {
os() << "#VRML V1.0 ascii" << std::endl;
os() << "# File written with the help of the CGAL Library"
<< std::endl;
}
};
} //namespace CGAL
#endif // CGAL_IO_VRML_1_OSTREAM_H
#ifdef CGAL_TETRAHEDRON_3_H
#ifndef CGAL_IO_VRML_1_TETRAHEDRON_3
#define CGAL_IO_VRML_1_TETRAHEDRON_3
namespace CGAL {
template <class R >
VRML_1_ostream&
operator<<(VRML_1_ostream& os,
const Tetrahedron_3<R > &t)
{
const char *Indent = " ";
os.os() << "\n Separator {";
os.os() << "\n Coordinate3 { \n"
<< Indent << "point [\n"
<< Indent << " "
<< CGAL::to_double(t[0].x()) << " "
<< CGAL::to_double(t[0].y()) << " "
<< CGAL::to_double(t[0].z()) << " ,\n"
<< Indent << " "
<< CGAL::to_double(t[1].x()) << " "
<< CGAL::to_double(t[1].y()) << " "
<< CGAL::to_double(t[1].z()) << " ,\n"
<< Indent << " "
<< CGAL::to_double(t[2].x()) << " "
<< CGAL::to_double(t[2].y()) << " "
<< CGAL::to_double(t[2].z()) << " ,\n"
<< Indent << " "
<< CGAL::to_double(t[3].x()) << " "
<< CGAL::to_double(t[3].y()) << " "
<< CGAL::to_double(t[3].z()) << " ]"
<< "\n } #Coordinate3" ;
os.os() << "\n IndexedFaceSet {"
<< Indent << "coordIndex [ 0,1,2,-1, 1,3,2,-1,\n"
<< Indent << " 0,2,3,-1, 0,3,1,-1 ]\n"
<< "\n } #IndexedFaceSet"
<< "\n } #Separator\n";
return os;
}
} //namespace CGAL
#define CGAL_DEPRECATED_HEADER "<CGAL/IO/VRML_1_ostream.h>"
#define CGAL_REPLACEMENT_HEADER "<CGAL/IO/VRML/VRML_1_ostream.h>"
#include <CGAL/internal/deprecation_warning.h>
#include <CGAL/IO/VRML/VRML_1_ostream.h>"
#include <CGAL/enable_warnings.h>
#endif // CGAL_IO_VRML_1_TETRAHEDRON_3
#endif // CGAL_TETRAHEDRON_3_H

View File

@ -18,295 +18,12 @@
#ifndef CGAL_IO_VRML_2_OSTREAM_H
#define CGAL_IO_VRML_2_OSTREAM_H
#include <CGAL/disable_warnings.h>
#include <CGAL/basic.h>
#include <iostream>
namespace CGAL {
class VRML_2_ostream {
public:
VRML_2_ostream() : m_os(0) {}
VRML_2_ostream(std::ostream& o) : m_os(&o) { header();}
~VRML_2_ostream() { close(); }
void open(std::ostream& o) { m_os = &o; header(); }
void close() {
if ( m_os)
footer();
m_os = 0;
}
explicit operator bool () {
return m_os && !m_os->fail();
}
std::ostream& os() {
// The behaviour if m_os == 0 could be changed to return
// cerr or a file handle to /dev/null. The latter one would
// mimick the behaviour that one can still use a stream with
// an invalid stream, but without producing any output.
CGAL_assertion( m_os != 0 );
return *m_os;
}
private:
void header() {
os() << "#VRML V2.0 utf8\n"
"# File written with the help of the CGAL Library\n"
"#-- Begin of file header\n"
"Group {\n"
" children [\n"
" Shape {\n"
" appearance DEF A1 Appearance {\n"
" material Material {\n"
" diffuseColor .6 .5 .9\n"
" }\n }\n"
" appearance\n"
" Appearance {\n"
" material DEF Material Material {}\n"
" }\n"
" geometry nullptr\n"
" }\n"
" #-- End of file header" << std::endl;
}
void footer() {
os() << " #-- Begin of file footer\n"
" ]\n"
"}\n"
"#-- End of file footer" << std::endl;
}
std::ostream* m_os;
};
inline
VRML_2_ostream&
operator<<(VRML_2_ostream& os,
const char* s)
{
os.os() << s;
return os;
}
inline
VRML_2_ostream&
operator<<(VRML_2_ostream& os,
const double& d)
{
os.os() << d;
return os;
}
} //namespace CGAL
#endif // CGAL_IO_VRML_2_OSTREAM_H
#ifdef CGAL_TETRAHEDRON_3_H
#ifndef CGAL_IO_VRML_2_TETRAHEDRON_3
#define CGAL_IO_VRML_2_TETRAHEDRON_3
namespace CGAL {
template <class R >
VRML_2_ostream&
operator<<(VRML_2_ostream& os,
const Tetrahedron_3<R > &t)
{
const char *Indent = " ";
os << " Group {\n"
" children [\n"
" Shape {\n"
" appearance\n"
" Appearance {\n"
" material USE Material\n"
" } #Appearance\n"
" geometry\n"
" IndexedFaceSet {\n"
" coord Coordinate {\n"
" point [ \n"
<< Indent << " "
<< CGAL::to_double(t[0].x()) << " "
<< CGAL::to_double(t[0].y()) << " "
<< CGAL::to_double(t[0].z()) << " ,\n"
<< Indent << " "
<< CGAL::to_double(t[1].x()) << " "
<< CGAL::to_double(t[1].y()) << " "
<< CGAL::to_double(t[1].z()) << " ,\n"
<< Indent << " "
<< CGAL::to_double(t[2].x()) << " "
<< CGAL::to_double(t[2].y()) << " "
<< CGAL::to_double(t[2].z()) << " ,\n"
<< Indent << " "
<< CGAL::to_double(t[3].x()) << " "
<< CGAL::to_double(t[3].y()) << " "
<< CGAL::to_double(t[3].z()) <<
"\n ]\n"
" }\n"
" solid FALSE\n"
<< Indent << "coordIndex [ 0,1,2,-1, 1,3,2,-1,\n"
<< Indent << " 0,2,3,-1, 0,3,1,-1 ]\n"
" } #IndexedFaceSet\n"
" } #Shape\n"
" ] #children\n"
" } #Group\n";
return os;
}
} //namespace CGAL
#endif // CGAL_IO_VRML_2_TETRAHEDRON_3
#endif // CGAL_TETRAHEDRON_3_H
#ifdef CGAL_POINT_3_H
#ifndef CGAL_IO_VRML_2_POINT_3
#define CGAL_IO_VRML_2_POINT_3
namespace CGAL {
template <class R >
VRML_2_ostream&
operator<<(VRML_2_ostream& os,
const Point_3<R > &p)
{
const char *Indent = " ";
os << " Group {\n"
" children [\n"
" Shape {\n"
" appearance USE A1\n"
" geometry\n"
" PointSet {\n"
" coord Coordinate {\n"
" point [ ";
os << CGAL::to_double(p.x()) << " " << CGAL::to_double(p.y())
<< " " << CGAL::to_double(p.z()) << " ]\n";
os << Indent << "}\n";
os << Indent << "} # PointSet\n";
os << " } #Shape\n"
" ] #children\n"
" } #Group\n";
return os;
}
} //namespace CGAL
#endif // CGAL_IO_VRML_2_POINT_3
#endif // CGAL_POINT_3_H
#ifdef CGAL_TRIANGLE_3_H
#ifndef CGAL_IO_VRML_2_TRIANGLE_3
#define CGAL_IO_VRML_2_TRIANGLE_3
namespace CGAL {
template <class R >
VRML_2_ostream&
operator<<(VRML_2_ostream& os,
const Triangle_3<R > &t)
{
const char *Indent = " ";
os << " Group {\n"
" children [\n"
" Shape {\n"
" appearance USE A1\n"
" geometry\n"
" IndexedLineSet {\n"
" coord Coordinate {\n"
" point [ \n";
os << Indent ;
os << CGAL::to_double(t[0].x()) << " " << CGAL::to_double(t[0].y())
<< " " << CGAL::to_double(t[0].z()) << ",\n";
os << Indent;
os << CGAL::to_double(t[1].x()) << " " << CGAL::to_double(t[1].y())
<< " " << CGAL::to_double(t[1].z()) << ",\n";
os << Indent;
os << CGAL::to_double(t[2].x()) << " " << CGAL::to_double(t[2].y())
<< " " << CGAL::to_double(t[2].z()) << " ]\n";
os << Indent << "}\n" << Indent << "coordIndex [ 0 1, 1 2, 2 0 -1 ]\n";
os << Indent << "} # IndexedLineSet\n";
os << " } #Shape\n"
" ] #children\n"
" } #Group\n";
return os;
}
} //namespace CGAL
#endif // CGAL_IO_VRML_2_TRIANGLE_3
#endif // CGAL_TRIANGLE_3_H
#ifdef CGAL_SEGMENT_3_H
#ifndef CGAL_IO_VRML_2_SEGMENT_3
#define CGAL_IO_VRML_2_SEGMENT_3
namespace CGAL {
template <class R >
VRML_2_ostream&
operator<<(VRML_2_ostream& os,
const Segment_3<R > &s)
{
const char *Indent = " ";
os << " Group {\n"
" children [\n"
" Shape {\n"
" appearance USE A1\n"
" geometry\n"
" IndexedLineSet {\n"
" coord Coordinate {\n"
" point [ \n";
os << Indent << CGAL::to_double(s.source().x());
os << " " << CGAL::to_double(s.source().y())
<< " " << CGAL::to_double(s.source().z()) << ",\n";
os << Indent;
os << CGAL::to_double(s.target().x())
<< " " << CGAL::to_double(s.target().y())
<< " " << CGAL::to_double(s.target().z()) << " ]\n";
os << Indent << "}\n" << Indent << "coordIndex [ 0 1 -1 ]\n";
os << Indent << "} # IndexedLineSet\n";
os << " } #Shape\n"
" ] #children\n"
" } #Group\n";
return os;
}
} //namespace CGAL
#define CGAL_DEPRECATED_HEADER "<CGAL/IO/VRML_2_ostream.h>"
#define CGAL_REPLACEMENT_HEADER "<CGAL/IO/VRML/VRML_2_ostream.h>"
#include <CGAL/internal/deprecation_warning.h>
#include <CGAL/IO/VRML/VRML_2_ostream.h>
#include <CGAL/enable_warnings.h>
#endif // CGAL_IO_VRML_2_SEGMENT_3
#endif // CGAL_SEGMENT_3_H
#ifdef CGAL_SPHERE_3_H
#ifndef CGAL_IO_VRML_2_SPHERE_3
#define CGAL_IO_VRML_2_SPHERE_3
namespace CGAL {
template <class R >
VRML_2_ostream&
operator<<(VRML_2_ostream& os,
const Sphere_3<R > &s)
{
os << " Group {\n"
" children [\n"
" Transform {\n"
" translation ";
os << CGAL::to_double(s.center().x()) << " "
<< CGAL::to_double(s.center().y()) << " "
<< CGAL::to_double(s.center().z()) << "\n";
os << " children Shape {\n"
" appearance USE A1\n"
" geometry\n"
" Sphere { "
"radius ";
os << std::sqrt(CGAL::to_double(s.squared_radius())) <<" }\n";
os << " } #children Shape\n"
" } # Transform\n"
" ] #children\n"
" } #Group\n";
return os;
}
} //namespace CGAL
#endif // CGAL_IO_VRML_2_SEGMENT_3
#endif // CGAL_SPHERE_3_H

View File

@ -327,7 +327,9 @@ in the Reference Manual.
\cgalExample{Mesh_2/mesh_optimization.cpp}
\section secMesh_2_IO Input/Output
It is possible to export the result of a meshing in VTU, using the function `write_vtu()`.
For more information about this format, see \ref IOStreamVTK.
*/
} /* namespace CGAL */

View File

@ -0,0 +1,13 @@
namespace CGAL{
/**
* \ingroup PkgMesh3IOFunctions
* @brief outputs mesh to avizo format
* @param os the stream
* @param c3t3 the mesh complex
* \see \ref IOStreamAvizo
*/
template <class C3T3>
void
output_to_avizo(std::ostream& os,
const C3T3& c3t3);
}

View File

@ -0,0 +1,19 @@
namespace CGAL{
/**
* \ingroup PkgMesh3IOFunctions
* @brief outputs a mesh complex to tetgen format
* @param filename the path to the output file
* @param c3t3 the mesh
* @param rebind if true, labels of cells are rebinded into [1..nb_of_labels]
* @param show_patches if true, patches are labeled with different labels than
* cells. If false, each surface facet is written twice, using label of
* each adjacent cell.
* \see \ref IOStreamTetgen
*/
template <class C3T3>
void
output_to_tetgen(std::string filename,
const C3T3& c3t3,
bool rebind = false,
bool show_patches = false);
}

View File

@ -547,6 +547,15 @@ To control the number of threads used, the user may use the tbb::task_scheduler_
See the <a href="https://www.threadingbuildingblocks.org/documentation">TBB documentation</a>
for more details.
\section Mesh_3_section_io Input/Output
Several formats are supported for writing a mesh:
- VTU, with `CGAL::output_to_vtu()`
- Avizo with `CGAL::output_to_avizo()`
- Medit with `CGAL::output_to_medit()`
- Tetgen with `CGAL::output_to_tetgen()`
\section Mesh_3_section_examples Examples
\subsection Mesh_33DDomainsBoundedbyIsosurfaces 3D Domains Bounded by Isosurfaces

View File

@ -146,6 +146,7 @@ output_to_avizo(std::ostream& os,
* @brief outputs mesh to avizo format
* @param os the stream
* @param c3t3 the mesh
* \see \ref IOStreamAvizo
*/
template <class C3T3>
void

View File

@ -25,11 +25,6 @@
#include <sstream>
namespace CGAL {
//-------------------------------------------------------
// IO functions
//-------------------------------------------------------
template <class C3T3>
void
output_to_maya(std::ostream& os,

View File

@ -869,6 +869,7 @@ output_to_medit(std::ostream& os,
* @param show_patches if true, patches are labeled with different labels than
* cells. If false, each surface facet is written twice, using label of
* each adjacent cell.
* \see \ref IOStreamMedit
*/
template <class C3T3>
void

View File

@ -128,7 +128,7 @@ output_to_tetgen(std::string filename,
// Elements
//-------------------------------------------------------
std::string elem_filename = filename + ".elem";
std::string elem_filename = filename + ".ele";
std::ofstream elem_stream(elem_filename.c_str());
elem_stream << std::setprecision(17);
@ -189,15 +189,6 @@ output_to_tetgen(std::string filename,
/**
* @brief outputs mesh to tetgen format
* @param os the stream
* @param c3t3 the mesh
* @param rebind if true, labels of cells are rebinded into [1..nb_of_labels]
* @param show_patches if true, patches are labeled with different labels than
* cells. If false, each surface facet is written twice, using label of
* each adjacent cell.
*/
template <class C3T3>
void
output_to_tetgen(std::string filename,

View File

@ -240,6 +240,8 @@ container.
\cgalExample{Point_set_processing_3/read_las_example.cpp}
\sa \ref IOstreamPointSetIO
\section Point_set_processing_3Spacing Average Spacing
Function `compute_average_spacing()` computes the average

View File

@ -44,7 +44,7 @@ if (VTK_FOUND)
polyhedron_demo_plugin(vtk_plugin VTK_io_plugin KEYWORDS IO Mesh_3)
target_link_libraries(vtk_plugin PUBLIC scene_surface_mesh_item scene_polylines_item scene_c3t3_item scene_points_with_normal_item
${VTK_LIBRARIES})
target_compile_definitions(vtk_plugin PRIVATE -DCGAL_USE_VTK)
else()
message(STATUS "NOTICE : the vtk IO plugin needs VTK libraries and will not be compiled.")
endif()

View File

@ -3,12 +3,12 @@
#include "Kernel_type.h"
#include "Scene.h"
#include "SMesh_type.h"
#include <CGAL/gocad_io.h>
#include <CGAL/Timer.h>
#include <CGAL/Three/Polyhedron_demo_io_plugin_interface.h>
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
#include <CGAL/Three/Polyhedron_demo_plugin_helper.h>
#include <CGAL/Three/Three.h>
#include <CGAL/boost/graph/io.h>
#include <fstream>
#include <QColor>

View File

@ -8,8 +8,8 @@
#include <CGAL/Three/Three.h>
#include <fstream>
#include <CGAL/IO/Polyhedron_builder_from_STL.h>
#include <CGAL/IO/STL_writer.h>
#include <CGAL/IO/STL_reader.h>
#include <CGAL/boost/graph/io.h>
#include <CGAL/Polygon_mesh_processing/polygon_soup_to_polygon_mesh.h>

View File

@ -39,6 +39,7 @@
#include <CGAL/IO/Complex_3_in_triangulation_3_to_vtk.h>
#include <CGAL/Mesh_3/tet_soup_to_c3t3.h>
#include <CGAL/IO/output_to_vtu.h>
#include <CGAL/IO/VTK/vtk_internals.h>
#include <CGAL/boost/graph/io.h>
#include <vtkSmartPointer.h>
@ -79,98 +80,6 @@ CGAL::vertex_point_t>::type>::value_type Point;
namespace CGAL{
class ErrorObserverVtk : public vtkCommand
{
public:
ErrorObserverVtk() :
Error(false),
Warning(false),
ErrorMessage(""),
WarningMessage("") {}
static ErrorObserverVtk *New() { return new ErrorObserverVtk; }
bool GetError() const { return this->Error; }
bool GetWarning() const { return this->Warning; }
std::string GetErrorMessage() { return ErrorMessage; }
std::string GetWarningMessage() { return WarningMessage; }
void Clear()
{
this->Error = false;
this->Warning = false;
this->ErrorMessage = "";
this->WarningMessage = "";
}
virtual void Execute(vtkObject *vtkNotUsed(caller),
unsigned long event,
void *calldata)
{
switch (event)
{
case vtkCommand::ErrorEvent:
ErrorMessage = static_cast<char *>(calldata);
this->Error = true;
break;
case vtkCommand::WarningEvent:
WarningMessage = static_cast<char *>(calldata);
this->Warning = true;
break;
}
}
private:
bool Error;
bool Warning;
std::string ErrorMessage;
std::string WarningMessage;
};
template <typename TM>
bool vtkPointSet_to_polygon_mesh(vtkPointSet* poly_data,
TM& tmesh)
{
typedef typename boost::property_map<TM, CGAL::vertex_point_t>::type VPMap;
typedef typename boost::property_map_value<TM, CGAL::vertex_point_t>::type Point_3;
typedef typename boost::graph_traits<TM>::vertex_descriptor vertex_descriptor;
VPMap vpmap = get(CGAL::vertex_point, tmesh);
// get nb of points and cells
vtkIdType nb_points = poly_data->GetNumberOfPoints();
vtkIdType nb_cells = poly_data->GetNumberOfCells();
//extract points
std::vector<vertex_descriptor> vertex_map(nb_points);
for (vtkIdType i = 0; i<nb_points; ++i)
{
double coords[3];
poly_data->GetPoint(i, coords);
vertex_descriptor v = add_vertex(tmesh);
put(vpmap, v, Point_3(coords[0], coords[1], coords[2]));
vertex_map[i]=v;
}
//extract cells
for (vtkIdType i = 0; i<nb_cells; ++i)
{
if(poly_data->GetCellType(i) != 5
&& poly_data->GetCellType(i) != 7
&& poly_data->GetCellType(i) != 9) //only supported cells are triangles, quads and polygons
continue;
vtkCell* cell_ptr = poly_data->GetCell(i);
vtkIdType nb_vertices = cell_ptr->GetNumberOfPoints();
if (nb_vertices < 3)
return false;
std::vector<vertex_descriptor> vr(nb_vertices);
for (vtkIdType k=0; k<nb_vertices; ++k)
vr[k]=vertex_map[cell_ptr->GetPointId(k)];
CGAL::Euler::add_face(vr, tmesh);
}
return true;
}
template <class Point_3>
void extract_segments_from_vtkPointSet(vtkPointSet* poly_data,
@ -354,19 +263,6 @@ public:
bool canLoad(QFileInfo) const { return true; }
template <class vtkReader>
vtkSmartPointer<vtkReader>
read_vtk_file(const std::string& input_filename,
vtkSmartPointer<CGAL::ErrorObserverVtk> errorObserver)
{
vtkSmartPointer<vtkReader> reader = vtkSmartPointer<vtkReader>::New();
reader->AddObserver(vtkCommand::ErrorEvent, errorObserver);
reader->AddObserver(vtkCommand::WarningEvent, errorObserver);
reader->SetFileName(input_filename.data());
reader->Update();
return reader;
}
QList<Scene_item*> load(QFileInfo fileinfo, bool& ok, bool add_to_scene)
{
std::string extension=fileinfo.suffix().toLower().toStdString();
@ -392,20 +288,21 @@ public:
}
vtkSmartPointer<vtkPointSet> data;
vtkSmartPointer<CGAL::ErrorObserverVtk> obs =
vtkSmartPointer<CGAL::ErrorObserverVtk>::New();
vtkSmartPointer<CGAL::VTK_internal::ErrorObserverVtk> obs =
vtkSmartPointer<CGAL::VTK_internal::ErrorObserverVtk>::New();
if (extension=="vtp")
data = read_vtk_file<vtkXMLPolyDataReader>(fname,obs)
data = CGAL::VTK_internal::read_vtk_file<vtkXMLPolyDataReader>(fname,obs)
->GetOutput();
else
if (extension=="vtu")
data = read_vtk_file<vtkXMLUnstructuredGridReader>(fname,obs)
data = CGAL::VTK_internal::
read_vtk_file<vtkXMLUnstructuredGridReader>(fname,obs)
->GetOutput();
else{
//read non-XML data
vtkSmartPointer<vtkDataSetReader> reader =
read_vtk_file<vtkDataSetReader>(fname,obs);
CGAL::VTK_internal::read_vtk_file<vtkDataSetReader>(fname,obs);
data = vtkPolyData::SafeDownCast(reader->GetOutput());
if (!data)
data = vtkUnstructuredGrid::SafeDownCast(reader->GetOutput());
@ -433,28 +330,6 @@ public:
msgBox.setIcon(QMessageBox::Warning);
msgBox.exec();
}
if (obs->GetError())
{
QMessageBox msgBox;
msgBox.setText("This type of data can't be opened");
msgBox.setInformativeText(QString("VTK error message :\n")
.append(QString(obs->GetErrorMessage().data())));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setIcon(QMessageBox::Critical);
msgBox.exec();
ok = false;
return QList<Scene_item*>();
}
if (obs->GetWarning())
{
QMessageBox msgBox;
msgBox.setText("This file generates a warning");
msgBox.setInformativeText(QString("VTK warning message :\n")
.append(QString(obs->GetWarningMessage().data())));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setIcon(QMessageBox::Warning);
msgBox.exec();
}
//check celltypes
bool is_polygon_mesh(false),
@ -481,7 +356,7 @@ public:
if(is_polygon_mesh)
{
FaceGraph* poly = new FaceGraph();
if (CGAL::vtkPointSet_to_polygon_mesh(data, *poly))
if (CGAL::VTK_internal::vtkPointSet_to_polygon_mesh(data, *poly))
{
Scene_facegraph_item* poly_item = new Scene_facegraph_item(poly);
if(group)

View File

@ -44,6 +44,7 @@
#include <CGAL/Three/Edge_container.h>
#include <CGAL/Three/Point_container.h>
#include <CGAL/Three/Three.h>
#include <CGAL/boost/graph/io.h>
#include <CGAL/Buffer_for_vao.h>
#include <QMenu>
@ -1491,12 +1492,15 @@ bool
Scene_surface_mesh_item::load_obj(std::istream& in)
{
typedef SMesh::Point Point;
bool failed = !CGAL::read_OBJ(*d->smesh_, in);
if(failed){
std::vector<Point> points;
std::vector<std::vector<std::size_t> > faces;
bool failed = !CGAL::read_OBJ(in,points,faces);
failed = !CGAL::read_OBJ(in,points,faces);
CGAL::Polygon_mesh_processing::orient_polygon_soup(points,faces);
CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(points,faces,*(d->smesh_));
}
if ( (! failed) && !isEmpty() )
{
invalidate(ALL);
@ -1508,9 +1512,8 @@ Scene_surface_mesh_item::load_obj(std::istream& in)
bool
Scene_surface_mesh_item::save_obj(std::ostream& out) const
{
CGAL::File_writer_wavefront writer;
CGAL::generic_print_surface_mesh(out, *(d->smesh_), writer);
return out.good();
return CGAL::write_OBJ(*d->smesh_, out);
}
void

View File

@ -1,163 +0,0 @@
#ifndef CGAL_GOCAD_IO_H
#define CGAL_GOCAD_IO_H
#include <deque>
#include <iostream>
#include <string>
#include <CGAL/Modifier_base.h>
#include <CGAL/Polyhedron_incremental_builder_3.h>
#include <boost/tuple/tuple.hpp>
#include <iostream>
template <class Facegraph, class P>
class Build_from_gocad_BGL
{
typedef P Point_3;
typedef std::deque<Point_3> Points_3;
typedef boost::tuple<int,int,int> Facet;
typedef std::deque<Facet> Surface;
std::istream& is;
int counter;
Points_3 meshPoints;
Surface mesh;
public:
std::string name, color;
Build_from_gocad_BGL(std::istream& is_)
: is(is_), counter(0)
{}
void operator()( Facegraph& graph) {
read(is, meshPoints, mesh);
// graph.begin_surface( meshPoints.size(), mesh.size());
typedef typename Points_3::size_type size_type;
for(size_type i=0; i < mesh.size(); i++){
std::array<typename boost::graph_traits<Facegraph>::vertex_descriptor, 3> face;
face[0] = add_vertex( meshPoints[mesh[i].template get<0>()],graph);
face[1] = add_vertex( meshPoints[mesh[i].template get<1>()],graph);
face[2] = add_vertex( meshPoints[mesh[i].template get<2>()],graph);
CGAL::Euler::add_face(face, graph);
}
}
void
read(std::istream& input, Points_3& points, Surface& surface, int offset = 0)
{
char c;
std::string s, tface("TFACE");
int i,j,k;
Point_3 p;
bool vertices_read = false;
while(input >> s){
if(s == tface){
break;
}
std::string::size_type idx;
if((idx = s.find("name")) != std::string::npos){
std::istringstream str(s.substr(idx+5));
str >> name;
}
if((idx = s.find("color")) != std::string::npos){
std::istringstream str(s.substr(idx+6));
str >> color;
}
}
std::getline(input, s);
while(input.get(c)){
if((c == 'V')||(c == 'P')){
input >> s >> i >> p;
if(! vertices_read){
vertices_read = true;
offset -= i; // Some files start with index 0 others with 1
}
points.push_back(p);
} else if(vertices_read && (c == 'T')){
input >> c >> c >> c >> i >> j >> k;
surface.push_back(boost::make_tuple(offset+i, offset+j, offset+k));
} else if(c == 'E'){
break;
}
std::getline(input, s);
}
}
};
template <typename FaceGraph>
bool
read_gocad(FaceGraph& polyhedron, std::istream& in, std::string& name, std::string& color)
{
//typedef typename Polyhedron::HalfedgeDS HDS;
typedef typename boost::property_traits<typename boost::property_map<FaceGraph, CGAL::vertex_point_t>::type>::value_type Point_3;
Build_from_gocad_BGL<FaceGraph, Point_3> builder(in);
builder(polyhedron);
name=builder.name;
color=builder.color;
return in.good() && polyhedron.is_valid();
}
template <typename FaceGraph>
bool
write_gocad(FaceGraph& polyhedron, std::ostream& os, const std::string& name)
{
os << "GOCAD TSurf 1\n"
"HEADER {\n"
"name:";
os << name << std::endl;
os << "*border:on\n"
"*border*bstone:on\n"
"}\n"
"GOCAD_ORIGINAL_COORDINATE_SYSTEM\n"
"NAME Default\n"
"AXIS_NAME \"X\" \"Y\" \"Z\"\n"
"AXIS_UNIT \"m\" \"m\" \"m\"\n"
"ZPOSITIVE Elevation\n"
"END_ORIGINAL_COORDINATE_SYSTEM\n"
"TFACE\n";
os.precision(16);
typedef typename boost::property_map<FaceGraph, CGAL::vertex_point_t>::type VPMap;
VPMap vpmap = get(CGAL::vertex_point, polyhedron);
std::map<typename boost::graph_traits<FaceGraph>::vertex_descriptor, int> id_map;
{
typename boost::graph_traits<FaceGraph>::vertex_iterator it, end;
it = vertices(polyhedron).begin();
end = vertices(polyhedron).end();
int i=0;
for(; it != end; ++it){
id_map[*it] = i;
os << "VRTX " << i << " " << get(vpmap, *it) << "\n";
++i;
}
}
{
typename boost::graph_traits<FaceGraph>::face_iterator it, end;
it = faces(polyhedron).begin();
end = faces(polyhedron).end();
for(; it != end; ++it){
os << "TRGL " << id_map[target(prev(halfedge(*it, polyhedron), polyhedron), polyhedron)] << " "
<< id_map[target(halfedge(*it, polyhedron), polyhedron)] << " "
<< id_map[target(next(halfedge(*it, polyhedron), polyhedron), polyhedron)] << "\n";
}
}
os << "END" << std::endl;
return true;
}
#endif // CGAL_GOCAD_IO_H

View File

@ -363,6 +363,9 @@ restrictions on these formats. They must represent a permissible
polyhedral surface, e.g., a 2-manifold and no isolated vertices, see
Section \ref sectionPolyIntro.
For more information, you can see the \ref IOstreamPolygonMeshIO
section.
Some example programs around the different file formats are provided
in the distribution under <TT>examples/Polyhedron_IO/</TT> and
<TT>demo/Polyhedron_IO/</TT>. We show an example converting OFF input

View File

@ -11,6 +11,8 @@
#ifndef CGAL_IO_POLYHEDRON_STL_BUILDER_H
#define CGAL_IO_POLYHEDRON_STL_BUILDER_H
#include <CGAL/license/Polyhedron.h>
#include <CGAL/Modifier_base.h>
#include <CGAL/Polyhedron_incremental_builder_3.h>
#include <CGAL/IO/STL_reader.h>

View File

@ -18,8 +18,8 @@
#include <CGAL/disable_warnings.h>
#include <CGAL/basic.h>
#include <CGAL/IO/File_header_OFF.h>
#include <CGAL/IO/File_scanner_OFF.h>
#include <CGAL/IO/OFF/File_header_OFF.h>
#include <CGAL/IO/OFF/File_scanner_OFF.h>
#include <CGAL/Modifier_base.h>
#include <CGAL/Polyhedron_incremental_builder_3.h>
#include <CGAL/Polyhedron_3.h>

View File

@ -17,7 +17,7 @@
#include <CGAL/basic.h>
#include <CGAL/IO/File_writer_OFF.h>
#include <CGAL/IO/OFF/File_writer_OFF.h>
#include <CGAL/IO/generic_print_polyhedron.h>
#include <CGAL/Polyhedron_3.h>
#include <iostream>

View File

@ -16,7 +16,7 @@
#include <CGAL/license/Polyhedron.h>
#include <CGAL/IO/File_writer_wavefront.h>
#include <CGAL/IO/OBJ/File_writer_wavefront.h>
#include <CGAL/IO/generic_print_polyhedron.h>
#include <CGAL/Polyhedron_3.h>
#include <iostream>

View File

@ -1,27 +0,0 @@
# Created by the script cgal_create_cmake_script
# This is the CMake script for compiling a CGAL application.
cmake_minimum_required(VERSION 3.1...3.15)
project( Polyhedron_IO_Demo )
if(NOT POLICY CMP0070 AND POLICY CMP0053)
# Only set CMP0053 to OLD with CMake<3.10, otherwise there is a warning.
cmake_policy(SET CMP0053 OLD)
endif()
set_property(DIRECTORY PROPERTY CGAL_NO_TESTING TRUE)
find_package(CGAL QUIET)
if ( CGAL_FOUND )
create_single_source_cgal_program( "geomview_demo.cpp" )
create_single_source_cgal_program( "viewpoint2off.cpp" )
else()
message(STATUS "This program requires the CGAL library, and will not be compiled.")
endif()

View File

@ -1,18 +0,0 @@
demo/Polyhedron_IO/README
-------------------------
viewpoint2off.C
A demo program that converts geometry files in Viewpoint
Data Labs mesh format into OFF files. Type 'make viewpoint2off'
to compile it. See http://www.viewpoint.com/
It is in the demo directory since no viewpoint example
data is provided.
geomview_demo.C
Displays a polyhedron from CGAL in Geomview using
CGAL::Geomview_stream. Type 'make geomview_demo' to compile it.
Lutz Kettner

View File

@ -1,49 +0,0 @@
// Copyright (c) 2002 Max Planck Institut fuer Informatik (Germany).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Lutz Kettner
#include <CGAL/basic.h>
#ifdef _MSC_VER
#include <iostream>
int main() {
std::cout << "Geomview doesn't work on Windows, so no demo." << std::endl;
return 0;
}
#else // can have Geomeview
#include <CGAL/Cartesian.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/IO/Polyhedron_geomview_ostream.h>
typedef CGAL::Cartesian<double> Kernel;
typedef Kernel::Point_3 Point;
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
int main() {
Point p( 1.0, 0.0, 0.0);
Point q( 0.0, 1.0, 0.0);
Point r( 0.0, 0.0, 1.0);
Point s( 0.0, 0.0, 0.0);
Polyhedron P;
P.make_tetrahedron( p,q,r,s);
CGAL::Geomview_stream geo;
geo << CGAL::green() << P;
// wait for a mouse click.
Point click;
geo >> click;
return 0;
}
#endif

View File

@ -1,348 +0,0 @@
// Copyright (c) 2002 Max Planck Institut fuer Informatik (Germany).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Lutz Kettner
// Copies from Viewpoint ASCII format into OFF format.
// ============================================================================
#include <CGAL/Cartesian.h>
#include <CGAL/IO/Verbose_ostream.h>
#include <CGAL/IO/binary_file_io.h>
#include <CGAL/IO/File_writer_OFF.h>
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <fstream>
#include <vector>
#include <boost/cstdint.hpp>
using namespace std;
typedef CGAL::Cartesian<float> Kernel;
typedef Kernel::Point_3 Point;
typedef vector<Point> Point_vector;
typedef vector<std::size_t> Facet;
typedef vector<Facet> Facet_vector;
bool verbose = false;
bool binary = false;
bool skel = false;
bool noc = false;
bool binary_mesh = false;
bool ascii_mesh = false;
bool normals_file = false;
bool no_normals = false;
const char* normals_filename = 0;
// main function with standard unix commandline arguments
// ------------------------------------------------------
int main( int argc, char **argv) {
#if CGAL_CFG_INCOMPLETE_TYPE_BUG_5
Point _work_around_incomplete_type;
#endif // CGAL_CFG_INCOMPLETE_TYPE_BUG_5
int n = 0;
char *filename[3];
bool help = false;
for ( int i = 1; i < argc; i++) {
// check commandline options
if ( strcmp( "-v", argv[i]) == 0)
verbose = true;
else if ( strcmp( "-b", argv[i]) == 0)
binary = true;
else if ( strcmp( "-skel", argv[i]) == 0)
skel = true;
else if ( strcmp( "-noc", argv[i]) == 0)
noc = true;
else if ( strcmp( "-mesh", argv[i]) == 0)
binary_mesh = true;
else if ( strcmp( "-ascii", argv[i]) == 0)
ascii_mesh = true;
else if ( strcmp( "-no_normals", argv[i]) == 0)
no_normals = true;
else if ( strcmp( "-normals", argv[i]) == 0) {
normals_file = true;
i++;
if ( i < argc) {
normals_filename = argv[i];
} else {
cerr << argv[0] << ": error: -normals need a filename as "
"parameter." << endl;
help = true;
}
} else if ( (strcmp( "-h", argv[i]) == 0) ||
(strcmp( "-help", argv[i]) == 0))
help = true;
else if ( n < 3 ) {
filename[n ++] = argv[i];
} else {
++n;
break;
}
}
if ((n < 1) || (n > 3) || help) {
if ( ! help)
cerr << "Error: in parameter list" << endl;
cerr << "Usage: " << argv[0]
<< " [<options>] <infile.coo> <infile.ele> [<outfile>]" << endl;
cerr << " or: " << argv[0]
<< " [<options>] <infile.msh> [<outfile>]" << endl;
cerr << " convert an object from Viewpoint formats into OFF."
<< endl;
cerr << " -mesh forces input to be read from mesh file."
<< endl;
cerr << " -ascii forces input to be read from ascii mesh file."
<< endl;
cerr << " -normals <filename> reads normals file (in "
"polygon format)." << endl;
cerr << " -no_normals ignore normals." << endl;
cerr << " -b binary output (default is ASCII)." << endl;
cerr << " -skel Geomview SKEL format." << endl;
cerr << " -noc no comments in file." << endl;
cerr << " -v verbose." << endl;
exit( ! help);
}
CGAL::Verbose_ostream vout( verbose);
vout << argv[0] << ": verbosity on." << endl;
ifstream in( filename[0]);
if ( ! in) {
cerr << argv[0] << ": error: cannot open file '"<< filename[0]
<< "' for reading." <<endl;
exit( 1);
}
Point_vector points;
Point_vector normals;
Facet_vector facets;
points.reserve( 64000); // Avoid too much reallocation
normals.reserve( 64000);
facets.reserve( 64000);
float x,y,z;
char c,d,e;
in.get(c);
if ( c < '0' && c > '9')
binary_mesh = 1;
in.putback(c);
boost::int32_t number;
if ( ! binary_mesh) {
in >> number;
if ( number != 1)
ascii_mesh = 1;
}
if ( binary_mesh) {
vout << "Scanning Viewpoint binary mesh data file ..." << endl;
CGAL::I_Binary_read_big_endian_integer32( in, number);
int tmesh = 0;
while( in) {
tmesh ++;
for ( int j = 0; j < number; j++) {
if ( j > 1) {
facets.push_back( Facet());
Facet& facet = (*(facets.end() - 1));
facet.push_back( points.size());
if (j & 1) {
facet.push_back( points.size()-2);
facet.push_back( points.size()-1);
} else {
facet.push_back( points.size()-1);
facet.push_back( points.size()-2);
}
}
// Scan vertex coordinates.
CGAL::I_Binary_read_big_endian_float32( in, x);
CGAL::I_Binary_read_big_endian_float32( in, y);
CGAL::I_Binary_read_big_endian_float32( in, z);
points.push_back( Point( x, y, z));
}
for ( int k = 0; k < number; k++) {
// Scan vertex normal.
CGAL::I_Binary_read_big_endian_float32( in, x);
CGAL::I_Binary_read_big_endian_float32( in, y);
CGAL::I_Binary_read_big_endian_float32( in, z);
if ( ! no_normals)
normals.push_back( Point( x, y, z));
}
CGAL::I_Binary_read_big_endian_integer32( in, number);
}
in.close();
vout << points.size() << " vertex coordinates read." << endl;
vout << facets.size() << " facets read." << endl;
vout << tmesh << " triangle meshes read." << endl;
} else if ( ascii_mesh) {
vout << "Scanning Viewpoint ASCII mesh data file ..." << endl;
int tmesh = 0;
while( in) {
tmesh ++;
for ( int j = 0; j < number; j++) {
if ( j > 1) {
facets.push_back( Facet());
Facet& facet = (*(facets.end() - 1));
facet.push_back( points.size());
if (j & 1) {
facet.push_back( points.size()-2);
facet.push_back( points.size()-1);
} else {
facet.push_back( points.size()-1);
facet.push_back( points.size()-2);
}
}
// Scan vertex coordinates.
in >> x >> y >> z;
points.push_back( Point( x, y, z));
}
for ( int k = 0; k < number; k++) {
// Scan vertex normal.
in >> x >> y >> z;
if ( ! no_normals)
normals.push_back( Point( x, y, z));
}
in >> number;
}
in.close();
vout << points.size() << " vertex coordinates read." << endl;
vout << facets.size() << " facets read." << endl;
vout << tmesh << " triangle meshes read." << endl;
} else {
vout << "Scanning Viewpoint polygon data files ..." << endl;
vout << " ... start with coordinates file ..." << endl;
if ( n < 2) {
cerr << argv[0] << ": error: two input filenames needed." << endl;
exit( 1);
}
while( in) {
in >> c >> x >> d >> y >> e >> z;
if ( ! in || (size_t)number != (points.size() + 1) ||
c != ',' || d != ',' || e != ',') {
cerr << argv[0] << ": error: cannot read line "
<< points.size() + 1 << " from file '" << filename[0]
<< "'." <<endl;
exit( 1);
}
points.push_back( Point( x, y, z));
in >> number;
}
in.close();
vout << points.size() << " vertex coordinates read." << endl;
if ( normals_file && ! no_normals) {
vout << " ... next is normals file ..." << endl;
in.open( normals_filename);
if ( ! in) {
cerr << argv[0] << ": error: cannot open file '"
<< normals_filename << "' for reading." <<endl;
exit( 1);
}
in >> x;
while( in) {
in >> y >> z;
if ( ! in ) {
cerr << argv[0] << ": error: cannot read line "
<< points.size() + 1 << " from file '"
<< normals_filename << "'." <<endl;
exit( 1);
}
normals.push_back( Point( x, y, z));
in >> x;
}
in.close();
vout << normals.size() << " normals read." << endl;
if ( normals.size() != points.size()) {
cerr << argv[0] << ": error: number of points and normals "
"differ." << endl;
exit( 1);
}
}
vout << " ... next is element file ..." << endl;
in.open( filename[1]);
if ( ! in) {
cerr << argv[0] << ": error: cannot open file '"<< filename[1]
<< "' for reading." <<endl;
exit( 1);
}
char part_name[16000];
in >> part_name;
while( in) {
in.get(c);
facets.push_back( Facet());
Facet& facet = (*(facets.end() - 1));
while( c == ' ') {
in >> number;
if ( number < 1 || (size_t)number > points.size()) {
cerr << argv[0] << ": error: parsing line "
<< facets.size() << " from file '" << filename[1]
<< "': index " << number << " is out of range."
<< endl;
exit( 1);
}
facet.push_back( number - 1);
in.get(c);
}
in >> part_name;
}
in.close();
vout << facets.size() << " facets read." << endl;
}
const char* oname = "cout";
ostream* p_out = &cout;
ofstream out;
if ( n > 2) {
out.open( filename[2]);
p_out = &out;
oname = filename[2];
}
if ( (ascii_mesh || binary_mesh) && n > 1) {
out.open( filename[1]);
p_out = &out;
oname = filename[1];
}
if ( !*p_out) {
cerr << argv[0] << ": error: cannot open file '"<< oname
<< "' for writing." <<endl;
exit( 1);
}
vout << "CGAL::File_writer_OFF( " << (binary ? ", binary" : ", ASCII")
<< ") ...." << endl;
CGAL::File_header_OFF header( binary, noc, skel, verbose);
CGAL::File_writer_OFF writer( header);
writer.write_header( *p_out, points.size(), 0, facets.size(),
normals.size()>0);
Point_vector::iterator norm = normals.begin();
for ( Point_vector::iterator p = points.begin(); p != points.end(); ++p) {
writer.write_vertex( (*p).x(), (*p).y(), (*p).z());
if ( normals.size()>0) {
writer.write_normal( (*norm).x(), (*norm).y(), (*norm).z());
++norm;
}
}
writer.write_facet_header();
for ( Facet_vector::iterator fc = facets.begin(); fc!=facets.end(); ++fc) {
writer.write_facet_begin( (*fc).size());
for ( Facet::iterator fi = (*fc).begin(); fi != (*fc).end(); ++fi) {
writer.write_facet_vertex_index( *fi);
}
writer.write_facet_end();
}
writer.write_footer();
vout << " .... done." << endl;
if ( !*p_out) {
cerr << argv[0] << " write error: while writing file '"<< oname
<< "'." << endl;
exit( 1);
}
return 0;
}
// EOF //

View File

@ -1,24 +0,0 @@
# Created by the script cgal_create_cmake_script
# This is the CMake script for compiling a CGAL application.
cmake_minimum_required(VERSION 3.1...3.15)
project( Polyhedron_IO_Examples )
find_package(CGAL QUIET)
if ( CGAL_FOUND )
# create a target per cppfile
file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
foreach(cppfile ${cppfiles})
create_single_source_cgal_program( "${cppfile}" )
endforeach()
else()
message(STATUS "This program requires the CGAL library, and will not be compiled.")
endif()

View File

@ -11,54 +11,13 @@
#ifndef CGAL_IO_OBJ_READER_H
#define CGAL_IO_OBJ_READER_H
#include <istream>
#include <sstream>
#include <vector>
#include <CGAL/disable_warnings.h>
#define CGAL_DEPRECATED_HEADER "<CGAL/IO/OBJ_reader.h>"
#define CGAL_REPLACEMENT_HEADER "<CGAL/IO/OBJ/OBJ_reader.h>"
#include <CGAL/internal/deprecation_warning.h>
#include <CGAL/IO/OBJ/OBJ_reader.h>
#include <CGAL/enable_warnings.h>
namespace CGAL {
template <class Point_3>
bool
read_OBJ( std::istream& input,
std::vector<Point_3> &points,
std::vector<std::vector<std::size_t> > &faces)
{
Point_3 p;
std::string line;
while(getline(input, line)) {
if(line[0] == 'v' && line[1] == ' ') {
std::istringstream iss(line.substr(1));
iss >> p;
if(!iss)
return false;
points.push_back(p);
}
else if(line[0] == 'f') {
std::istringstream iss(line.substr(1));
int i;
faces.push_back( std::vector<std::size_t>() );
while(iss >> i)
{
if(i < 1)
{
faces.back().push_back(points.size()+i);//negative indices are relative references
}
else {
faces.back().push_back(i-1);
}
iss.ignore(256, ' ');
}
}
else
{
//std::cerr<<"ERROR : Cannnot read line beginning with "<<line[0]<<std::endl;
continue;
}
}
return true;
}
} // namespace CGAL
#endif // CGAL_IO_OBJ_READER_H

View File

@ -10,131 +10,11 @@
#ifndef CGAL_IO_OFF_READER_H
#define CGAL_IO_OFF_READER_H
#include <CGAL/disable_warnings.h>
#include <CGAL/IO/File_scanner_OFF.h>
#include <CGAL/IO/reader_helpers.h>
#include <vector>
#include <iostream>
#include <CGAL/array.h>
#include <CGAL/assertions.h>
#include <CGAL/use.h>
namespace CGAL {
template <class Point_3, class Polygon_3>
bool
read_OFF( std::istream& in,
std::vector< Point_3 >& points,
std::vector< Polygon_3 >& polygons,
bool /* verbose */ = false)
{
CGAL::File_scanner_OFF scanner(in);
points.resize(scanner.size_of_vertices());
polygons.resize(scanner.size_of_facets());
for (std::size_t i = 0; i < scanner.size_of_vertices(); ++i) {
double x, y, z, w;
scanner.scan_vertex( x, y, z, w);
CGAL_assertion(w!=0);
IO::internal::fill_point( x/w, y/w, z/w, points[i] );
scanner.skip_to_next_vertex( i);
}
if(!in)
return false;
for (std::size_t i = 0; i < scanner.size_of_facets(); ++i) {
std::size_t no;
scanner.scan_facet( no, i);
IO::internal::resize(polygons[i], no);
for(std::size_t j = 0; j < no; ++j) {
std::size_t id;
scanner.scan_facet_vertex_index(id, i);
if(id < scanner.size_of_vertices())
{
polygons[i][j] = id;
}
else
return false;
}
}
return in.good();
}
template <class Point_3, class Polygon_3, class Color_rgb >
bool
read_OFF( std::istream& in,
std::vector< Point_3 >& points,
std::vector< Polygon_3 >& polygons,
std::vector<Color_rgb>& fcolors,
std::vector<Color_rgb>& vcolors,
bool /* verbose */ = false)
{
CGAL::File_scanner_OFF scanner(in);
points.resize(scanner.size_of_vertices());
polygons.resize(scanner.size_of_facets());
if(scanner.has_colors())
vcolors.resize(scanner.size_of_vertices());
for (std::size_t i = 0; i < scanner.size_of_vertices(); ++i) {
double x, y, z, w;
scanner.scan_vertex( x, y, z, w);
CGAL_assertion(w!=0);
IO::internal::fill_point( x/w, y/w, z/w, points[i] );
if(scanner.has_colors())
{
unsigned char r=0, g=0, b=0;
scanner.scan_color( r, g, b);
vcolors[i] = Color_rgb(r,g,b);
}
else
scanner.skip_to_next_vertex(i);
if(!in)
return false;
}
bool has_fcolors = false;
for (std::size_t i = 0; i < scanner.size_of_facets(); ++i) {
std::size_t no;
scanner.scan_facet( no, i);
if(!in)
return false;
IO::internal::resize(polygons[i], no);
for(std::size_t j = 0; j < no; ++j) {
std::size_t id;
scanner.scan_facet_vertex_index(id, i);
if(id < scanner.size_of_vertices())
{
polygons[i][j] = id;
}
else
{
return false;
}
}
if(i==0)
{
std::string col;
std::getline(in, col);
std::istringstream iss(col);
char ci =' ';
if(iss >> ci){
has_fcolors = true;
fcolors.resize(scanner.size_of_facets());
std::istringstream iss2(col);
fcolors[i] = scanner.get_color_from_line(iss2);
}
}
else if(has_fcolors)
{
unsigned char r=0, g=0, b=0;
scanner.scan_color(r,g,b);
fcolors[i] = Color_rgb(r,g,b);
}
}
return in.good();
}
} // namespace CGAL
#define CGAL_DEPRECATED_HEADER "<CGAL/IO/OFF_reader.h>"
#define CGAL_REPLACEMENT_HEADER "<CGAL/IO/OFF.h>"
#include <CGAL/internal/deprecation_warning.h>
#include <CGAL/IO/OFF.h>
#include <CGAL/enable_warnings.h>
#endif // CGAL_IO_OFF_READER_H

View File

@ -13,327 +13,12 @@
#include <CGAL/IO/PLY.h>
namespace CGAL{
#include <CGAL/disable_warnings.h>
namespace internal
{
template <typename Integer, class Polygon_3, class Color_rgb>
bool
read_PLY_faces (std::istream& in,
internal::PLY::PLY_element& element,
std::vector< Polygon_3 >& polygons,
std::vector< Color_rgb >& fcolors,
const char* vertex_indices_tag)
{
bool has_colors = false;
std::string rtag = "r", gtag = "g", btag = "b";
if ((element.has_property<boost::uint8_t>("red") || element.has_property<boost::uint8_t>("r")) &&
(element.has_property<boost::uint8_t>("green") || element.has_property<boost::uint8_t>("g")) &&
(element.has_property<boost::uint8_t>("blue") || element.has_property<boost::uint8_t>("b")))
{
has_colors = true;
if (element.has_property<boost::uint8_t>("red"))
{
rtag = "red"; gtag = "green"; btag = "blue";
}
}
for (std::size_t j = 0; j < element.number_of_items(); ++ j)
{
for (std::size_t k = 0; k < element.number_of_properties(); ++ k)
{
internal::PLY::PLY_read_number* property = element.property(k);
property->get (in);
if (in.fail())
return false;
}
std::tuple<std::vector<Integer>, boost::uint8_t, boost::uint8_t, boost::uint8_t> new_face;
if (has_colors)
{
PLY::process_properties (element, new_face,
std::make_pair (CGAL::make_nth_of_tuple_property_map<0>(new_face),
PLY_property<std::vector<Integer> >(vertex_indices_tag)),
std::make_pair (CGAL::make_nth_of_tuple_property_map<1>(new_face),
PLY_property<boost::uint8_t>(rtag.c_str())),
std::make_pair (CGAL::make_nth_of_tuple_property_map<2>(new_face),
PLY_property<boost::uint8_t>(gtag.c_str())),
std::make_pair (CGAL::make_nth_of_tuple_property_map<3>(new_face),
PLY_property<boost::uint8_t>(btag.c_str())));
fcolors.push_back (Color_rgb (get<1>(new_face), get<2>(new_face), get<3>(new_face)));
}
else
PLY::process_properties (element, new_face,
std::make_pair (CGAL::make_nth_of_tuple_property_map<0>(new_face),
PLY_property<std::vector<Integer> >(vertex_indices_tag)));
polygons.push_back (Polygon_3(get<0>(new_face).size()));
for (std::size_t i = 0; i < get<0>(new_face).size(); ++ i)
polygons.back()[i] = std::size_t(get<0>(new_face)[i]);
}
return true;
}
}
template <class Point_3, class Polygon_3>
bool
read_PLY( std::istream& in,
std::vector< Point_3 >& points,
std::vector< Polygon_3 >& polygons,
bool /* verbose */ = false)
{
if(!in)
{
std::cerr << "Error: cannot open file" << std::endl;
return false;
}
internal::PLY::PLY_reader reader;
if (!(reader.init (in)))
{
in.setstate(std::ios::failbit);
return false;
}
for (std::size_t i = 0; i < reader.number_of_elements(); ++ i)
{
internal::PLY::PLY_element& element = reader.element(i);
if (element.name() == "vertex" || element.name() == "vertices")
{
for (std::size_t j = 0; j < element.number_of_items(); ++ j)
{
for (std::size_t k = 0; k < element.number_of_properties(); ++ k)
{
internal::PLY::PLY_read_number* property = element.property(k);
property->get (in);
if (in.fail())
return false;
}
Point_3 new_vertex;
internal::PLY::process_properties (element, new_vertex,
make_ply_point_reader (CGAL::Identity_property_map<Point_3>()));
points.push_back (get<0>(new_vertex));
}
}
else if (element.name() == "face" || element.name() == "faces")
{
std::vector<CGAL::Color> dummy;
if (element.has_property<std::vector<boost::int32_t> > ("vertex_indices"))
internal::read_PLY_faces<boost::int32_t> (in, element, polygons, dummy, "vertex_indices");
else if (element.has_property<std::vector<boost::uint32_t> > ("vertex_indices"))
internal::read_PLY_faces<boost::uint32_t> (in, element, polygons, dummy, "vertex_indices");
else if (element.has_property<std::vector<boost::int32_t> > ("vertex_index"))
internal::read_PLY_faces<boost::int32_t> (in, element, polygons, dummy, "vertex_index");
else if (element.has_property<std::vector<boost::uint32_t> > ("vertex_index"))
internal::read_PLY_faces<boost::uint32_t> (in, element, polygons, dummy, "vertex_index");
else
{
std::cerr << "Error: can't find vertex indices in PLY input" << std::endl;
return false;
}
}
else // Read other elements and ignore
{
for (std::size_t j = 0; j < element.number_of_items(); ++ j)
{
for (std::size_t k = 0; k < element.number_of_properties(); ++ k)
{
internal::PLY::PLY_read_number* property = element.property(k);
property->get (in);
if (in.fail())
return false;
}
}
}
}
return !in.bad();
}
template <class Point_3, class Polygon_3, class Color_rgb>
bool
read_PLY( std::istream& in,
std::vector< Point_3 >& points,
std::vector< Polygon_3 >& polygons,
std::vector<std::pair<unsigned int, unsigned int> >& hedges,
std::vector<Color_rgb>& fcolors,
std::vector<Color_rgb>& vcolors,
std::vector<std::pair<float, float> >& huvs,
bool /* verbose */ = false)
{
if(!in)
{
std::cerr << "Error: cannot open file" << std::endl;
return false;
}
internal::PLY::PLY_reader reader;
if (!(reader.init (in)))
{
in.setstate(std::ios::failbit);
return false;
}
for (std::size_t i = 0; i < reader.number_of_elements(); ++ i)
{
internal::PLY::PLY_element& element = reader.element(i);
if (element.name() == "vertex" || element.name() == "vertices")
{
bool has_colors = false;
std::string rtag = "r", gtag = "g", btag = "b";
if ((element.has_property<boost::uint8_t>("red") || element.has_property<boost::uint8_t>("r")) &&
(element.has_property<boost::uint8_t>("green") || element.has_property<boost::uint8_t>("g")) &&
(element.has_property<boost::uint8_t>("blue") || element.has_property<boost::uint8_t>("b")))
{
has_colors = true;
if (element.has_property<boost::uint8_t>("red"))
{
rtag = "red"; gtag = "green"; btag = "blue";
}
}
for (std::size_t j = 0; j < element.number_of_items(); ++ j)
{
for (std::size_t k = 0; k < element.number_of_properties(); ++ k)
{
internal::PLY::PLY_read_number* property = element.property(k);
property->get (in);
if (in.fail())
return false;
}
std::tuple<Point_3, boost::uint8_t, boost::uint8_t, boost::uint8_t> new_vertex;
if (has_colors)
{
internal::PLY::process_properties (element, new_vertex,
make_ply_point_reader (CGAL::make_nth_of_tuple_property_map<0>(new_vertex)),
std::make_pair (CGAL::make_nth_of_tuple_property_map<1>(new_vertex),
PLY_property<boost::uint8_t>(rtag.c_str())),
std::make_pair (CGAL::make_nth_of_tuple_property_map<2>(new_vertex),
PLY_property<boost::uint8_t>(gtag.c_str())),
std::make_pair (CGAL::make_nth_of_tuple_property_map<3>(new_vertex),
PLY_property<boost::uint8_t>(btag.c_str())));
vcolors.push_back (Color_rgb (get<1>(new_vertex), get<2>(new_vertex), get<3>(new_vertex)));
}
else
internal::PLY::process_properties (element, new_vertex,
make_ply_point_reader (CGAL::make_nth_of_tuple_property_map<0>(new_vertex)));
points.push_back (get<0>(new_vertex));
}
}
else if (element.name() == "face" || element.name() == "faces")
{
if (element.has_property<std::vector<boost::int32_t> > ("vertex_indices"))
internal::read_PLY_faces<boost::int32_t> (in, element, polygons, fcolors, "vertex_indices");
else if (element.has_property<std::vector<boost::uint32_t> > ("vertex_indices"))
internal::read_PLY_faces<boost::uint32_t> (in, element, polygons, fcolors, "vertex_indices");
else if (element.has_property<std::vector<boost::int32_t> > ("vertex_index"))
internal::read_PLY_faces<boost::int32_t> (in, element, polygons, fcolors, "vertex_index");
else if (element.has_property<std::vector<boost::uint32_t> > ("vertex_index"))
internal::read_PLY_faces<boost::uint32_t> (in, element, polygons, fcolors, "vertex_index");
else
{
std::cerr << "Error: can't find vertex indices in PLY input" << std::endl;
return false;
}
}
else if(element.name() == "halfedge" )
{
bool has_uv = false;
std::string stag = "source", ttag = "target", utag = "u", vtag = "v";
if ( element.has_property<unsigned int>("source") &&
element.has_property<unsigned int>("target") &&
element.has_property<float>("u") &&
element.has_property<float>("v"))
{
has_uv = true;
}
std::tuple<unsigned int, unsigned int, float, float, float> new_hedge;
for (std::size_t j = 0; j < element.number_of_items(); ++ j)
{
for (std::size_t k = 0; k < element.number_of_properties(); ++ k)
{
internal::PLY::PLY_read_number* property = element.property(k);
property->get (in);
if (in.eof())
return false;
}
if (has_uv)
{
internal::PLY::process_properties (element, new_hedge,
std::make_pair (CGAL::make_nth_of_tuple_property_map<0>(new_hedge),
PLY_property<unsigned int>(stag.c_str())),
std::make_pair (CGAL::make_nth_of_tuple_property_map<1>(new_hedge),
PLY_property<unsigned int>(ttag.c_str())),
std::make_pair (CGAL::make_nth_of_tuple_property_map<2>(new_hedge),
PLY_property<float>(utag.c_str())),
std::make_pair (CGAL::make_nth_of_tuple_property_map<3>(new_hedge),
PLY_property<float>(vtag.c_str())));
hedges.push_back (std::make_pair(get<0>(new_hedge), get<1>(new_hedge)));
huvs.push_back (std::make_pair(get<2>(new_hedge), get<3>(new_hedge)));
}
else
internal::PLY::process_properties (element, new_hedge,
std::make_pair(CGAL::make_nth_of_tuple_property_map<0>(new_hedge),
PLY_property<unsigned int>(stag.c_str())),
std::make_pair(CGAL::make_nth_of_tuple_property_map<1>(new_hedge),
PLY_property<unsigned int>(ttag.c_str()))
);
}
}
else // Read other elements and ignore
{
for (std::size_t j = 0; j < element.number_of_items(); ++ j)
{
for (std::size_t k = 0; k < element.number_of_properties(); ++ k)
{
internal::PLY::PLY_read_number* property = element.property(k);
property->get (in);
if (in.fail())
return false;
}
}
}
}
return !in.bad();
}
template <class Point_3, class Polygon_3, class Color_rgb>
bool
read_PLY( std::istream& in,
std::vector< Point_3 >& points,
std::vector< Polygon_3 >& polygons,
std::vector<Color_rgb>& fcolors,
std::vector<Color_rgb>& vcolors,
bool /* verbose */ = false)
{
std::vector<std::pair<unsigned int, unsigned int> > dummy_pui;
std::vector<std::pair<float, float> > dummy_pf;
return read_PLY<Point_3, Polygon_3, Color_rgb>(in, points, polygons,
dummy_pui,
fcolors, vcolors,
dummy_pf);
}
} // namespace CGAL
#define CGAL_DEPRECATED_HEADER "<CGAL/IO/PLY_reader.h>"
#define CGAL_REPLACEMENT_HEADER "<CGAL/IO/PLY/PLY_reader.h>"
#include <CGAL/internal/deprecation_warning.h>
#include <CGAL/IO/PLY/PLY_reader.h>
#include <CGAL/enable_warnings.h>
#endif // CGAL_IO_PLY_READER_H

View File

@ -13,148 +13,11 @@
#include <CGAL/IO/PLY.h>
namespace CGAL{
template <class Point_3, class Polygon_3>
bool
write_PLY(std::ostream& out,
const std::vector< Point_3 >& points,
const std::vector< Polygon_3 >& polygons,
bool /* verbose */ = false)
{
if(!out)
{
std::cerr << "Error: cannot open file" << std::endl;
return false;
}
// Write header
out << "ply" << std::endl
<< ((get_mode(out) == IO::BINARY) ? "format binary_little_endian 1.0" : "format ascii 1.0") << std::endl
<< "comment Generated by the CGAL library" << std::endl
<< "element vertex " << points.size() << std::endl;
internal::PLY::output_property_header (out,
make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
out << "element face " << polygons.size() << std::endl;
internal::PLY::output_property_header (out,
std::make_pair (CGAL::Identity_property_map<Polygon_3>(),
PLY_property<std::vector<int> >("vertex_indices")));
out << "end_header" << std::endl;
for (std::size_t i = 0; i < points.size(); ++ i)
internal::PLY::output_properties (out, points.begin() + i,
make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
for (std::size_t i = 0; i < polygons.size(); ++ i)
internal::PLY::output_properties (out, polygons.begin() + i,
std::make_pair (CGAL::Identity_property_map<Polygon_3>(),
PLY_property<std::vector<int> >("vertex_indices")));
return out.good();
}
template <class SurfaceMesh>
bool
write_PLY(std::ostream& out,
const SurfaceMesh& mesh,
bool /* verbose */ = false)
{
typedef typename boost::graph_traits<SurfaceMesh>::face_descriptor face_descriptor;
typedef typename boost::graph_traits<SurfaceMesh>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<SurfaceMesh>::vertex_descriptor vertex_descriptor;
typedef typename boost::property_map<SurfaceMesh, boost::vertex_point_t>::type::value_type Point_3;
typedef typename SurfaceMesh::template Property_map<halfedge_descriptor,std::pair<float, float> > UV_map;
UV_map h_uv;
bool has_texture;
boost::tie(h_uv, has_texture) = mesh.template property_map<halfedge_descriptor,std::pair<float, float> >("h:uv");
if(!out)
{
std::cerr << "Error: cannot open file" << std::endl;
return false;
}
// Write header
out << "ply" << std::endl
<< ((get_mode(out) == IO::BINARY) ? "format binary_little_endian 1.0" : "format ascii 1.0") << std::endl
<< "comment Generated by the CGAL library" << std::endl
<< "element vertex " << num_vertices(mesh) << std::endl;
internal::PLY::output_property_header (out,
make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
out << "element face " << num_faces(mesh) << std::endl;
internal::PLY::output_property_header (out,
std::make_pair (CGAL::Identity_property_map<std::vector<std::size_t> >(),
PLY_property<std::vector<int> >("vertex_indices")));
if(has_texture)
{
out << "element halfedge " << num_halfedges(mesh) << std::endl;
internal::PLY::output_property_header (out,
std::make_pair (CGAL::Identity_property_map<std::size_t >(),
PLY_property<unsigned int >("source")));
internal::PLY::output_property_header (out,
std::make_pair (CGAL::Identity_property_map<std::size_t >(),
PLY_property<unsigned int >("target")));
internal::PLY::output_property_header (out,
std::make_tuple (h_uv,
PLY_property<float>("u"),
PLY_property<float>("v")));
}
out << "end_header" << std::endl;
for(vertex_descriptor vd : vertices(mesh))
{
Point_3 p = get(get(CGAL::vertex_point, mesh), vd);
internal::PLY::output_properties (out, &p,
make_ply_point_writer (CGAL::Identity_property_map<Point_3>()));
}
std::vector<std::size_t> polygon;
for(face_descriptor fd : faces(mesh))
{
polygon.clear();
for(halfedge_descriptor hd : halfedges_around_face(halfedge(fd, mesh), mesh))
polygon.push_back (get(get(boost::vertex_index, mesh), target(hd,mesh)));
internal::PLY::output_properties (out, &polygon,
std::make_pair (CGAL::Identity_property_map<std::vector<std::size_t> >(),
PLY_property<std::vector<int> >("vertex_indices")));
}
if(has_texture)
{
for(halfedge_descriptor hd : halfedges(mesh))
{
typedef std::tuple<unsigned int, unsigned int, float, float> Super_tuple;
Super_tuple t =
std::make_tuple(source(hd, mesh),target(hd, mesh),
h_uv[hd].first,
h_uv[hd].second);
internal::PLY::output_properties (out, &t,
std::make_pair (Nth_of_tuple_property_map<0,Super_tuple>(),
PLY_property<unsigned int >("source")),
std::make_pair (Nth_of_tuple_property_map<1,Super_tuple>(),
PLY_property<unsigned int >("target")),
std::make_pair (Nth_of_tuple_property_map<2,Super_tuple>(),
PLY_property<float>("u")),
std::make_pair (Nth_of_tuple_property_map<3,Super_tuple>(),
PLY_property<float>("v")));
}
}
return out.good();
}
} // namespace CGAL
#include <CGAL/disable_warnings.h>
#define CGAL_DEPRECATED_HEADER "<CGAL/IO/PLY_writer.h>"
#define CGAL_REPLACEMENT_HEADER "<CGAL/IO/PLY/PLY_writer.h>"
#include <CGAL/internal/deprecation_warning.h>
#include <CGAL/IO/PLY/PLY_writer.h>
#include <CGAL/enable_warnings.h>
#endif // CGAL_IO_PLY_WRITER_H

View File

@ -12,352 +12,12 @@
#ifndef CGAL_IO_STL_READER_H
#define CGAL_IO_STL_READER_H
#include <CGAL/IO/io.h>
#include <CGAL/IO/reader_helpers.h>
#include <CGAL/disable_warnings.h>
#include <boost/cstdint.hpp>
#include <cctype>
#include <iostream>
#include <map>
#include <string>
#include <vector>
namespace CGAL {
template <class Point, class Triangle>
bool read_ASCII_facet(std::istream& input,
std::vector<Point>& points,
std::vector<Triangle>& facets,
int& index,
std::map<Point, int >& index_map,
bool verbose = false)
{
// Here, we have already read the word 'facet' and are looking to read till 'endfacet'
std::string s;
std::string vertex("vertex"),
endfacet("endfacet");
int count = 0;
double x,y,z;
Point p;
Triangle ijk;
IO::internal::resize(ijk, 3);
while(input >> s)
{
if(s == endfacet)
{
if(count != 3)
{
if(verbose)
std::cerr << "Error: only triangulated surfaces are supported" << std::endl;
return false;
}
facets.push_back(ijk);
return true;
}
else if(s == vertex)
{
if(count >= 3)
{
if(verbose)
std::cerr << "Error: only triangulated surfaces are supported" << std::endl;
return false;
}
if(!(input >> iformat(x) >> iformat(y) >> iformat(z)))
{
if(verbose)
std::cerr << "Error while reading point coordinates (premature end of file)" << std::endl;
return false;
}
else
{
IO::internal::fill_point(x, y, z, p);
typename std::map<Point, int>::iterator iti = index_map.insert(std::make_pair(p, -1)).first;
if(iti->second == -1)
{
ijk[count] = index;
iti->second = index++;
points.push_back(p);
}
else
{
ijk[count] = iti->second;
}
}
++count;
}
}
if(verbose)
std::cerr << "Error while reading facet (premature end of file)" << std::endl;
return false;
}
template <class Point, class Triangle>
bool parse_ASCII_STL(std::istream& input,
std::vector<Point>& points,
std::vector<Triangle>& facets,
bool verbose = false)
{
if(verbose)
std::cout << "Parsing ASCII file..." << std::endl;
if(!input.good())
return true;
// Here, we have already read the word 'solid'
int index = 0;
std::map<Point, int> index_map;
std::string s, facet("facet"), endsolid("endsolid");
while(input >> s)
{
if(s == facet)
{
if(!read_ASCII_facet(input, points, facets, index, index_map, verbose))
return false;
}
else if(s == endsolid)
{
return true;
}
}
if(verbose)
std::cerr << "Error while parsing ASCII file" << std::endl;
return false;
}
template <typename Point, typename Triangle>
bool parse_binary_STL(std::istream& input,
std::vector<Point>& points,
std::vector<Triangle>& facets,
bool verbose = false)
{
if(verbose)
std::cout << "Parsing binary file..." << std::endl;
// Start from the beginning again to simplify things
input.clear();
input.seekg(0, std::ios::beg);
if(!input.good())
return true;
// Discard the first 80 chars (unused header)
int pos = 0;
char c;
if(verbose)
std::cout << "header: ";
while(pos < 80)
{
input.read(reinterpret_cast<char*>(&c), sizeof(c));
if(!input.good())
break;
if(verbose)
std::cout << c;
++pos;
}
if(verbose)
std::cout << std::endl;
if(pos != 80)
return true; // empty file
int index = 0;
std::map<Point, int> index_map;
boost::uint32_t N32;
if(!(input.read(reinterpret_cast<char*>(&N32), sizeof(N32))))
{
if(verbose)
std::cerr << "Error while reading number of facets" << std::endl;
return false;
}
unsigned int N = N32;
if(verbose)
std::cout << N << " facets to read" << std::endl;
for(unsigned int i=0; i<N; ++i)
{
float normal[3];
if(!(input.read(reinterpret_cast<char*>(&normal[0]), sizeof(normal[0]))) ||
!(input.read(reinterpret_cast<char*>(&normal[1]), sizeof(normal[1]))) ||
!(input.read(reinterpret_cast<char*>(&normal[2]), sizeof(normal[2]))))
{
if(verbose)
std::cerr << "Error while reading normal coordinates (premature end of file)" << std::endl;
return false;
}
Triangle ijk;
IO::internal::resize(ijk, 3);
for(int j=0; j<3; ++j)
{
float x,y,z;
if(!(input.read(reinterpret_cast<char*>(&x), sizeof(x))) ||
!(input.read(reinterpret_cast<char*>(&y), sizeof(y))) ||
!(input.read(reinterpret_cast<char*>(&z), sizeof(z))))
{
if(verbose)
std::cerr << "Error while reading vertex coordinates (premature end of file)" << std::endl;
return false;
}
Point p;
IO::internal::fill_point(x, y, z, p);
typename std::map<Point, int>::iterator iti = index_map.insert(std::make_pair(p, -1)).first;
if(iti->second == -1)
{
ijk[j] = index;
iti->second = index++;
points.push_back(p);
}
else
{
ijk[j] = iti->second;
}
}
facets.push_back(ijk);
// Read so-called attribute byte count and ignore it
char c;
if(!(input.read(reinterpret_cast<char*>(&c), sizeof(c))) ||
!(input.read(reinterpret_cast<char*>(&c), sizeof(c))))
{
if(verbose)
std::cerr << "Error while reading attribute byte count (premature end of file)" << std::endl;
return false;
}
}
return true;
}
//
// Read a file with `.stl` format.
//
// \tparam Point must be a model of the concept `RandomAccessContainer` or a %CGAL point type
// \tparam Triangle must be a model of the concept `RandomAccessContainer`
//
// \param input the input stream
// \param points a container that will contain the points used in the .stl file
// \param polygons a container that will contain the triangles used in the .stl file
// \param verbose whether to enable or not a sanity log
//
// \returns `true` if the reading process went well, `false` otherwise
//
// \warning `points` and `facets` are not cleared: new points and triangles are added to the back
// of the containers.
//
// Although the STL file format uses triangles, it is convenient to be able to use vectors
// and other models of the `SequenceContainer` (instead of arrays) for the face type,
// to avoid having to convert the to apply polygon soup reparation algorithms.
template <class Point, class Triangle>
bool read_STL(std::istream& input,
std::vector<Point>& points,
std::vector<Triangle>& facets,
bool verbose = false)
{
int pos = 0;
// Ignore all initial whitespace
unsigned char c;
while(input.read(reinterpret_cast<char*>(&c), sizeof(c)))
{
if(!isspace(c))
{
input.unget(); // move back to the first interesting char
break;
}
++pos;
}
if(!input.good()) // reached the end
return true;
// If we have gone beyond 80 characters and have not read anything yet,
// then this must be an ASCII file.
if(pos > 80)
return parse_ASCII_STL(input, points, facets, verbose);
// We are within the first 80 characters, both ASCII and binary are possible
// Read the 5 first characters to check if the first word is "solid"
std::string s, solid("solid");
char word[5];
if(input.read(reinterpret_cast<char*>(&word[0]), sizeof(c)) &&
input.read(reinterpret_cast<char*>(&word[1]), sizeof(c)) &&
input.read(reinterpret_cast<char*>(&word[2]), sizeof(c)) &&
input.read(reinterpret_cast<char*>(&word[3]), sizeof(c)) &&
input.read(reinterpret_cast<char*>(&word[4]), sizeof(c)))
{
s = std::string(word, 5);
pos += 5;
}
else
return true; // empty file
// If the first word is not 'solid', the file must be binary
if(s != solid)
{
if(parse_binary_STL(input, points, facets, verbose))
{
return true;
}
else
{
// If we failed to read it as a binary, try as ASCII just in case...
// The file does not start with 'solid' anyway, so it's fine to reset it.
input.clear();
input.seekg(0, std::ios::beg);
return parse_ASCII_STL(input, points, facets, verbose);
}
}
// Now, we have found the keyword "solid" which is supposed to indicate that the file is ASCII
if(parse_ASCII_STL(input, points, facets, verbose))
{
// correctly read the input as an ASCII file
return true;
}
else // Failed to read the ASCII file
{
// It might have actually have been a binary file... ?
return parse_binary_STL(input, points, facets, verbose);
}
}
} // namespace CGAL
#define CGAL_DEPRECATED_HEADER "<CGAL/IO/STL_reader.h>"
#define CGAL_REPLACEMENT_HEADER "<CGAL/IO/STL/STL_reader.h>"
#include <CGAL/internal/deprecation_warning.h>
#include <CGAL/IO/STL/STL_reader.h>
#include <CGAL/enable_warnings.h>
#endif // CGAL_IO_STL_READER_H

View File

@ -11,79 +11,10 @@
#ifndef CGAL_IO_STL_WRITER_H
#define CGAL_IO_STL_WRITER_H
#include <CGAL/Kernel_traits.h>
#include <CGAL/boost/graph/properties.h>
#include <boost/cstdint.hpp>
#include <boost/graph/graph_traits.hpp>
namespace CGAL{
template <class TriangleMesh>
std::ostream&
write_STL(const TriangleMesh& tm, std::ostream& out)
{
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::property_map<TriangleMesh, boost::vertex_point_t>::const_type Vpm;
typedef typename boost::property_traits<Vpm>::reference Point_3_ref;
typedef typename boost::property_traits<Vpm>::value_type Point_3;
typedef typename Kernel_traits<Point_3>::Kernel::Vector_3 Vector_3;
Vpm vpm = get(boost::vertex_point, tm);
if (get_mode(out) == IO::BINARY)
{
out << "FileType: Binary ";
const boost::uint32_t N32 = static_cast<boost::uint32_t>(faces(tm).size());
out.write(reinterpret_cast<const char *>(&N32), sizeof(N32));
for(face_descriptor f : faces(tm))
{
halfedge_descriptor h = halfedge(f, tm);
Point_3_ref p = get(vpm, target(h, tm));
Point_3_ref q = get(vpm, target(next(h, tm), tm));
Point_3_ref r = get(vpm, source(h, tm));
Vector_3 n = collinear(p,q,r) ? Vector_3(1,0,0):
unit_normal(p,q,r);
const float coords[12]={
static_cast<float>(n.x()), static_cast<float>(n.y()), static_cast<float>(n.z()),
static_cast<float>(p.x()), static_cast<float>(p.y()), static_cast<float>(p.z()),
static_cast<float>(q.x()), static_cast<float>(q.y()), static_cast<float>(q.z()),
static_cast<float>(r.x()), static_cast<float>(r.y()), static_cast<float>(r.z()) };
for (int i=0; i<12; ++i)
out.write(reinterpret_cast<const char *>(&coords[i]), sizeof(coords[i]));
out << " ";
}
}
else
{
out << "solid\n";
for(face_descriptor f : faces(tm))
{
halfedge_descriptor h = halfedge(f, tm);
Point_3_ref p = get(vpm, target(h, tm));
Point_3_ref q = get(vpm, target(next(h, tm), tm));
Point_3_ref r = get(vpm, source(h, tm));
Vector_3 n = collinear(p,q,r) ? Vector_3(1,0,0):
unit_normal(p,q,r);
out << "facet normal " << n << "\nouter loop\n";
out << "vertex " << p << "\n";
out << "vertex " << q << "\n";
out << "vertex " << r << "\n";
out << "endloop\nendfacet\n";
}
out << "endsolid\n";
}
return out;
}
} // end of namespace CGAL
#define CGAL_DEPRECATED_HEADER "<CGAL/IO/STL_writer.h>"
#define CGAL_REPLACEMENT_HEADER "<CGAL/boost/graph/io.h>"
#include <CGAL/internal/deprecation_warning.h>
#include <CGAL/boost/graph/io.h>
#include <CGAL/enable_warnings.h>
#endif // CGAL_IO_STL_WRITER_H

View File

@ -1,24 +0,0 @@
# Created by the script cgal_create_cmake_script
# This is the CMake script for compiling a CGAL application.
cmake_minimum_required(VERSION 3.1...3.15)
project( Polyhedron_IO_Tests )
find_package(CGAL QUIET)
if ( CGAL_FOUND )
# create a target per cppfile
file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
foreach(cppfile ${cppfiles})
create_single_source_cgal_program( "${cppfile}" )
endforeach()
else()
message(STATUS "This program requires the CGAL library, and will not be compiled.")
endif()

View File

@ -0,0 +1,11 @@
namespace CGAL {
//! \ingroup IOstreamFunctions
///reads a file in .obj format.
///\tparam Points_3 a RandomAccessContainer of Point_3,
///\tparam Faces a RandomAccessContainer of RandomAccessContainer of std::size_t
/// \see IOStreamOBJ
template <class Points_3, class Faces>
bool
read_OBJ(std::istream& input, Points_3 &points, Faces &faces);
}

View File

@ -0,0 +1,24 @@
namespace CGAL{
/*!
* \ingroup IOstreamFunctions
* writes the content of `in` in `points` and `polygons`, in the OFF format.
* \see \ref IOStreamOFF
*/
template <class Point_3, class Polygon_3>
bool
read_OFF( std::istream& in,
std::vector< Point_3 >& points,
std::vector< Polygon_3 >& polygons,
bool /* verbose */ = false);
/*!
* \ingroup IOstreamFunctions
* writes the content of `points` and `polygons` in `out`, in the OFF format.
* \see \ref IOStreamOFF
*/
template <class Point_3, class Polygon_3>
bool
write_OFF(std::ostream& out,
std::vector< Point_3 >& points,
std::vector< Polygon_3 >& polygons);
}

View File

@ -0,0 +1,220 @@
/*!
\page IOStreamSupportedFileFormats Supported File Formats
\cgal provides a large number of data structures and algorithms dedicated to
various applications. This page lists the various supported file formats
and the data structures offered by \cgal that may be used to read and write files of
this specific format.
- \ref IOStreamOFF
- \ref IOStreamOBJ
- \ref IOStreamPLY
- \ref IOStreamSTL
- \ref IOStreamXYZ
- \ref IOStreamVTK
- \ref IOStreamAvizo
- \ref IOStreamMedit
- \ref IOStreamTetgen
- \ref IOStreamGocad
- \ref IOStreamWRL
\section IOStreamOFF Object File Format (OFF)
The `OFF` file format can be used to represent collections of planar polygons with possibly shared vertices.
Although it can be as light as providing points and faces described by IDs, the format also allows
users to provide more properties such as associating normals or colors to vertices.
A precise specification of the format is available at <a href="http://www.geomview.org/docs/html/OFF.html">geomview.org</a>.
\subsection IOStreamOFFInput Reading OFF files
Objects represented in the `.OFF` format can be imported into \cgal's working environment
using the following data structures and functions.
- CGAL::Surface_mesh (\ref read_off(Surface_mesh<K>&, const std::string&)), a halfedge data structure allowing to represent polyhedral surfaces
- CGAL::Polyhedron_3 (\ref read_off( std::istream&, Polyhedron_3<PolyhedronTraits_3>&)), a halfedge data structure, which restricts the class of representable surfaces
to orientable 2-manifolds.
- Any structure that is a model of the concept `FaceGraph` (read_off(std::istream&,FaceGraph&,NamedParameters))
- CGAL::Point_set_3 (operator>>(std::istream&,CGAL::Point_set_3<Point, Vector>&)
Polygon soups can also be imported using the function read_OFF().
As documented in the functions above, the only property that we support is the color,
and it is only supported for the CGAL::Surface_mesh.
\subsection IOStreamOFFOutput Writing OFF files
The following \cgal data structures can be exported into the `OFF` file format:
- CGAL::Surface_mesh (write_off(std::ostream&, const Surface_mesh<P>&, const NamedParameters&))
- Any structure that is a model of the concept `FaceGraph` (write_off(std::ostream&,const FaceGraph&,const NamedParameters&))
- CGAL::Point_set_3 (\ref write_off_point_set())
Polygon soups can also be exported using the function write_OFF().
Note that we only support OFF, and COFF for CGAL::Surface_mesh.
\section IOStreamOBJ Wavefront (OBJ)
The OBJ file format is a simple data-format that represents 3D geometry.
Vertices are stored in a counter-clockwise order by default, making explicit declaration of face normals unnecessary.
A precise specification of the format is available <a href="http://www.martinreddy.net/gfx/3d/OBJ.spec">here</a>.
\subsection IOStreamOBJInput Reading OBJ files
Objects represented in the `.OBJ` format can be imported into \cgal's working environment
using any structure that is a model of the concept `FaceGraph`, and the function `read_OBJ()`.
Polygon soups can also be imported using the function \ref IOstreamFunctions "read_OBJ()".
\subsection IOStreamOBJOutput Writing OBJ files
Any structure that is a model of the concept `FaceGraph` can be exported into the `OBJ` file format
using the function `write_OBJ()`.
\section IOStreamPLY Polygon File Format (PLY)
Conceived to store the data obtained during 3D scans, the `PLY` file format stores objects
as a simple list of polygons, etc.
A precise specification of those formats is available at
<a href="http://paulbourke.net/dataformats/ply/"> paulbourke.net</a>.
\subsection IOStreamPLYInput Reading PLY files
Objects represented in the `.PLY` format can be imported into \cgal's working environment
using the following data structures and functions.
- CGAL::Surface_mesh (read_ply())
- CGAL::Point_set_3 (operator>>(std::istream&,CGAL::Point_set_3<Point, Vector>&))a collection of points with dynamically associated properties
\subsection IOStreamPLYOutput Writing PLY files
The following \cgal data structures can be exported into the `PLY` file format:
- CGAL::Surface_mesh (write_ply())
- CGAL::Point_set_3 (operator<<(std::ostream&,const CGAL::Point_set_3<Point, Vector>&))
\section IOStreamSTL Standard Triangle Language (STL)
STL is a file format native to the stereolithography CAD software created by
3D Systems.STL files describe the surface geometry of a three-dimensional object.
A precise specification of those formats is available at
<a href="http://www.fabbers.com/tech/STL_Format"> fabbers.com</a>.
\subsection IOStreamSTLInput Reading STL files
Objects represented in the `.STL` format can be imported into \cgal's working environment
using any data structure that is a model of the `FaceGraph` concept, using \ref CGAL::read_STL();
In addition, if the data cannot be read in a `FaceGraph` because of bad orientation or
manifoldness, the function \link IOstreamFunctions `CGAL::read_STL(std::istream&,PointRange&,TriangleRange&,bool)` \endlink
allows to load data directly in a soup of triangles. From there, you can use \ref PMPRepairing
functions to construct a valid PolygonMesh.
\subsection IOStreamSTLOutput Writing STL files
Similarly, any data structure that is a model of the `FaceGraph` concept can be exported
as a `.STL` file using \ref CGAL::write_STL(const TriangleMesh&, std::ostream&).
Polygon soups can also be exported using the function \link IOstreamFunctions `CGAL::write_STL(const PointRange&,const TriangleRange&,std::ostream&)`. \endlink
Note that the STL file format exports triangular faces as geometric triangles and thus
lose combinatorial information.
\section IOStreamXYZ XYZ (or PWN)
The `XYZ` format is a non standard format regularly used to described point sets.
each line represent a point, and is composed of its coordinates and other properties.
We only support coordinates and normals (in that case the standard extension in CGAL
is .pwn for points with normals.)
\subsection IOStreamZYZInput Reading XYZ files
Objects represented in the `.XYZ` or `.PWN` format can be imported into \cgal's working environment
using the CGAL::Point_set_3 and the function read_xyz_point_set().
\subsection IOStreamXYZOutput Writing XYZ files
The CGAL::Point_set_3 can be exported into a `XYZ` or a `PWN` file using the function
write_xyz_point_set().
\section IOStreamVTK VTK Formats (VTU VTP)
The VTK libraries use different file formats to handle data structures, but we only support two:
- The `VTU` format can be used to store am unordered collection of 3D cells, like tetrahedra,
but also points, triangles, lines, ... In the <a href="https://vtk.org/"> VTK Libraries</a>,
it is the format reserved to store `Unstructured Grids`, and in \cgal,
we use it to store triangulations(2D and 3D).
- The `VTP` format can be used to store collections of points, lines and triangles.
In the <a href="https://vtk.org/"> VTK Libraries</a>,it is the format
reserved to store `PolyData`., and in CGAL, we use it to store Polygon Meshes.
A precise specification of those formats is available at
<a href="https://vtk.org/wp-content/uploads/2015/04/file-formats.pdf"> vtk.org</a>.
\subsection IOStreamVTKInput Reading VTK files
Objects represented in the `VTP` format can be imported into \cgal's working environment
using the following data structures and functions.
- CGAL::Surface_mesh
- CGAL::Polyhedron_3
using the function \ref CGAL::read_vtp(), in the condition that CGAL has been configured
with the VTK libraries.
\subsection IOStreamVTKOutput Writing VTK files
The following \cgal data structures can be exported into the `.VTP` file format:
- CGAL::Surface_mesh
- CGAL::Polyhedron_3
using the function \ref CGAL::write_vtp().
The following \cgal data structures can be exported into the `.VTU` file format:
- CGAL::Mesh_complex_3_in_triangulation_3 using \ref CGAL::output_to_vtu()`.
- CGAL::Constrained_Delaunay_triangulation_2 using the function \ref CGAL::write_vtu()
\section IOStreamAvizo Avizo Format
The `.am` files are used by Avizo to read 3D geometry.
\subsection IOStreamtAvizoOutput Writing Avizo files
Only the `CGAL::Mesh_complex_3_in_triangulation_3` \cgal data structure can be exported into `.am`
This can be done using the function \ref CGAL::output_to_avizo()
\section IOStreamMedit Medit Format
The `.mesh` Medit file format is a format used by the Medit software. In CGAL,
it is mostly used to represent 3D meshes.
A precise specification of the format is available <a href="https://hal.inria.fr/inria-00069921/document"> in this report</a>,
in the appendices (section 7.2.1, page 36).
\subsection IOStreamtMeditOutput Writing Medit files
Only the `CGAL::Mesh_complex_3_in_triangulation_3` \cgal data structure can be exported into `.mesh`
This can be done using the function \ref CGAL::output_to_medit()
\section IOStreamTetgen Tetgen Format
The `Tetgen` file formatscan be used to represent lists of nodes, edges, faces, ...
A precise specification of the format is available at <a href="https://wias-berlin.de/software/tetgen/fformats.html"> wias-berlin.de</a>.
\subsection IOStreamTetgenOutput Writing Tetgen files
Only the `CGAL::Mesh_complex_3_in_triangulation_3` \cgal data structure can be exported into some of the Tetgen file formats,
naming `.node`, `.ele` and `.face`
This can be done using the function \ref CGAL::output_to_tetgen()
\section IOStreamGocad GOCAD Format (TS)
The `.ts` format is an ASCII file format that allows a range of primitive types to be imported into the GOCAD package.
A precise specification of the format is available <a href="http://paulbourke.net/dataformats/gocad/gocad.pdf"> here</a>.
\subsection IOStreamGocadInput Reading Gocad files
Objects represented in the `.ts` format can be imported into \cgal's working environment
using any structure that is a model of the concept `FaceGraph`, and the function `read_gocad()`.
\subsection IOStreamGocadOutput Writing Gocad files
Any structure that is a model of the concept `FaceGraph` can be exported into the `.ts` file format
using the function `write_gocad()`
\section IOStreamWRL
WRL is a file extension for a Virtual Reality Modeling Language (VRML)
file format often used by browser plug-ins to display virtual reality environments.
VRML files are known as “worlds,” which is what WRL stands for.
WRL files are plain ASCII text files.
A WRL file includes data specifying 3-D details such as vertices,
edges for a 3-D polygon, surface color, ...
A precise specification of the format is available <a href="http://gun.teipir.gr/VRML-amgem/spec/"> here</a>.
\subsection IOStreamtWRLOutput Writing WRL files
Any structure that is a model of the concept `FaceGraph` can be exported into the `.wrl` file format
using the `write_wrl()` function.
*/

View File

@ -8,12 +8,215 @@ namespace CGAL {
\authors Andreas Fabri, Geert-Jan Giezeman, Lutz Kettner, and Maxime Gimeno
\section IOstreamIntro Introduction
CGAL algorithms and data structures are usually part of a pipeline of algorithms.
Everything is not entirely self-contained.
Need a way to import and export data to known file formats.
Can in addition enhance the existing stream system coming with the STL.
We first explain which file formats are supported for various types of structures in CGAL.
Then we explain how to customize your stream to read and write objects that do not necessarily already
have an existing overload.
Supported file formats are listed on the \link IOStreamSupportedFileFormats following page\endlink.
\section IOstreamSupportedFormats Importing and Exporting Data
CGAL algorithms work on different types of data structures, such as \ref Chapter_Point_Set_3 "point sets",
\ref PolygonSoups "polygon soups" or \ref PMPDef "polygon meshes".
\subsection IOstreamPolygonMeshIO Polygon Mesh IO
Basically, a Polygon Mesh is a 3D structure that refines the concept of `FaceGraph`
with some other restrictions. A more precise definition can be found \ref PMPDef "here".
<table class="iotable">
<tr>
<th colspan="1"></th>
<th colspan="1">\ref IOStreamOFF "OFF"</th>
<th colspan="1">\ref IOStreamSTL "STL"</th>
<th colspan="2">\ref IOStreamVTK "VTP"</th>
<th colspan="1">\ref IOStreamOBJ "OBJ"</th>
<th colspan="1">\ref IOStreamGocad "GOCAD"</th>
<th colspan="1">\ref IOStreamWRL "WRL"</th>
</tr>
<tr>
<th colspan="1"></th>
<th colspan="1">ASCII</th>
<th colspan="1">ASCII</th>
<th colspan="1">ASCII</th> <th colspan="1">BINARY</th>
<th colspan="1">BINARY</th>
<th colspan="1">ASCII</th>
<th colspan="1">ASCII</th>
</tr>
<tr>
<td>Export</td>
<td>\ref write_off(std::ostream&,const FaceGraph&,const NamedParameters&) "CGAL::write_off()"</td>
<td>\ref CGAL::write_STL(const TriangleMesh&, std::ostream&) "CGAL::write_STL()"</td>
<td>\ref CGAL::write_vtp()</td>
<td>\ref CGAL::write_vtp()</td>
<td>`write_OBJ()`</td>
<td>`write_gocad()`</td>
<td>`write_wrl()`</td>
</tr>
<tr>
<td>Import</td>
<td>\ref read_off(std::istream&,FaceGraph&,NamedParameters) "CGAL::read_off()"</td>
<td>\ref CGAL::read_STL()</td>
<td>\ref CGAL::read_vtp()</td>
<td>\ref CGAL::read_vtp()</td>
<td>`read_OBJ()`</td>
<td>`read_gocad()`</td>
<td>n/a</td>
</tr>
</table>
The table above only lists the functions that work with any Polygon Mesh.
More functions are available for more specific classes, and they can be found
\link IOStreamSupportedFileFormats here\endlink.
\subsection IOstreamPolygonSoupIO Polygon Soup IO
A polygon soup is a set of polygons with no global combinatorial information,
stored in a two containers: one storing the points, and the other one storing
their indices per face (i.e a vector of 3 integers represent a triangle face).
<table class="iotable">
<tr>
<th colspan="1"></th>
<th colspan="1">\ref IOStreamOFF "OFF"</th>
<th colspan="1">\ref IOStreamSTL "STL"</th>
<th colspan="1">\ref IOStreamOBJ "OBJ"</th>
</tr>
<tr>
<th colspan="1"></th>
<th colspan="1">ASCII</th>
<th colspan="1">ASCII</th>
<th colspan="1">BINARY</th>
</tr>
<tr>
<td>Export</td>
<td>write_OFF()</td>
<td> \ref IOstreamFunctions "write_STL()" </td>
<td>n/a</td>
</tr>
<tr>
<td>Import</td>
<td>read_OFF()</td>
<td>\ref IOstreamFunctions "read_STL()"</td>
<td>\ref IOstreamFunctions "read_OBJ()"</td>
</tr>
</table>
\subsection IOstreamPointSetIO Point Set IO
The CGAL::Point_set_3 is a vector based data structure that contains
a default property (named point) for the coordinates of the points,
and is able to work with dynamic properties.
<table class="iotable">
<tr>
<th colspan="1"></th>
<th colspan="1">\ref IOStreamOFF "OFF"</th>
<th colspan="1">\ref IOStreamXYZ "XYZ"</th>
<th colspan="2<td>operator<<(std::ostream&,const CGAL::Point_set_3<Point, Vector>&)</td>">\ref IOStreamPLY "PLY"</th>
</tr>
<tr>
<th colspan="1"></th>
<th colspan="1">ASCII</th>
<th colspan="1">ASCII</th>
<th colspan="1">ASCII</th> <th colspan="1">BINARY</th>
</tr>
<tr>
<td>Export</td>
<td>write_OFF()</td>
<td>write_xyz_point_set()</td>
<td>operator<<(std::ostream&,const CGAL::Point_set_3<Point, Vector>&)</td><td>write_ply_point_set()</td>
</tr>
<tr>
<td>Import</td>
<td>read_OFF()</td>
<td>read_xyz_point_set()</td>
<td>operator>>(std::istream&,CGAL::Point_set_3<Point, Vector>&)</td><td>operator>>(std::istream&,CGAL::Point_set_3<Point, Vector>&)</td>
</tr>
</table>
\subsection IOstreamWKT Simple 2D Geometry IO
`WKT` stands for <em>Well Known Text</em> and it is a text markup language for representing
vector geometry objects on a geographical map. See the
<A HREF="https://en.wikipedia.org/wiki/Well-known_text">wikipedia page</A> for details.
CGAL supports a subset of WKT types: point, multipoint, linestring, multilinestring, polygon and multipolygon.
Free functions are provided for reading and writing several \cgal types using these WKT types, namely:
- `CGAL::Point_2`
- `CGAL::Point_3`
- `CGAL::Polygon_with_holes_2`
- random access range of the above types.
You can find more information about WKT \ref PkgStreamSupportRef "here", but
here is a table to summarize the most useful functions :
<table>
<tr>
<th colspan="1"></th>
<th colspan="1">Points</th>
<th colspan="1">Polylines</th>
<th colspan="1">Polygons</th>
<th colspan="1">Everything</th>
</tr>
<tr>
<td>Import</td>
<td>read_multi_point_WKT()</td>
<td>read_multi_linestring_WKT()</td>
<td>read_multi_polygon_WKT()</td>
<td>read_WKT()</td>
</tr>
<tr>
<td>Export</td>
<td>write_multi_point_WKT()</td>
<td>write_multi_linestring_WKT()</td>
<td>write_multi_polygon_WKT()</td>
<td>n/a</td>
</tr>
</table>
\subsection IOstreamOtherIO Other Data Structures
- \ref AlphaShape3DIO "3D Alpha Shapes".
- \ref arr_secio "2D Arrangements"
- \ref secMesh_2_IO "2D Conforming Triangulations and Meshes"
- \ref Mesh_3_section_io "3D Mesh Generation"
- \ref Nef_3File "3D Boolean Operations on Nef Polyhedra"
- \ref Surface_mesherIO "3D Surface Mesh"
- \ref TriangulationSecIO "Triangulation"
\subsection IOstreamOther Reading Unsupported Formats
If %CGAL does not support the file format of your data, the
<a href="https://www.boost.org/doc/libs/release/libs/property_tree/">`boost::property_tree`</a>
might come in handy if your data has a simple-enough structure.
The following small example shows how to parse an <a href="https://en.wikipedia.org/wiki/XML">XML</a> file,
which might look as follows:
\code{.xml}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PolySet>
<Polygon>
<Point X="-715.8811978465" Y="-2729.9490000000" Z="-534.9000000000"/>
<Point X="-718.1905989232" Y="-2729.9490000000" Z="-538.9000000000"/>
<Point X="-722.8094010768" Y="-2729.9490000000" Z="-538.9000000000"/>
</Polygon>
</PolySet>
\endcode
\cgalExample{Stream_support/read_xml.cpp}
\section IOstreamIO IO Streams
All classes in the \cgal kernel provide input and output operators for
IO streams. Classes external to \cgal are also supported, by means of `oformat()` (Section \ref seciofornoncgaltypes "IO for Non CGAL Types").
IO streams. Classes external to \cgal are also supported, by means of `oformat()`
(Section \ref seciofornoncgaltypes "IO for Non CGAL Types").
The basic task of such an operator is to produce a
representation of an object that can be written as a sequence of
characters on devices as a console, a file, or a pipe. In \cgal we distinguish between a raw ascii, a raw binary and a
pretty printing format.
characters on devices as a console, a file, or a pipe. In \cgal we distinguish between a raw ascii,
a raw binary, and a pretty printing format.
\code{.cpp}
enum Mode {ASCII = 0, BINARY, PRETTY};
@ -36,14 +239,13 @@ is in <span class="textsc">Ascii</span> mode.
\cgal provides the following functions to modify the mode of an IO stream.
\code{.cpp}
IO::Mode set_mode(std::ios& s, IO::Mode m);
IO::Mode set_ascii_mode(std::ios& s);
IO::Mode set_binary_mode(std::ios& s);
IO::Mode set_pretty_mode(std::ios& s);
\endcode
The following functions allow to test whether a stream is in a certain mode.
The following functions enable testing whether a stream is in a certain mode:
\code{.cpp}
IO::Mode get_mode(std::ios& s);
bool is_ascii(std::ios& s);
@ -51,13 +253,14 @@ bool is_binary(std::ios& s);
bool is_pretty(std::ios& s);
\endcode
\section IOstreamOutput Output Operator
\subsection IOstreamOutput Output Operator
\cgal defines output operators for classes that are derived
from the class `ostream`. This allows to write to ostreams
as `std::cout` or `std::cerr`, as well as to `std::ostringstream`
and `std::ofstream`.
The output operator is defined for all classes in the \cgal `Kernel` and for the class `Color` as well.
The output operator is defined for all classes in the \cgal `Kernel` and for the class `Color` (see
Section \ref IOstreamColors) as well.
Let `os` be an output stream.
\code{.cpp}
@ -65,9 +268,6 @@ Let `os` be an output stream.
ostream& operator<<(ostream& os, Class c);
\endcode
\subsection IOstreamExample Example
\code{.cpp}
#include <iostream>
#include <fstream>
@ -94,7 +294,7 @@ int main()
}
\endcode
\section IOstreamInput Input Operator
\subsection IOstreamInput Input Operator
\cgal defines input operators for classes that are derived
from the class `istream`. This allows to read from istreams
@ -107,8 +307,6 @@ Let `is` be an input stream.
istream& operator>>(istream& is, Class c);
\endcode
\subsection IOstreamExample_1 Example
\code{.cpp}
#include <iostream>
#include <fstream>
@ -136,24 +334,19 @@ main()
}
\endcode
\section seciofornoncgaltypes IO for Non-CGAL Types
\subsection seciofornoncgaltypes IO for Non-CGAL Types
\subsection IOstreamUsingOutputFormatting Using Output Formatting
\subsubsection IOstreamUsingOutputFormatting Using Output Formatting
To ensure that non-\cgal types are formatted correctly (i.e., respecting `IO::Mode`), `oformat()` can be used. For types with a `Output_rep` specialization, the respective output routine of `Output_rep` will be called by `oformat()`. Otherwise, the stream output operator will be called.
Example
--------------
To ensure that non-\cgal types are formatted correctly (i.e., respecting `IO::Mode`), `oformat()` can be used.
For types with a `Output_rep` specialization, the respective output routine of `Output_rep`
will be called by `oformat()`. Otherwise, the stream output operator will be called.
\code{.cpp}
std::cout << CGAL::oformat( myobject );
\endcode
Optional, you can provide a second template parameter `F` as a formatting tag:
Example
--------------
Optionally, you can provide a second template parameter `F` as a formatting tag:
\code{.cpp}
std::cout << CGAL::oformat( myobject, My_formatting_tag() );
\endcode
@ -161,7 +354,7 @@ std::cout << CGAL::oformat( myobject, My_formatting_tag() );
For a list of formatting tags supported by the type `T`, please
refer to the documentation of the respective type.
\subsection IOstreamCustomizingOutputFormatting Customizing Output Formatting
\subsubsection IOstreamCustomizingOutputFormatting Customizing Output Formatting
In some situations, you want to control the output formatting for a
type `T`. For external types (third party libraries etc.),
@ -172,7 +365,7 @@ stream output operator.
Instead of putting `T` directly into an output stream,
`T` is wrapped into an output representation `Output_rep`. For
convenience, a function `oformat()` exists which constructs an instance
convenience, a function `oformat()` exists, which constructs an instance
of `Output_rep`.
If you do not specialize `Output_rep` for `T`, `T`'s
@ -186,9 +379,6 @@ tag). The second template parameter defaults to `Null_tag` and means
For example, specializing `Output_rep` for `CORE::BigRat` (without a
formatting tag parameter) could look like this:
Example
--------------
\code{.cpp}
template <class F>
class Output_rep< ::CORE::BigRat, F> {
@ -217,7 +407,7 @@ public:
};
\endcode
\section IOstreamColors Colors
\subsection IOstreamColors Colors
An object of the class `Color` is a color available
for drawing operations in many \cgal output streams.
@ -229,9 +419,7 @@ There are a 11 predefined `Color` constants available:
`DEEPBLUE`, `BLUE`, `PURPLE`, `VIOLET`, `ORANGE`,
and `YELLOW`.
\section IOstreamStream Stream Support
\subsection IOstreamStream Stream Support
Three classes are provided by \cgal as adaptors to input and output stream
iterators. The class `Istream_iterator` is an input iterator adaptor and
@ -245,37 +433,6 @@ output is active or not. If the state is active, the stream output
operator `<<` uses the internal stream to output its argument. If
the state is inactive, nothing happens.
\section IOstreamWKT WKT Support
WKT stands for <em>Well Known Text</em> and it is a text markup language for representing
vector geometry objects on a geographical map. See the
<A HREF="https://en.wikipedia.org/wiki/Well-known_text">wikipedia page</A> for details.
CGAL supports a subset of WKT types: point, multipoint, linestring, multilinestring, polygon and multipolygon.
Free functions are provided for reading and writing several \cgal types
in those WKT types, namely:
- `CGAL::Point_2`
- `CGAL::Point_3`
- `CGAL::Polygon_with_holes_2`
- random access range of the above types.
\section IOstreamXML Reading Adhoc XML
In case you have to read data in a simple xml file with a simple structure, without existing I/O libraries
the <a href="https://www.boost.org/doc/libs/release/libs/property_tree/">`boost::property_tree`</a> comes in handy.
The following small example shows how to parse a file
looking like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<PolySet>
<Polygon>
<Point X="-715.8811978465" Y="-2729.9490000000" Z="-534.9000000000"/>
<Point X="-718.1905989232" Y="-2729.9490000000" Z="-538.9000000000"/>
<Point X="-722.8094010768" Y="-2729.9490000000" Z="-538.9000000000"/>
</Polygon>
</PolySet>
\cgalExample{Stream_support/read_xml.cpp}
*/
} /* namespace CGAL */

View File

@ -1,6 +1,8 @@
/// \defgroup PkgStreamSupportRef IO Streams Reference
/// \defgroup IOstreamOperators Stream Operators
/// \ingroup PkgStreamSupportRef
/// \defgroup IOstreamFunctions I/O Functions
/// \ingroup PkgStreamSupportRef
/*!
\addtogroup PkgStreamSupportRef
\cgalPkgDescriptionBegin{IO Streams,PkgStreamSupport}
@ -41,6 +43,7 @@ the printing mode.
- \link IOstreamOperators `CGAL::operator<<()` \endlink
- `CGAL::iformat()`
- `CGAL::oformat()`
- `CGAL::read_STL()`
\cgalCRPSection{WKT I/O Functions}
- `CGAL::read_point_WKT()`

View File

@ -1,7 +1,18 @@
Manual
Kernel_23
STL_Extension
Alpha_shapes_3
Arrangement_on_surface_2
BGL
Geomview
Surface_mesh
Kernel_23
Manual
Mesh_2
Mesh_3
Nef_3
Polyhedron
Polygon
Polygon_mesh_processing
Point_set_3
STL_Extension
Surface_mesh
Surface_mesher
Triangulation
Triangulation_2

View File

@ -18,100 +18,14 @@
#ifndef CGAL_IO_FILE_HEADER_OFF_H
#define CGAL_IO_FILE_HEADER_OFF_H 1
#include <CGAL/IO/File_header_extended_OFF.h>
#include <iostream>
namespace CGAL {
#include <CGAL/disable_warnings.h>
// Info structure for OFF file headers
// ===================================
class CGAL_EXPORT File_header_OFF : public File_header_extended_OFF {
private:
// Publicly accessible file informations.
std::size_t n_vertices;
std::size_t n_facets;
bool m_skel; // SKEL format instead of OFF.
bool m_binary; // OFF in binary format.
bool m_no_comments; // no comments in output.
std::size_t m_offset; // index offset for vertices, usually 0.
// Publicly accessible but not that well supported file informations.
bool m_colors; // COFF detected.
bool m_normals; // NOFF format stores also normals at vertices.
// More privately used file informations to scan the file.
bool m_tag4; // 4OFF detected.
bool m_tagDim; // nOFF detected (will not be supported).
int m_dim; // dimension for nOFF (will not be supported).
public:
typedef File_header_OFF Self;
typedef File_header_extended_OFF Base;
explicit File_header_OFF( bool verbose = false);
File_header_OFF( bool binary, bool noc, bool skel,
bool verbose = false);
//File_header_OFF( int v, int h, int f, bool verbose = false);
File_header_OFF( std::size_t v, std::size_t h, std::size_t f,
bool binary, bool noc, bool skel,
bool verbose = false);
File_header_OFF( const File_header_extended_OFF& ext_header);
File_header_OFF( const File_header_extended_OFF& ext_header,
bool binary, bool noc, bool skel);
File_header_OFF( std::size_t v, std::size_t h, std::size_t f,
const File_header_extended_OFF& ext_header);
File_header_OFF( std::size_t v, std::size_t h, std::size_t f,
const File_header_extended_OFF& ext_header,
bool binary, bool noc, bool skel);
Self& operator= ( const Base& base) { (Base&)(*this) = base;
return *this;
}
std::size_t size_of_vertices() const { return n_vertices; }
std::size_t size_of_facets() const { return n_facets; }
bool skel() const { return m_skel; } // SKEL format.
bool off() const { return ! m_skel; } // OFF format.
bool binary() const { return m_binary; } // binary format.
bool ascii() const { return ! m_binary; } // ASCII format.
bool no_comments() const { return m_no_comments; }
bool comments() const { return ! m_no_comments; }
std::size_t index_offset() const { return m_offset; }
bool has_colors() const { return m_colors; } // COFF detected.
bool has_normals() const { return m_normals;} // NOFF format.
bool is_homogeneous() const { return m_tag4; } // 4OFF detected.
// nOFF detected. (will not be supported).
bool n_dimensional() const { return m_tagDim; }
// dimension for nOFF (will not be supported).
int dimension() const { return m_dim; }
void set_vertices( std::size_t n) { n_vertices = n; }
void set_facets( std::size_t n) { n_facets = n; }
void set_skel( bool b) { m_skel = b; }
void set_binary( bool b) { m_binary = b; }
void set_no_comments( bool b) { m_no_comments = b; }
void set_index_offset( std::size_t i) { m_offset = i; }
void set_colors( bool b) { m_colors = b; }
void set_normals( bool b) { m_normals = b;}
void set_homogeneous( bool b) { m_tag4 = b; }
void set_dimensional( bool b) { m_tagDim = b; }
void set_dimension( int i) { m_dim = i; }
Self& operator+=( const Self& header);
};
// Write header.
CGAL_EXPORT std::ostream& operator<<( std::ostream& out, const File_header_OFF& h);
// Scan header. Marks streams badbit if not in SKEL format nor in OFF.
CGAL_EXPORT std::istream& operator>>( std::istream& in, File_header_OFF& h);
} //namespace CGAL
#ifdef CGAL_HEADER_ONLY
#include <CGAL/IO/File_header_OFF_impl.h>
#endif // CGAL_HEADER_ONLY
#define CGAL_DEPRECATED_HEADER "<CGAL/IO/File_header_OFF.h>"
#define CGAL_REPLACEMENT_HEADER "<CGAL/IO/OFF/File_header_OFF.h>"
#include <CGAL/internal/deprecation_warning.h>
#include <CGAL/IO/OFF/File_header_OFF.h>
#include <CGAL/enable_warnings.h>
#endif // CGAL_IO_FILE_HEADER_OFF_H //
// EOF //

View File

@ -19,679 +19,10 @@
#include <CGAL/disable_warnings.h>
#include <CGAL/config.h>
#include <cstddef>
#include <CGAL/IO/binary_file_io.h>
#include <CGAL/IO/File_header_OFF.h>
#include <iostream>
#include <sstream>
#include <boost/cstdint.hpp>
#include <CGAL/Point_3.h>
#include <CGAL/Vector_3.h>
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<File_header_OFF&>( *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 >> iformat(x) >> iformat(y) >> iformat(z);
if ( is_homogeneous()) {
float w;
m_in >> iformat(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 >> iformat(x) >> iformat(y) >> iformat(z);
if ( is_homogeneous()) {
double w;
m_in >> iformat(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 >> iformat(fx) >> iformat(fy) >> iformat(fz) >> iformat(fw);
x = int( fx / fw);
y = int( fy / fw);
z = int( fz / fw);
} else {
double d;
m_in >> iformat(d);
x = int(d);
m_in >> iformat(d);
y = int(d);
m_in >> iformat(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 >> iformat(x) >> iformat(y) >> iformat(z);
if ( is_homogeneous())
m_in >> iformat(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 >> iformat(x);
m_in >> iformat(y);
m_in >> iformat(z);
if ( is_homogeneous())
m_in >> iformat(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 >> iformat(d);
x = int(d);
m_in >> iformat(d);
y = int(d);
m_in >> iformat(d);
z = int(d);
if ( is_homogeneous()) {
m_in >> iformat(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 >> iformat(x) >> iformat(y) >> iformat(z);
if ( is_homogeneous()) {
float w;
m_in >> iformat(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 >> iformat(fx) >> iformat(fy) >> iformat(fz) >> iformat(fw);
x = fx / fw;
y = fy / fw;
z = fz / fw;
} else
m_in >> iformat(x) >> iformat(y) >> iformat(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 >> iformat(fx) >> iformat(fy) >> iformat(fz) >> iformat(fw);
x = int( fx / fw);
y = int( fy / fw);
z = int( fz / fw);
} else {
double d;
m_in >> iformat(d);
x = int(d);
m_in >> iformat(d);
y = int(d);
m_in >> iformat(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 >> iformat(x) >> iformat(y) >> iformat(z);
if ( is_homogeneous())
m_in >> iformat(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 >> iformat(x) >> iformat(y) >> iformat(z);
if ( is_homogeneous())
m_in >> iformat(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 >> iformat(d);
x = int(d);
m_in >> iformat(d);
y = int(d);
m_in >> iformat(d);
z = int(d);
if ( is_homogeneous()) {
m_in >> iformat(d);
w = int(d);
}
}
}
}
static const Color& get_indexed_color(int id)
{
static const Color color[149] = {
Color(255, 255, 255, 191),
Color(255, 255, 255, 191),
Color(255, 255, 255, 191),
Color(255, 255, 255, 191),
Color(255, 255, 255, 191),
Color(255, 255, 255, 191),
Color(178, 38, 25, 191),
Color(51, 51, 204, 191),
Color(229, 153, 5, 191),
Color(25, 76, 204, 191),
Color(25, 178, 51, 191),
Color(204, 204, 102, 191),
Color(178, 178, 0, 191),
Color(178, 0, 178, 191),
Color(0, 178, 178, 191),
Color(229, 0, 51, 191),
Color(51, 229, 0, 191),
Color(0, 51, 229, 191),
Color(191, 191, 191, 191),
Color(204, 102, 0, 191),
Color(204, 102, 0, 191),
Color(0, 102, 204, 191),
Color(0, 102, 204, 191),
Color(0, 204, 102, 191),
Color(0, 204, 102, 191),
Color(102, 0, 204, 191),
Color(102, 0, 204, 191),
Color(204, 0, 102, 191),
Color(204, 0, 102, 191),
Color(178, 127, 51, 191),
Color(178, 127, 51, 191),
Color(178, 178, 0, 191),
Color(178, 0, 178, 191),
Color(0, 178, 178, 191),
Color(229, 0, 0, 191),
Color(0, 229, 0, 191),
Color(0, 0, 229, 191),
Color(191, 191, 191, 191),
Color(204, 102, 0, 191),
Color(102, 204, 0, 191),
Color(0, 102, 204, 191),
Color(0, 204, 102, 191),
Color(102, 0, 204, 191),
Color(204, 0, 102, 191),
Color(178, 178, 0, 191),
Color(178, 0, 178, 191),
Color(0, 178, 178, 191),
Color(229, 0, 0, 191),
Color(0, 229, 0, 191),
Color(0, 0, 229, 191),
Color(191, 191, 191, 191),
Color(204, 102, 0, 191),
Color(102, 204, 0, 191),
Color(0, 102, 204, 191),
Color(0, 204, 102, 191),
Color(102, 0, 204, 191),
Color(204, 0, 102, 191),
Color(178, 178, 0, 191),
Color(178, 0, 178, 191),
Color(0, 178, 178, 191),
Color(229, 0, 0, 191),
Color(0, 229, 0, 191),
Color(0, 0, 229, 191),
Color(191, 191, 191, 191),
Color(204, 102, 0, 191),
Color(102, 204, 0, 191),
Color(0, 102, 204, 191),
Color(0, 204, 102, 191),
Color(102, 0, 204, 191),
Color(204, 0, 102, 191),
Color(255, 255, 255, 191),
Color(255, 255, 255, 191),
Color(255, 255, 255, 191),
Color(255, 255, 255, 191),
Color(255, 255, 255, 191),
Color(255, 255, 255, 191),
Color(12, 76, 25, 191),
Color(178, 2, 25, 191),
Color(51, 12, 153, 191),
Color(229, 229, 5, 191),
Color(0, 51, 102, 191),
Color(25, 102, 102, 191),
Color(204, 204, 204, 191),
Color(178, 178, 0, 191),
Color(178, 178, 0, 191),
Color(178, 0, 178, 191),
Color(178, 0, 178, 191),
Color(0, 178, 178, 191),
Color(0, 178, 178, 191),
Color(229, 0, 0, 191),
Color(229, 0, 0, 191),
Color(0, 229, 0, 191),
Color(0, 229, 0, 191),
Color(0, 0, 229, 191),
Color(0, 0, 229, 191),
Color(191, 191, 191, 191),
Color(191, 191, 191, 191),
Color(204, 102, 0, 191),
Color(204, 102, 0, 191),
Color(0, 102, 204, 191),
Color(0, 102, 204, 191),
Color(0, 204, 102, 191),
Color(0, 204, 102, 191),
Color(102, 0, 204, 191),
Color(102, 0, 204, 191),
Color(204, 0, 102, 191),
Color(204, 0, 102, 191),
Color(178, 127, 51, 191),
Color(178, 127, 51, 191),
Color(178, 178, 0, 191),
Color(178, 0, 178, 191),
Color(0, 178, 178, 191),
Color(229, 0, 0, 191),
Color(0, 229, 0, 191),
Color(0, 0, 229, 191),
Color(191, 191, 191, 191),
Color(204, 102, 0, 191),
Color(102, 204, 0, 191),
Color(0, 102, 204, 191),
Color(0, 204, 102, 191),
Color(102, 0, 204, 191),
Color(204, 0, 102, 191),
Color(178, 178, 0, 191),
Color(178, 0, 178, 191),
Color(0, 178, 178, 191),
Color(229, 0, 0, 191),
Color(0, 229, 0, 191),
Color(0, 0, 229, 191),
Color(191, 191, 191, 191),
Color(204, 102, 0, 191),
Color(102, 204, 0, 191),
Color(0, 102, 204, 191),
Color(0, 204, 102, 191),
Color(102, 0, 204, 191),
Color(204, 0, 102, 191),
Color(178, 178, 0, 191),
Color(178, 0, 178, 191),
Color(0, 178, 178, 191),
Color(229, 0, 0, 191),
Color(0, 229, 0, 191),
Color(0, 0, 229, 191),
Color(191, 191, 191, 191),
Color(204, 102, 0, 191),
Color(102, 204, 0, 191),
Color(0, 102, 204, 191),
Color(0, 204, 102, 191),
Color(102, 0, 204, 191),
Color(204, 0, 102, 191),
Color(120, 120, 120, 120) };
if(id > 148) id =148;
return color[id];
}
static CGAL::Color get_color_from_line(std::istream &is)
{
std::string color_info;
bool is_float = false;
std::string col;
//get the line content
std::getline(is, col);
//split it into strings
std::istringstream iss(col);
//holds the rgb values
unsigned char rgb[3];
int index =0;
//split the string into numbers
while(iss>>color_info){
//stop if comment is read
if(color_info.at(0) == '#')
break;
//detect if the value is float
for(int c = 0; c<static_cast<int>(color_info.length()); c++)
{
if(color_info.at(c) == '.')
{
is_float = true;
break;
}
}
//if the value is of float type, convert it into an int
if(is_float)
rgb[index] = static_cast<unsigned char>(atof(color_info.c_str())*255);
//else stores the value
else
rgb[index] = static_cast<unsigned char>(atoi(color_info.c_str()));
index++;
if(index == 3)
break;
}
CGAL::Color color;
//if there were only one number, fetch the color in the color map
if(index<2)
color = get_indexed_color(rgb[0]);
//else create the coor with the 3 values;
else
color = CGAL::Color(rgb[0], rgb[1], rgb[2]);
return color;
}
void scan_color( unsigned char& r, unsigned char& g, unsigned char& b) {
if ( binary()) {
float fr, fg, fb;
I_Binary_read_big_endian_float32( m_in, fr);
I_Binary_read_big_endian_float32( m_in, fg);
I_Binary_read_big_endian_float32( m_in, fb);
r = (unsigned char)(fr);
g = (unsigned char)(fg);
b = (unsigned char)(fb);
} else {
CGAL::Color color = get_color_from_line(m_in);
r = color.red();
g = color.green();
b = color.blue();
}
}
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 T_Color> inline
T_Color&
file_scan_color( File_scanner_OFF& scanner, T_Color& c) {
unsigned char r, g, b;
scanner.scan_color(r,g,b);
c = T_Color(r,g,b);
return c;
}
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
#ifdef CGAL_HEADER_ONLY
#include <CGAL/IO/File_scanner_OFF_impl.h>
#endif // CGAL_HEADER_ONLY
#define CGAL_DEPRECATED_HEADER "<CGAL/IO/File_scanner_OFF.h>"
#define CGAL_REPLACEMENT_HEADER "<CGAL/IO/OFF/File_scanner_OFF.h>"
#include <CGAL/internal/deprecation_warning.h>
#include <CGAL/IO/OFF/File_scanner_OFF.h>
#include <CGAL/enable_warnings.h>
#endif // CGAL_IO_FILE_SCANNER_OFF_H //

View File

@ -17,89 +17,13 @@
#ifndef CGAL_IO_FILE_WRITER_OFF_H
#define CGAL_IO_FILE_WRITER_OFF_H 1
#include <CGAL/IO/binary_file_io.h>
#include <CGAL/IO/File_header_OFF.h>
#include <iostream>
#include <cstddef>
#include <CGAL/disable_warnings.h>
namespace CGAL {
class CGAL_EXPORT File_writer_OFF {
std::ostream* m_out;
File_header_OFF m_header;
public:
File_writer_OFF( bool verbose = false) : m_header( verbose) {}
File_writer_OFF( const File_header_OFF& h) : m_header( h) {}
std::ostream& out() { return *m_out; }
File_header_OFF& header() { return m_header; }
const File_header_OFF& header() const { return m_header; }
void write_header( std::ostream& out,
std::size_t vertices,
std::size_t halfedges,
std::size_t facets,
bool normals = false);
void write_footer() {
if ( m_header.ascii() && m_header.comments())
out() << "\n\n# End of OFF #";
out() << std::endl;
}
void write_vertex( const double& x, const double& y, const double& z) {
if ( m_header.binary()) {
I_Binary_write_big_endian_float32( out(), float(x));
I_Binary_write_big_endian_float32( out(), float(y));
I_Binary_write_big_endian_float32( out(), float(z));
} else {
out() << '\n' << x << ' ' << y << ' ' << z;
}
}
void write_normal( const double& x, const double& y, const double& z) {
if ( m_header.binary()) {
I_Binary_write_big_endian_float32( out(), float(x));
I_Binary_write_big_endian_float32( out(), float(y));
I_Binary_write_big_endian_float32( out(), float(z));
} else {
out() << ' ' << ' ' << x << ' ' << y << ' ' << z;
}
}
void write_facet_header() {
if ( m_header.ascii()) {
if ( m_header.no_comments())
out() << '\n';
else {
out() << "\n\n# " << m_header.size_of_facets()
<< " facets\n";
out() << "# ------------------------------------------"
"\n\n";
}
}
}
void write_facet_begin( std::size_t no) {
if ( m_header.binary())
I_Binary_write_big_endian_integer32( out(), static_cast<boost::int32_t>(no));
else
out() << no << ' ';
}
void write_facet_vertex_index( std::size_t index) {
if ( m_header.binary())
I_Binary_write_big_endian_integer32( out(), static_cast<boost::int32_t>(index));
else
out() << ' ' << index;
}
void write_facet_end() {
if ( m_header.binary())
I_Binary_write_big_endian_integer32( out(), 0);
else
out() << '\n';
}
};
} //namespace CGAL
#ifdef CGAL_HEADER_ONLY
#include <CGAL/IO/File_writer_OFF_impl.h>
#endif // CGAL_HEADER_ONLY
#define CGAL_DEPRECATED_HEADER "<CGAL/IO/File_write_OFF.h>"
#define CGAL_REPLACEMENT_HEADER "<CGAL/IO/OFF/File_writer_OFF.h>"
#include <CGAL/internal/deprecation_warning.h>
#include <CGAL/IO/OFF/File_writer_OFF.h>
#include <CGAL/enable_warnings.h>
#endif // CGAL_IO_FILE_WRITER_OFF_H //
// EOF //

View File

@ -17,44 +17,16 @@
#ifndef CGAL_IO_FILE_WRITER_WAVEFRONT_H
#define CGAL_IO_FILE_WRITER_WAVEFRONT_H 1
#include <CGAL/IO/binary_file_io.h>
#include <iostream>
#include <cstddef>
namespace CGAL {
class CGAL_EXPORT File_writer_wavefront {
std::ostream* m_out;
std::size_t m_facets;
public:
std::ostream& out() const { return *m_out; }
void write_header( std::ostream& out,
std::size_t vertices,
std::size_t halfedges,
std::size_t facets);
void write_footer() const {
out() << "\n# End of Wavefront obj format #" << std::endl;
}
void write_vertex( const double& x, const double& y, const double& z) {
out() << "v " << x << ' ' << y << ' ' << z << '\n';
#include <CGAL/disable_warnings.h>
}
void write_vertex_normal( const double& x, const double& y, const double& z) {
out() << "vn " << x << ' ' << y << ' ' << z << '\n';
}
void write_facet_header() {
out() << "\n# " << m_facets << " facets\n";
out() << "# ------------------------------------------\n\n";
}
void write_facet_begin( std::size_t) { out() << "f "; }
void write_facet_vertex_index( std::size_t idx) { out() << ' ' << idx+1; }
void write_facet_end() { out() << '\n'; }
};
} //namespace CGAL
#ifdef CGAL_HEADER_ONLY
#include <CGAL/IO/File_writer_wavefront_impl.h>
#endif // CGAL_HEADER_ONLY
#define CGAL_DEPRECATED_HEADER "<CGAL/IO/File_writer_wavefront.h>"
#define CGAL_REPLACEMENT_HEADER "<CGAL/IO/OBJ/File_writer_wavefront.h>"
#include <CGAL/internal/deprecation_warning.h>
#include <CGAL/IO/OBJ/File_writer_wavefront.h>
#include <CGAL/enable_warnings.h>
#endif // CGAL_IO_FILE_WRITER_WAVEFRONT_H //
// EOF //

View File

@ -0,0 +1,66 @@
// 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$
// SPDX-License-Identifier: LGPL-3.0+
//
//
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
#ifndef CGAL_IO_OBJ_FILE_WRITER_WAVEFRONT_H
#define CGAL_IO_OBJ_FILE_WRITER_WAVEFRONT_H 1
#include <CGAL/IO/binary_file_io.h>
#include <iostream>
#include <cstddef>
namespace CGAL {
class CGAL_EXPORT File_writer_wavefront {
std::ostream* m_out;
std::size_t m_facets;
public:
std::ostream& out() const { return *m_out; }
void write_header( std::ostream& out,
std::size_t vertices,
std::size_t halfedges,
std::size_t facets);
void write_footer() const {
out() << "\n# End of Wavefront obj format #" << std::endl;
}
void write_vertex( const double& x, const double& y, const double& z) {
out() << "v " << x << ' ' << y << ' ' << z << '\n';
}
void write_facet_header() {
out() << "\n# " << m_facets << " facets\n";
out() << "# ------------------------------------------\n\n";
}
void write_facet_begin( std::size_t) { out() << "f "; }
void write_facet_vertex_index( std::size_t idx) { out() << ' ' << idx+1; }
void write_facet_end() { out() << '\n'; }
};
} //namespace CGAL
#ifdef CGAL_HEADER_ONLY
#include <CGAL/IO/OBJ/File_writer_wavefront_impl.h>
#endif // CGAL_HEADER_ONLY
#endif // CGAL_IO_OBJ_FILE_WRITER_WAVEFRONT_H //
// EOF //

View File

@ -22,7 +22,7 @@
#include <CGAL/basic.h>
#include <iostream>
#include <CGAL/IO/File_writer_wavefront.h>
#include <CGAL/IO/OBJ/File_writer_wavefront.h>
namespace CGAL {

View File

@ -0,0 +1,89 @@
// Copyright (c) 2016 GeometryFactory
//
// 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) : Andreas Fabri and Maxime Gimeno
#ifndef CGAL_IO_OBJ_OBJ_READER_H
#define CGAL_IO_OBJ_OBJ_READER_H
#include <istream>
#include <sstream>
#include <vector>
#include <limits>
namespace CGAL {
//Points_3 a RandomAccessContainer of Point_3,
//Faces a RandomAccessContainer of RandomAccessContainer of std::size_t
template <class Points_3, class Faces>
bool
read_OBJ( std::istream& input,
Points_3 &points,
Faces &faces)
{
typedef typename Points_3::value_type Point_3;
int mini(1),
maxi(-INT_MAX);
Point_3 p;
std::string line;
while(getline(input, line)) {
if(line[0] == 'v' && line[1] == ' ') {
std::istringstream iss(line.substr(1));
iss >> p;
if(!iss)
return false;
points.push_back(p);
}
else if(line[0] == 'f') {
std::istringstream iss(line.substr(1));
int i;
faces.push_back( std::vector<std::size_t>() );
while(iss >> i)
{
if(i < 1)
{
faces.back().push_back(points.size()+i);//negative indices are relative references
if(i<mini)
mini=i;
}
else {
faces.back().push_back(i-1);
if(i-1 > maxi)
maxi = i-1;
}
iss.ignore(256, ' ');
}
if(!iss.good() && !iss.eof())
return false;
}
else
{
//std::cerr<<"ERROR : Cannnot read line beginning with "<<line[0]<<std::endl;
continue;
}
}
if(maxi > points.size() || mini < -static_cast<int>(points.size())){
std::cerr<<"a face index is invalid "<<std::endl;
return false;
}
return true;
}
} // namespace CGAL
#endif // CGAL_IO_OBJ_OBJ_READER_H

Some files were not shown because too many files have changed in this diff Show More