mirror of https://github.com/CGAL/cgal
Merge branch 'CGAL_IO-maxGimeno-old' into CGAL_IO-maxGimeno
This commit is contained in:
commit
d620198049
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -25,11 +25,6 @@
|
|||
#include <sstream>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
//-------------------------------------------------------
|
||||
// IO functions
|
||||
//-------------------------------------------------------
|
||||
|
||||
template <class C3T3>
|
||||
void
|
||||
output_to_maya(std::ostream& os,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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()
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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 //
|
||||
|
|
@ -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()
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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.
|
||||
|
||||
*/
|
||||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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()`
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 //
|
||||
|
|
|
|||
|
|
@ -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 //
|
||||
|
|
|
|||
|
|
@ -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 //
|
||||
|
|
|
|||
|
|
@ -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 //
|
||||
|
|
|
|||
|
|
@ -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 //
|
||||
|
|
@ -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 {
|
||||
|
||||
|
|
@ -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
Loading…
Reference in New Issue