mirror of https://github.com/CGAL/cgal
- Unify the Facegraph builders (GOCAD and STL for now)
- Make a BGL STL_reader - Add a test for it.
This commit is contained in:
parent
6dbf2d3d78
commit
6638d51fe8
|
|
@ -39,7 +39,8 @@
|
|||
#include <CGAL/IO/VTK/vtk_internals.h>
|
||||
#endif
|
||||
#include <CGAL/IO/write_vtk.h>
|
||||
#include <CGAL/IO/GOCAD/Build_from_gocad.h>
|
||||
#include <CGAL/internal/Generic_facegraph_builder.h>
|
||||
#include <CGAL/IO/STL/STL_reader.h>
|
||||
|
||||
namespace CGAL {
|
||||
/*!
|
||||
|
|
@ -411,10 +412,10 @@ bool write_inp(std::ostream& os,
|
|||
namespace GOCAD_internal{
|
||||
//Use CRTP to gain access to the protected members without getters/setters.
|
||||
template <class Facegraph, class P>
|
||||
class GOCAD_builder : public Build_from_gocad<Facegraph, P, GOCAD_builder<Facegraph, P> >
|
||||
class GOCAD_builder : public CGAL::internal::IO::Generic_facegraph_builder<Facegraph, P, GOCAD_builder<Facegraph, P> >
|
||||
{
|
||||
typedef GOCAD_builder<Facegraph, P> Self;
|
||||
typedef Build_from_gocad<Facegraph, P, Self> Base;
|
||||
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;
|
||||
|
|
@ -437,13 +438,64 @@ public:
|
|||
|
||||
for(size_type i=0; i < this->mesh.size(); i++){
|
||||
std::array<vertex_descriptor, 3> face;
|
||||
face[0] = vertices[this->mesh[i].template get<0>()];
|
||||
face[1] = vertices[this->mesh[i].template get<1>()];
|
||||
face[2] = vertices[this->mesh[i].template get<2>()];
|
||||
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
|
||||
|
||||
|
|
@ -912,6 +964,67 @@ write_STL(const TriangleMesh& tm, std::ostream& out)
|
|||
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
|
||||
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 CGAL
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -162,22 +162,65 @@ bool test_gocad()
|
|||
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;
|
||||
#ifdef CGAL_USE_OPENMESH
|
||||
test_bgl_read_write<OMesh>(filename);
|
||||
#endif
|
||||
//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;
|
||||
|
|
|
|||
|
|
@ -1,111 +0,0 @@
|
|||
// Copyright (c) 2019 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) : Maxime Gimeno
|
||||
|
||||
#ifndef CGAL_IO_GOCAD_BUILD_FROM_GOCAD_H
|
||||
#define CGAL_IO_GOCAD_BUILD_FROM_GOCAD_H
|
||||
|
||||
#include <deque>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace CGAL{
|
||||
|
||||
namespace GOCAD_internal {
|
||||
template <class Facegraph, class P, class Derived>
|
||||
class Build_from_gocad
|
||||
{
|
||||
protected:
|
||||
typedef P Point_3;
|
||||
typedef std::deque<Point_3> Points_3;
|
||||
typedef boost::tuple<int,int,int> Facet;
|
||||
typedef std::deque<Facet> Surface;
|
||||
|
||||
public:
|
||||
std::string name, color;
|
||||
Build_from_gocad(std::istream& is_)
|
||||
: is(is_), counter(0)
|
||||
{}
|
||||
|
||||
void do_construct(){} //specific to Facegraph (declared in BGL)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void operator()( Facegraph& graph)
|
||||
{
|
||||
read(this->is, this->meshPoints, this->mesh);
|
||||
static_cast<Derived*>(this)->do_construct(graph);
|
||||
}
|
||||
|
||||
protected:
|
||||
std::istream& is;
|
||||
int counter;
|
||||
Points_3 meshPoints;
|
||||
Surface mesh;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}//end GOCAD_internal
|
||||
}//end CGAL
|
||||
#endif // CGAL_IO_GOCAD_BUILD_FROM_GOCAD_H
|
||||
|
||||
|
|
@ -34,14 +34,17 @@
|
|||
|
||||
namespace CGAL {
|
||||
|
||||
template <class Point, class Triangle>
|
||||
template <class PointRange, class TriangleRange, typename IndexMap>
|
||||
bool read_ASCII_facet(std::istream& input,
|
||||
std::vector<Point>& points,
|
||||
std::vector<Triangle>& facets,
|
||||
PointRange& points,
|
||||
TriangleRange& facets,
|
||||
int& index,
|
||||
std::map<Point, int >& index_map,
|
||||
IndexMap& index_map,
|
||||
bool verbose = false)
|
||||
{
|
||||
typedef typename PointRange::value_type Point;
|
||||
typedef typename TriangleRange::value_type Triangle;
|
||||
|
||||
// Here, we have already read the word 'facet' and are looking to read till 'endfacet'
|
||||
|
||||
std::string s;
|
||||
|
|
@ -113,12 +116,14 @@ bool read_ASCII_facet(std::istream& input,
|
|||
return false;
|
||||
}
|
||||
|
||||
template <class Point, class Triangle>
|
||||
template <class PointRange, class TriangleRange>
|
||||
bool parse_ASCII_STL(std::istream& input,
|
||||
std::vector<Point>& points,
|
||||
std::vector<Triangle>& facets,
|
||||
PointRange& points,
|
||||
TriangleRange& facets,
|
||||
bool verbose = false)
|
||||
{
|
||||
typedef typename PointRange::value_type Point;
|
||||
typedef typename TriangleRange::value_type Triangle;
|
||||
if(verbose)
|
||||
std::cout << "Parsing ASCII file..." << std::endl;
|
||||
|
||||
|
|
@ -162,12 +167,15 @@ bool parse_ASCII_STL(std::istream& input,
|
|||
return true;
|
||||
}
|
||||
|
||||
template <typename Point, typename Triangle>
|
||||
template <class PointRange, class TriangleRange>
|
||||
bool parse_binary_STL(std::istream& input,
|
||||
std::vector<Point>& points,
|
||||
std::vector<Triangle>& facets,
|
||||
PointRange& points,
|
||||
TriangleRange& facets,
|
||||
bool verbose = false)
|
||||
{
|
||||
typedef typename PointRange::value_type Point;
|
||||
typedef typename TriangleRange::value_type Triangle;
|
||||
|
||||
if(verbose)
|
||||
std::cout << "Parsing binary file..." << std::endl;
|
||||
|
||||
|
|
@ -301,10 +309,10 @@ bool parse_binary_STL(std::istream& input,
|
|||
// 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>
|
||||
template <class PointRange, class TriangleRange>
|
||||
bool read_STL(std::istream& input,
|
||||
std::vector<Point>& points,
|
||||
std::vector<Triangle>& facets,
|
||||
PointRange& points,
|
||||
TriangleRange& facets,
|
||||
bool verbose = false)
|
||||
{
|
||||
int pos = 0;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
// Copyright (c) 2019 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) : Maxime Gimeno
|
||||
|
||||
#ifndef CGAL_INTERNAL_IO_GENERIC_FACEGRAPH_BUILDER_H
|
||||
#define CGAL_INTERNAL_IO_GENERIC_FACEGRAPH_BUILDER_H
|
||||
|
||||
#include <deque>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace CGAL{
|
||||
|
||||
namespace internal {
|
||||
namespace IO{
|
||||
template <class Facegraph, class P, class Derived>
|
||||
class Generic_facegraph_builder
|
||||
{
|
||||
protected:
|
||||
typedef P Point_3;
|
||||
typedef std::deque<Point_3> Points_3;
|
||||
typedef std::vector<int> Facet;
|
||||
typedef std::deque<Facet> Surface;
|
||||
|
||||
public:
|
||||
std::string name, color;
|
||||
Generic_facegraph_builder(std::istream& is_)
|
||||
: is(is_), counter(0)
|
||||
{}
|
||||
|
||||
void do_construct(){} //specific to Facegraph (declared in BGL)
|
||||
void
|
||||
read(std::istream&, Points_3&, Surface&) {}
|
||||
|
||||
void operator()( Facegraph& graph)
|
||||
{
|
||||
static_cast<Derived*>(this)->read(this->is, this->meshPoints, this->mesh);
|
||||
static_cast<Derived*>(this)->do_construct(graph);
|
||||
}
|
||||
|
||||
protected:
|
||||
std::istream& is;
|
||||
int counter;
|
||||
Points_3 meshPoints;
|
||||
Surface mesh;
|
||||
};
|
||||
|
||||
|
||||
} //end IO
|
||||
}//end internal
|
||||
}//end CGAL
|
||||
#endif // CGAL_INTERNAL_IO_GENERIC_FACEGRAPH_BUILDER_H
|
||||
Loading…
Reference in New Issue