mirror of https://github.com/CGAL/cgal
207 lines
6.7 KiB
C++
207 lines
6.7 KiB
C++
// Glue vertices of a polyhedron together that have equal coordinate values.
|
|
|
|
#include <CGAL/Simple_cartesian.h>
|
|
#include <CGAL/IO/Verbose_ostream.h>
|
|
#include <CGAL/IO/File_scanner_OFF.h>
|
|
#include <CGAL/IO/File_writer_OFF.h>
|
|
#include <cstddef>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <vector>
|
|
#include <algorithm>
|
|
|
|
using namespace std;
|
|
|
|
typedef CGAL::Simple_cartesian<double> Kernel;
|
|
typedef Kernel::Point_3 Point;
|
|
typedef Kernel::Vector_3 Vector;
|
|
struct Vertex {
|
|
Point point;
|
|
Vector normal;
|
|
int index;
|
|
};
|
|
typedef vector<Vertex> Vertex_vector;
|
|
typedef Vertex_vector::iterator VIterator;
|
|
|
|
struct VertexComp {
|
|
bool operator()( const Vertex* v, const Vertex* w) const {
|
|
return ( v->point.x() < w->point.x() ||
|
|
(v->point.x() == w->point.x() && v->point.y() < w->point.y()) ||
|
|
(v->point.x() == w->point.x() && (v->point.y() == w->point.y()
|
|
&& v->point.z() < w->point.z())));
|
|
}
|
|
};
|
|
|
|
bool verbose = false;
|
|
bool binary = false;
|
|
bool skel = false;
|
|
bool noc = false;
|
|
|
|
// main function with standard unix commandline arguments
|
|
// ------------------------------------------------------
|
|
int main( int argc, char **argv) {
|
|
int n = 0; // number of filenames
|
|
char *filename[2];
|
|
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( "-h", argv[i]) == 0) ||
|
|
(strcmp( "-help", argv[i]) == 0))
|
|
help = true;
|
|
else if ( n < 2 ) {
|
|
filename[ n++] = argv[i];
|
|
} else {
|
|
++n;
|
|
break;
|
|
}
|
|
}
|
|
if ((n > 2) || help) {
|
|
if ( ! help)
|
|
cerr << "Error: in parameter list" << endl;
|
|
cerr << "Usage: " << argv[0] << " [<options>] [<infile> [<outfile>]]"
|
|
<< endl;
|
|
cerr << " glues vertices of equal coordinates together." << 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;
|
|
|
|
const char* name = "<cin>";
|
|
istream* p_in = &cin;
|
|
ifstream in;
|
|
if ( n > 0) {
|
|
in.open( filename[0]);
|
|
p_in = ∈
|
|
name = filename[0];
|
|
}
|
|
if ( !in) {
|
|
cerr << argv[0] << ": error: cannot open file '"<< name
|
|
<< "' for reading." <<endl;
|
|
exit( 1);
|
|
}
|
|
|
|
CGAL::File_scanner_OFF scanner( * p_in);
|
|
if ( ! (*p_in)) {
|
|
cerr << " " << endl;
|
|
cerr << argv[0] << ": input error: file format is not in OFF." << endl;
|
|
std::abort();
|
|
}
|
|
Vertex_vector vertices;
|
|
vector<Vertex*> sorted_vertices;
|
|
// Avoid any reallocation
|
|
vertices.reserve( scanner.size_of_vertices());
|
|
sorted_vertices.reserve( scanner.size_of_vertices());
|
|
|
|
float x, y, z;
|
|
for (std::size_t i = 0; i < scanner.size_of_vertices(); i++) {
|
|
Vertex vertex;
|
|
scanner.scan_vertex( x, y, z);
|
|
vertex.point = Point( x, y, z);
|
|
//scanner.scan_normal( x, y, z);
|
|
vertex.normal = Vector( x, y, z);
|
|
scanner.skip_to_next_vertex( i);
|
|
vertex.index = -1;
|
|
vertices.push_back( vertex);
|
|
sorted_vertices.push_back( & vertices.back());
|
|
}
|
|
vout << scanner.size_of_vertices() << " vertices read." << endl;
|
|
|
|
sort( sorted_vertices.begin(), sorted_vertices.end(), VertexComp());
|
|
int current_index = 0;
|
|
sorted_vertices[0]->index = 0;
|
|
for (std::size_t i = 1; i < scanner.size_of_vertices(); i++) {
|
|
if ( sorted_vertices[i]->point != sorted_vertices[i-1]->point)
|
|
current_index++;
|
|
sorted_vertices[i]->index = current_index;
|
|
}
|
|
current_index++;
|
|
vout << "Merged to " << current_index << " vertices." << endl;
|
|
|
|
const char* oname = "<cout>";
|
|
ostream* p_out = &cout;
|
|
ofstream out;
|
|
if ( 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,
|
|
current_index,
|
|
0,
|
|
scanner.size_of_facets(),
|
|
scanner.has_normals());
|
|
vector<Vertex*>::iterator v = sorted_vertices.begin();
|
|
writer.write_vertex((*v)->point.x(), (*v)->point.y(), (*v)->point.z());
|
|
if ( scanner.has_normals()) {
|
|
writer.write_normal((*v)->normal.x(),
|
|
(*v)->normal.y(),
|
|
(*v)->normal.z());
|
|
}
|
|
++v;
|
|
for ( ; v != sorted_vertices.end(); ++v) {
|
|
if ( (*v)->index != (*(v-1))->index) {
|
|
writer.write_vertex( (*v)->point.x(),
|
|
(*v)->point.y(),
|
|
(*v)->point.z());
|
|
if ( scanner.has_normals()) {
|
|
writer.write_normal( (*v)->normal.x(),
|
|
(*v)->normal.y(),
|
|
(*v)->normal.z());
|
|
}
|
|
}
|
|
}
|
|
|
|
// Copy facets and translate vertex indices.
|
|
writer.write_facet_header();
|
|
for (std::size_t i = 0; i < scanner.size_of_facets(); i++) {
|
|
std::size_t no; // number of vertices of a facet.
|
|
scanner.scan_facet( no, i);
|
|
writer.write_facet_begin( no);
|
|
for ( std::size_t j = 0; j < no; j++) {
|
|
std::size_t index;
|
|
scanner.scan_facet_vertex_index( index, i);
|
|
writer.write_facet_vertex_index( vertices[index].index);
|
|
}
|
|
scanner.skip_to_next_facet( i);
|
|
writer.write_facet_end();
|
|
}
|
|
writer.write_footer();
|
|
vout << " .... done." << endl;
|
|
|
|
if ( ! * p_in) {
|
|
cerr << argv[0] << " read error: while reading file '"<< name << "'."
|
|
<< endl;
|
|
exit( 1);
|
|
}
|
|
if ( !*p_out) {
|
|
cerr << argv[0] << " write error: while writing file '"<< oname
|
|
<< "'." << endl;
|
|
exit( 1);
|
|
}
|
|
return 0;
|
|
}
|