Simplify Ply_interpreter writing for users

This commit is contained in:
Simon Giraudot 2016-01-20 11:42:13 +01:00
parent f41b337e84
commit 1fafd34d32
1 changed files with 70 additions and 37 deletions

View File

@ -324,36 +324,75 @@ namespace internal {
bool read_ply_content (std::istream& stream, bool read_ply_content (std::istream& stream,
PlyInterpreter& interpreter, PlyInterpreter& interpreter,
const std::size_t nb_points, const std::size_t nb_points,
std::vector<CGAL::Ply_read_number*>& readers,
const Kernel& /*kernel*/) const Kernel& /*kernel*/)
{ {
std::size_t points_read = 0; std::size_t points_read = 0;
while (!(stream.eof()) && points_read < nb_points) while (!(stream.eof()) && points_read < nb_points)
{ {
for (std::size_t i = 0; i < readers.size (); ++ i) interpreter.get_line (stream);
readers[i]->get (stream); interpreter.process_line ();
interpreter (readers);
points_read++; points_read++;
} }
// Skip remaining lines // Skip remaining lines
for (std::size_t i = 0; i < readers.size (); ++ i)
delete readers[i];
return (points_read == nb_points); return (points_read == nb_points);
} }
} //namespace internal } //namespace internal
class Ply_abstract_interpreter
{
const std::vector<Ply_read_number*>* m_readers;
public:
Ply_abstract_interpreter () : m_readers (NULL) { }
virtual ~Ply_abstract_interpreter () { }
virtual bool init (const std::vector<Ply_read_number*>& readers)
{
m_readers = &readers;
return true;
}
virtual void get_line (std::istream& stream)
{
for (std::size_t i = 0; i < m_readers->size (); ++ i)
(*m_readers)[i]->get (stream);
}
virtual void process_line () = 0;
protected:
bool does_reader_exist (const char* tag)
{
for (std::size_t i = 0; i < m_readers->size (); ++ i)
if ((*m_readers)[i]->name () == tag)
return true;
return false;
}
template <typename T>
void assign (T& t, const char* tag)
{
for (std::size_t i = 0; i < m_readers->size (); ++ i)
if ((*m_readers)[i]->name () == tag)
{
(*m_readers)[i]->assign (t);
return;
}
}
};
template <typename OutputIteratorValueType, template <typename OutputIteratorValueType,
typename OutputIterator, typename OutputIterator,
typename PointPMap, typename PointPMap,
typename NormalPMap, typename NormalPMap,
typename Kernel> typename Kernel>
class Ply_interpreter_point_and_normal_3 class Ply_interpreter_point_and_normal_3 : public Ply_abstract_interpreter
{ {
// value_type_traits is a workaround as back_insert_iterator's value_type is void // value_type_traits is a workaround as back_insert_iterator's value_type is void
// typedef typename value_type_traits<OutputIterator>::type Enriched_point; // typedef typename value_type_traits<OutputIterator>::type Enriched_point;
@ -370,41 +409,30 @@ public:
Ply_interpreter_point_and_normal_3 (OutputIterator output, Ply_interpreter_point_and_normal_3 (OutputIterator output,
PointPMap& point_pmap, PointPMap& point_pmap,
NormalPMap& normal_pmap) NormalPMap& normal_pmap)
: m_output (output), : Ply_abstract_interpreter(),
m_output (output),
m_point_pmap (point_pmap), m_point_pmap (point_pmap),
m_normal_pmap (normal_pmap) m_normal_pmap (normal_pmap)
{ } { }
bool is_applicable (const std::vector<Ply_read_number*>& readers) bool init (const std::vector<Ply_read_number*>& readers)
{ {
bool x_found = false, y_found = false, z_found = false; Ply_abstract_interpreter::init (readers);
for (std::size_t i = 0; i < readers.size (); ++ i)
if (readers[i]->name () == "x")
x_found = true;
else if (readers[i]->name () == "y")
y_found = true;
else if (readers[i]->name () == "z")
z_found = true;
return x_found && y_found && z_found; return does_reader_exist ("x")
&& does_reader_exist ("y")
&& does_reader_exist ("z");
} }
void operator() (const std::vector<Ply_read_number*>& readers) void process_line ()
{ {
FT x, y, z, nx, ny, nz; FT x, y, z, nx, ny, nz;
for (std::size_t i = 0; i < readers.size (); ++ i) assign (x, "x");
if (readers[i]->name () == "x") assign (y, "y");
readers[i]->assign (x); assign (z, "z");
else if (readers[i]->name () == "y") assign (nx, "nx");
readers[i]->assign (y); assign (ny, "ny");
else if (readers[i]->name () == "z") assign (nz, "nz");
readers[i]->assign (z);
else if (readers[i]->name () == "nx")
readers[i]->assign (nx);
else if (readers[i]->name () == "ny")
readers[i]->assign (ny);
else if (readers[i]->name () == "nz")
readers[i]->assign (nz);
Point point (x, y, z); Point point (x, y, z);
Vector normal (nx, ny, nz); Vector normal (nx, ny, nz);
@ -452,13 +480,18 @@ bool read_ply_custom_points(std::istream& stream, ///< input stream.
if (!(internal::read_ply_header (stream, nb_points, readers))) if (!(internal::read_ply_header (stream, nb_points, readers)))
return false; return false;
if (!(interpreter.is_applicable (readers))) if (!(interpreter.init (readers)))
{ {
std::cerr << "Error: PLY interpreter is not applicable to input file" << std::endl; std::cerr << "Error: PLY interpreter is not applicable to input file" << std::endl;
return false; return false;
} }
return internal::read_ply_content (stream, interpreter, nb_points, readers, kernel); bool success = internal::read_ply_content (stream, interpreter, nb_points, kernel);
for (std::size_t i = 0; i < readers.size (); ++ i)
delete readers[i];
return success;
} }