54 #include <OpenMesh/Core/IO/MeshIO.hh>
55 #include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
58 #include <OpenMesh/Tools/Utils/getopt.h>
74 void usage_and_exit(
int xcode)
79 cout <<
"\nUsage: mconvert [option] <input> [<output>]\n\n";
80 cout <<
" Convert from one 3D geometry format to another.\n"
81 <<
" Or simply display some information about the object\n"
82 <<
" stored in <input>.\n"
86 cout <<
" -b\tUse binary mode if supported by target format.\n" << endl;
87 cout <<
" -l\tStore least significant bit first (LSB, little endian).\n" << endl;
88 cout <<
" -m\tStore most significant bit first (MSB, big endian).\n" << endl;
89 cout <<
" -s\tSwap byte order.\n" << endl;
90 cout <<
" -B\tUse binary mode if supported by source format.\n" << endl;
91 cout <<
" -S\tSwap byte order of input data.\n" << endl;
92 cout <<
" -c\tCopy vertex color if provided by input.\n" << endl;
93 cout <<
" -d\tCopy face color if provided by input.\n" << endl;
94 cout <<
" -C\tTranslate object in its center-of-gravity.\n" << endl;
95 cout <<
" -n\tCopy vertex normals if provided by input. Else compute normals.\n" << endl;
96 cout <<
" -N\tReverse normal directions.\n" << endl;
97 cout <<
" -t\tCopy vertex texture coordinates if provided by input file.\n" << endl;
98 cout <<
" -T \"x y z\"\tTranslate object by vector (x, y, z)'\"\n"
107 template <
typename T>
struct Option : std::pair< T, bool >
109 typedef std::pair< T, bool > Base;
112 { Base::second =
false; }
114 bool is_valid()
const {
return Base::second; }
115 bool is_empty()
const {
return !Base::second; }
117 operator T& () {
return Base::first; }
118 operator const T& ()
const {
return Base::first; }
120 Option& operator = (
const T& _rhs )
121 { Base::first = _rhs; Base::second=
true;
return *
this; }
123 bool operator == (
const T& _rhs )
const
124 {
return Base::first == _rhs; }
126 bool operator != (
const T& _rhs )
const
127 {
return Base::first != _rhs; }
130 template <
typename T>
131 std::ostream& operator << (std::ostream& _os, const Option<T>& _opt )
133 if (_opt.second) _os << _opt.first;
else _os <<
"<null>";
137 template <
typename T>
138 std::istream& operator >> (std::istream& _is,
Option<T>& _opt )
140 _is >> _opt.first; _opt.second =
true;
146 int main(
int argc,
char *argv[] )
151 std::string ifname, ofname;
152 bool rev_normals =
false;
153 bool obj_center =
false;
158 while ( (c=getopt(argc, argv,
"bBcdCi:hlmnNo:sStT:"))!=-1 )
169 case 'N': rev_normals =
true;
break;
170 case 'C': obj_center =
true;
break;
176 std::cout << optarg << std::endl;
177 std::stringstream str; str << optarg;
179 std::cout << tvec << std::endl;
182 case 'i': ifname = optarg;
break;
183 case 'o': ofname = optarg;
break;
195 ifname = argv[optind++];
205 std::cout <<
"reading.." << std::endl;
212 std::cout <<
" read in " << timer.
as_string() << std::endl;
215 std::cout <<
" read failed\n" << std::endl;
224 ?
" source is binary\n"
225 :
" source is ascii\n");
227 std::cout <<
" #V " << mesh.n_vertices() << std::endl;
228 std::cout <<
" #E " << mesh.n_edges() << std::endl;
229 std::cout <<
" #F " << mesh.n_faces() << std::endl;
231 if (ropt.vertex_has_texcoord())
232 std::cout <<
" has texture coordinates" << std::endl;
234 if (ropt.vertex_has_normal())
235 std::cout <<
" has vertex normals" << std::endl;
237 if (ropt.vertex_has_color())
238 std::cout <<
" has vertex colors" << std::endl;
240 if (ropt.face_has_normal())
241 std::cout <<
" has face normals" << std::endl;
243 if (ropt.face_has_color())
244 std::cout <<
" has face colors" << std::endl;
250 ofname = argv[optind++];
258 if ( opt.vertex_has_normal() && !ropt.vertex_has_normal())
260 std::cout <<
"compute normals" << std::endl;
265 std::cout <<
" " << mesh.n_faces()
266 <<
" face normals in " << timer.
as_string() << std::endl;
272 std::cout <<
" " << mesh.n_vertices()
273 <<
" vertex normals in " << timer.
as_string() << std::endl;
279 if ( rev_normals && ropt.vertex_has_normal() )
281 std::cout <<
"reverse normal directions" << std::endl;
283 MyMesh::VertexIter vit = mesh.vertices_begin();
284 for (; vit != mesh.vertices_end(); ++vit)
285 mesh.set_normal( *vit, -mesh.normal( *vit ) );
287 std::cout <<
" " << mesh.n_vertices()
288 <<
" vertex normals in " << timer.
as_string() << std::endl;
299 std::cout <<
"center object" << std::endl;
301 MyMesh::VertexIter vit = mesh.vertices_begin();
302 for (; vit != mesh.vertices_end(); ++vit)
303 cog += mesh.point( *vit );
305 nv = mesh.n_vertices();
306 cog *= 1.0f/mesh.n_vertices();
307 std::cout <<
" cog = [" << cog <<
"]'" << std::endl;
308 if (cog.sqrnorm() > 0.8)
310 vit = mesh.vertices_begin();
312 for (; vit != mesh.vertices_end(); ++vit)
313 mesh.set_point( *vit , mesh.point( *vit )-cog );
315 nv += mesh.n_vertices();
318 std::cout <<
" already centered!" << std::endl;
319 std::cout <<
" visited " << nv
320 <<
" vertices in " << timer.
as_string() << std::endl;
326 if ( tvec.is_valid() )
328 std::cout <<
"Translate object by " << tvec << std::endl;
331 MyMesh::VertexIter vit = mesh.vertices_begin();
332 for (; vit != mesh.vertices_end(); ++vit)
333 mesh.set_point( *vit , mesh.point( *vit ) + tvec.first );
335 std::cout <<
" moved " << mesh.n_vertices()
336 <<
" vertices in " << timer.
as_string() << std::endl;
343 std::cout <<
"Color vertices" << std::endl;
345 double d = 256.0/double(mesh.n_vertices());
347 double r = 0.0, g = 0.0, b = 255.0;
349 MyMesh::VertexIter vit = mesh.vertices_begin();
350 for (; vit != mesh.vertices_end(); ++vit)
352 mesh.set_color( *vit ,
MyMesh::Color( std::min((
int)(r+0.5),255),
353 std::min((
int)(g+0.5),255),
354 std::max((
int)(b+0.5),0) ) );
360 std::cout <<
" colored " << mesh.n_vertices()
361 <<
" vertices in " << timer.
as_string() << std::endl;
368 std::cout <<
"Color faces" << std::endl;
370 double d = 256.0/double(mesh.n_faces());
372 double r = 0.0, g = 50.0, b = 255.0;
374 MyMesh::FaceIter it = mesh.faces_begin();
375 for (; it != mesh.faces_end(); ++it)
377 mesh.set_color( *it ,
MyMesh::Color( std::min((
int)(r+0.5),255),
378 std::min((
int)(g+0.5),255),
379 std::max((
int)(b+0.5),0) ) );
385 std::cout <<
" colored " << mesh.n_faces()
386 <<
" faces in " << timer.
as_string() << std::endl;
391 std::cout <<
"writing.." << std::endl;
400 std::cerr <<
" error writing mesh!" << std::endl;
411 if ( opt.vertex_has_normal() )
412 std::cout <<
" with vertex normals" << std::endl;
413 if ( opt.vertex_has_color() )
414 std::cout <<
" with vertex colors" << std::endl;
415 if ( opt.vertex_has_texcoord() )
416 std::cout <<
" with vertex texcoord" << std::endl;
417 if ( opt.face_has_normal() )
418 std::cout <<
" with face normals" << std::endl;
419 if ( opt.face_has_color() )
420 std::cout <<
" with face colors" << std::endl;
421 std::cout <<
" wrote in " << timer.
as_string() << std::endl;
Add colors to mesh item (vertices/faces/edges)
bool read_mesh(Mesh &_mesh, const std::string &_filename)
Read a mesh from file _filename.
void stop(void)
Stop measurement.
Kernel::Color Color
Color type.
Has (r) / store (w) vertex normals.
size_t binary_size(const Mesh &_mesh, const std::string &_ext, Options _opt=Options::Default)
Get binary size of data.
Assume big endian byte ordering.
Has (r) / store (w) face colors.
Has (r) / store (w) texture coordinates.
Set options for reader/writer modules.
std::string as_string(Format format=Automatic)
Add 2D texture coordinates (vertices, halfedges)
void update_vertex_normals()
Update normal vectors for all vertices.
void reset(void)
Reset the timer.
void update_face_normals()
Update normal vectors for all faces.
Add storage for previous halfedge (halfedges). The bit is set by default in the DefaultTraits.
void start(void)
Start measurement.
Add normals to mesh item (vertices/faces)
Swap byte order in binary mode.
Has (r) / store (w) vertex colors.
Assume little endian byte ordering.
void cont(void)
Continue measurement.
bool write_mesh(const Mesh &_mesh, const std::string &_filename, Options _opt=Options::Default, std::streamsize _precision=6)
Write a mesh to the file _filename.