00001 #include <cstdlib> 00002 #include <cstring> 00003 #include <fstream> 00004 #include <iostream> 00005 00006 #include <tr1/functional> 00007 00008 #include <obj.hpp> 00009 00010 #ifdef HAVE_CONFIG_H 00011 # include <config.h> 00012 #endif 00013 00014 class obj_to_obj_converter 00015 { 00016 public: 00017 typedef int flags_type; 00018 enum flags { 00019 triangulate_faces = 1 << 0, 00020 translate_negative_indices = 1 << 1 00021 }; 00022 obj_to_obj_converter(flags_type flags) : flags_(flags) {} 00023 bool convert(std::istream& istream, std::ostream& ostream); 00024 private: 00025 void info_callback(const std::string& filename, std::size_t line_number, const std::string& message); 00026 void warning_callback(const std::string& filename, std::size_t line_number, const std::string& message); 00027 void error_callback(const std::string& filename, std::size_t line_number, const std::string& message); 00028 void geometric_vertex_callback(obj::float_type x, obj::float_type y, obj::float_type z); 00029 void texture_vertex_callback(obj::float_type u, obj::float_type v); 00030 void vertex_normal_callback(obj::float_type x, obj::float_type y, obj::float_type z); 00031 void triangular_face_geometric_vertices_callback(obj::index_type v1, obj::index_type v2, obj::index_type v3); 00032 void triangular_face_geometric_vertices_texture_vertices_callback(const obj::index_2_tuple_type& v1_vt1, const obj::index_2_tuple_type& v2_vt2, const obj::index_2_tuple_type& v3_vt3); 00033 void triangular_face_geometric_vertices_vertex_normals_callback(const obj::index_2_tuple_type& v1_vn1, const obj::index_2_tuple_type& v2_vn2, const obj::index_2_tuple_type& v3_vn3); 00034 void triangular_face_geometric_vertices_texture_vertices_vertex_normals_callback(const obj::index_3_tuple_type& v1_vt1_vn1, const obj::index_3_tuple_type& v2_vt2_vn2, const obj::index_3_tuple_type& v3_vt3_vn3); 00035 void quadrilateral_face_geometric_vertices_callback(obj::index_type v1, obj::index_type v2, obj::index_type v3, obj::index_type v4); 00036 void quadrilateral_face_geometric_vertices_texture_vertices_callback(const obj::index_2_tuple_type& v1_vt1, const obj::index_2_tuple_type& v2_vt2, const obj::index_2_tuple_type& v3_vt3, const obj::index_2_tuple_type& v4_vt4); 00037 void quadrilateral_face_geometric_vertices_vertex_normals_callback(const obj::index_2_tuple_type& v1_vn1, const obj::index_2_tuple_type& v2_vn2, const obj::index_2_tuple_type& v3_vn3, const obj::index_2_tuple_type& v4_vn4); 00038 void quadrilateral_face_geometric_vertices_texture_vertices_vertex_normals_callback(const obj::index_3_tuple_type& v1_vt1_vn1, const obj::index_3_tuple_type& v2_vt2_vn2, const obj::index_3_tuple_type& v3_vt3_vn3, const obj::index_3_tuple_type& v4_vt4_vn4); 00039 void polygonal_face_geometric_vertices_begin_callback(obj::index_type v1, obj::index_type v2, obj::index_type v3); 00040 void polygonal_face_geometric_vertices_vertex_callback(obj::index_type v); 00041 void polygonal_face_geometric_vertices_end_callback(); 00042 void polygonal_face_geometric_vertices_texture_vertices_begin_callback(const obj::index_2_tuple_type& v1_vt1, const obj::index_2_tuple_type& v2_vt2, const obj::index_2_tuple_type& v3_vt3); 00043 void polygonal_face_geometric_vertices_texture_vertices_vertex_callback(const obj::index_2_tuple_type& v_vt); 00044 void polygonal_face_geometric_vertices_texture_vertices_end_callback(); 00045 void polygonal_face_geometric_vertices_vertex_normals_begin_callback(const obj::index_2_tuple_type& v1_vn1, const obj::index_2_tuple_type& v2_vn2, const obj::index_2_tuple_type& v3_vn3); 00046 void polygonal_face_geometric_vertices_vertex_normals_vertex_callback(const obj::index_2_tuple_type& v_vn); 00047 void polygonal_face_geometric_vertices_vertex_normals_end_callback(); 00048 void polygonal_face_geometric_vertices_texture_vertices_vertex_normals_begin_callback(const obj::index_3_tuple_type& v1_vt1_vn1, const obj::index_3_tuple_type& v2_vt2_vn2, const obj::index_3_tuple_type& v3_vt3_vn3); 00049 void polygonal_face_geometric_vertices_texture_vertices_vertex_normals_vertex_callback(const obj::index_3_tuple_type& v_vt_vn); 00050 void polygonal_face_geometric_vertices_texture_vertices_vertex_normals_end_callback(); 00051 void group_name_callback(const std::string& group_name); 00052 void smoothing_group_callback(obj::size_type group_number); 00053 void object_name_callback(const std::string& object_name); 00054 void material_library_callback(const std::string& filename); 00055 void material_name_callback(const std::string& material_name); 00056 void comment_callback(const std::string& comment); 00057 flags_type flags_; 00058 std::ostream* ostream_; 00059 }; 00060 00061 void obj_to_obj_converter::info_callback(const std::string& filename, std::size_t line_number, const std::string& message) 00062 { 00063 std::cerr << filename << ":" << line_number << ": " << "info: " << message << std::endl; 00064 } 00065 00066 void obj_to_obj_converter::warning_callback(const std::string& filename, std::size_t line_number, const std::string& message) 00067 { 00068 std::cerr << filename << ":" << line_number << ": " << "warning: " << message << std::endl; 00069 } 00070 00071 void obj_to_obj_converter::error_callback(const std::string& filename, std::size_t line_number, const std::string& message) 00072 { 00073 std::cerr << filename << ":" << line_number << ": " << "error: " << message << std::endl; 00074 } 00075 00076 void obj_to_obj_converter::geometric_vertex_callback(obj::float_type x, obj::float_type y, obj::float_type z) 00077 { 00078 (*ostream_) << "v " << x << " " << y << " " << z << "\n"; 00079 } 00080 00081 void obj_to_obj_converter::texture_vertex_callback(obj::float_type u, obj::float_type v) 00082 { 00083 (*ostream_) << "vt " << u << " " << v << "\n"; 00084 } 00085 00086 void obj_to_obj_converter::vertex_normal_callback(obj::float_type x, obj::float_type y, obj::float_type z) 00087 { 00088 (*ostream_) << "vn " << x << " " << y << " " << z << "\n"; 00089 } 00090 00091 void obj_to_obj_converter::triangular_face_geometric_vertices_callback(obj::index_type v1, obj::index_type v2, obj::index_type v3) 00092 { 00093 (*ostream_) << "f " << v1 << " " << v2 << " " << v3 << "\n"; 00094 } 00095 00096 void obj_to_obj_converter::triangular_face_geometric_vertices_texture_vertices_callback(const obj::index_2_tuple_type& v1_vt1, const obj::index_2_tuple_type& v2_vt2, const obj::index_2_tuple_type& v3_vt3) 00097 { 00098 (*ostream_) << "f " << std::tr1::get<0>(v1_vt1) << "/" << std::tr1::get<1>(v1_vt1) << " " << std::tr1::get<0>(v2_vt2) << "/" << std::tr1::get<1>(v2_vt2) << " " << std::tr1::get<0>(v3_vt3) << "/" << std::tr1::get<1>(v3_vt3) << "\n"; 00099 } 00100 00101 void obj_to_obj_converter::triangular_face_geometric_vertices_vertex_normals_callback(const obj::index_2_tuple_type& v1_vn1, const obj::index_2_tuple_type& v2_vn2, const obj::index_2_tuple_type& v3_vn3) 00102 { 00103 (*ostream_) << "f " << std::tr1::get<0>(v1_vn1) << "//" << std::tr1::get<1>(v1_vn1) << " " << std::tr1::get<0>(v2_vn2) << "//" << std::tr1::get<1>(v2_vn2) << " " << std::tr1::get<0>(v3_vn3) << "//" << std::tr1::get<1>(v3_vn3) << "\n"; 00104 } 00105 00106 void obj_to_obj_converter::triangular_face_geometric_vertices_texture_vertices_vertex_normals_callback(const obj::index_3_tuple_type& v1_vt1_vn1, const obj::index_3_tuple_type& v2_vt2_vn2, const obj::index_3_tuple_type& v3_vt3_vn3) 00107 { 00108 (*ostream_) << "f " << std::tr1::get<0>(v1_vt1_vn1) << "/" << std::tr1::get<1>(v1_vt1_vn1) << "/" << std::tr1::get<2>(v1_vt1_vn1) << " " << std::tr1::get<0>(v2_vt2_vn2) << "/" << std::tr1::get<1>(v2_vt2_vn2) << "/" << std::tr1::get<2>(v2_vt2_vn2) << " " << std::tr1::get<0>(v3_vt3_vn3) << "/" << std::tr1::get<1>(v3_vt3_vn3) << "/" << std::tr1::get<2>(v3_vt3_vn3) << "\n"; 00109 } 00110 00111 void obj_to_obj_converter::quadrilateral_face_geometric_vertices_callback(obj::index_type v1, obj::index_type v2, obj::index_type v3, obj::index_type v4) 00112 { 00113 (*ostream_) << "f " << v1 << " " << v2 << " " << v3 << " " << v4 << "\n"; 00114 } 00115 00116 void obj_to_obj_converter::quadrilateral_face_geometric_vertices_texture_vertices_callback(const obj::index_2_tuple_type& v1_vt1, const obj::index_2_tuple_type& v2_vt2, const obj::index_2_tuple_type& v3_vt3, const obj::index_2_tuple_type& v4_vt4) 00117 { 00118 (*ostream_) << "f " << std::tr1::get<0>(v1_vt1) << "/" << std::tr1::get<1>(v1_vt1) << " " << std::tr1::get<0>(v2_vt2) << "/" << std::tr1::get<1>(v2_vt2) << " " << std::tr1::get<0>(v3_vt3) << "/" << std::tr1::get<1>(v3_vt3) << " " << std::tr1::get<0>(v4_vt4) << "/" << std::tr1::get<1>(v4_vt4) << "\n"; 00119 } 00120 00121 void obj_to_obj_converter::quadrilateral_face_geometric_vertices_vertex_normals_callback(const obj::index_2_tuple_type& v1_vn1, const obj::index_2_tuple_type& v2_vn2, const obj::index_2_tuple_type& v3_vn3, const obj::index_2_tuple_type& v4_vn4) 00122 { 00123 (*ostream_) << "f " << std::tr1::get<0>(v1_vn1) << "//" << std::tr1::get<1>(v1_vn1) << " " << std::tr1::get<0>(v2_vn2) << "//" << std::tr1::get<1>(v2_vn2) << " " << std::tr1::get<0>(v3_vn3) << "//" << std::tr1::get<1>(v3_vn3) << " " << std::tr1::get<0>(v4_vn4) << "//" << std::tr1::get<1>(v4_vn4) << "\n"; 00124 } 00125 00126 void obj_to_obj_converter::quadrilateral_face_geometric_vertices_texture_vertices_vertex_normals_callback(const obj::index_3_tuple_type& v1_vt1_vn1, const obj::index_3_tuple_type& v2_vt2_vn2, const obj::index_3_tuple_type& v3_vt3_vn3, const obj::index_3_tuple_type& v4_vt4_vn4) 00127 { 00128 (*ostream_) << "f " << std::tr1::get<0>(v1_vt1_vn1) << "/" << std::tr1::get<1>(v1_vt1_vn1) << "/" << std::tr1::get<2>(v1_vt1_vn1) << " " << std::tr1::get<0>(v2_vt2_vn2) << "/" << std::tr1::get<1>(v2_vt2_vn2) << "/" << std::tr1::get<2>(v2_vt2_vn2) << " " << std::tr1::get<0>(v3_vt3_vn3) << "/" << std::tr1::get<1>(v3_vt3_vn3) << "/" << std::tr1::get<2>(v3_vt3_vn3) << " " << std::tr1::get<0>(v4_vt4_vn4) << "/" << std::tr1::get<1>(v4_vt4_vn4) << "/" << std::tr1::get<2>(v4_vt4_vn4) << "\n"; 00129 } 00130 00131 void obj_to_obj_converter::polygonal_face_geometric_vertices_begin_callback(obj::index_type v1, obj::index_type v2, obj::index_type v3) 00132 { 00133 (*ostream_) << "f " << v1 << " " << v2 << " " << v3; 00134 } 00135 00136 void obj_to_obj_converter::polygonal_face_geometric_vertices_vertex_callback(obj::index_type v) 00137 { 00138 (*ostream_) << " " << v; 00139 } 00140 00141 void obj_to_obj_converter::polygonal_face_geometric_vertices_end_callback() 00142 { 00143 (*ostream_) << "\n"; 00144 } 00145 00146 void obj_to_obj_converter::polygonal_face_geometric_vertices_texture_vertices_begin_callback(const obj::index_2_tuple_type& v1_vt1, const obj::index_2_tuple_type& v2_vt2, const obj::index_2_tuple_type& v3_vt3) 00147 { 00148 (*ostream_) << "f " << std::tr1::get<0>(v1_vt1) << "/" << std::tr1::get<1>(v1_vt1) << " " << std::tr1::get<0>(v2_vt2) << "/" << std::tr1::get<1>(v2_vt2) << " " << std::tr1::get<0>(v3_vt3) << "/" << std::tr1::get<1>(v3_vt3); 00149 } 00150 00151 void obj_to_obj_converter::polygonal_face_geometric_vertices_texture_vertices_vertex_callback(const obj::index_2_tuple_type& v_vt) 00152 { 00153 (*ostream_) << " " << std::tr1::get<0>(v_vt) << "/" << std::tr1::get<1>(v_vt); 00154 } 00155 00156 void obj_to_obj_converter::polygonal_face_geometric_vertices_texture_vertices_end_callback() 00157 { 00158 (*ostream_) << "\n"; 00159 } 00160 00161 void obj_to_obj_converter::polygonal_face_geometric_vertices_vertex_normals_begin_callback(const obj::index_2_tuple_type& v1_vn1, const obj::index_2_tuple_type& v2_vn2, const obj::index_2_tuple_type& v3_vn3) 00162 { 00163 (*ostream_) << "f " << std::tr1::get<0>(v1_vn1) << "//" << std::tr1::get<1>(v1_vn1) << " " << std::tr1::get<0>(v2_vn2) << "//" << std::tr1::get<1>(v2_vn2) << " " << std::tr1::get<0>(v3_vn3) << "//" << std::tr1::get<1>(v3_vn3); 00164 } 00165 00166 void obj_to_obj_converter::polygonal_face_geometric_vertices_vertex_normals_vertex_callback(const obj::index_2_tuple_type& v_vn) 00167 { 00168 (*ostream_) << " " << std::tr1::get<0>(v_vn) << "//" << std::tr1::get<1>(v_vn); 00169 } 00170 00171 void obj_to_obj_converter::polygonal_face_geometric_vertices_vertex_normals_end_callback() 00172 { 00173 (*ostream_) << "\n"; 00174 } 00175 00176 void obj_to_obj_converter::polygonal_face_geometric_vertices_texture_vertices_vertex_normals_begin_callback(const obj::index_3_tuple_type& v1_vt1_vn1, const obj::index_3_tuple_type& v2_vt2_vn2, const obj::index_3_tuple_type& v3_vt3_vn3) 00177 { 00178 (*ostream_) << "f " << std::tr1::get<0>(v1_vt1_vn1) << "/" << std::tr1::get<1>(v1_vt1_vn1) << "/" << std::tr1::get<2>(v1_vt1_vn1) << " " << std::tr1::get<0>(v2_vt2_vn2) << "/" << std::tr1::get<1>(v2_vt2_vn2) << "/" << std::tr1::get<2>(v2_vt2_vn2) << " " << std::tr1::get<0>(v3_vt3_vn3) << "/" << std::tr1::get<1>(v3_vt3_vn3) << "/" << std::tr1::get<2>(v3_vt3_vn3); 00179 } 00180 00181 void obj_to_obj_converter::polygonal_face_geometric_vertices_texture_vertices_vertex_normals_vertex_callback(const obj::index_3_tuple_type& v_vt_vn) 00182 { 00183 (*ostream_) << " " << std::tr1::get<0>(v_vt_vn) << "/" << std::tr1::get<1>(v_vt_vn) << "/" << std::tr1::get<2>(v_vt_vn); 00184 } 00185 00186 void obj_to_obj_converter::polygonal_face_geometric_vertices_texture_vertices_vertex_normals_end_callback() 00187 { 00188 (*ostream_) << "\n"; 00189 } 00190 00191 void obj_to_obj_converter::group_name_callback(const std::string& group_name) 00192 { 00193 (*ostream_) << "g " << group_name << "\n"; 00194 } 00195 00196 void obj_to_obj_converter::smoothing_group_callback(obj::size_type group_number) 00197 { 00198 (*ostream_) << "s "; 00199 if (group_number == 0) { 00200 (*ostream_) << "off"; 00201 } 00202 else { 00203 (*ostream_) << group_number; 00204 } 00205 (*ostream_) << "\n"; 00206 } 00207 00208 void obj_to_obj_converter::object_name_callback(const std::string& object_name) 00209 { 00210 (*ostream_) << "o " << object_name << "\n"; 00211 } 00212 00213 void obj_to_obj_converter::material_library_callback(const std::string& filename) 00214 { 00215 (*ostream_) << "mtllib " << filename << "\n"; 00216 } 00217 00218 void obj_to_obj_converter::material_name_callback(const std::string& material_name) 00219 { 00220 (*ostream_) << "usemtl " << material_name << "\n"; 00221 } 00222 00223 void obj_to_obj_converter::comment_callback(const std::string& comment) 00224 { 00225 (*ostream_) << comment << "\n"; 00226 } 00227 00228 bool obj_to_obj_converter::convert(std::istream& istream, std::ostream& ostream) 00229 { 00230 using namespace std::tr1::placeholders; 00231 00232 obj::obj_parser::flags_type obj_parser_flags = 0; 00233 obj_parser_flags |= obj::obj_parser::parse_blank_lines_as_comment; 00234 if (flags_ & triangulate_faces) { 00235 obj_parser_flags |= obj::obj_parser::triangulate_faces; 00236 } 00237 if (flags_ & translate_negative_indices) { 00238 obj_parser_flags |= obj::obj_parser::translate_negative_indices; 00239 } 00240 00241 obj::obj_parser obj_parser(obj_parser_flags); 00242 00243 std::string ifilename; 00244 00245 obj_parser.info_callback(std::tr1::bind(&obj_to_obj_converter::info_callback, this, ifilename, _1, _2)); 00246 obj_parser.warning_callback(std::tr1::bind(&obj_to_obj_converter::warning_callback, this, ifilename, _1, _2)); 00247 obj_parser.error_callback(std::tr1::bind(&obj_to_obj_converter::error_callback, this, ifilename, _1, _2)); 00248 00249 obj_parser.geometric_vertex_callback(std::tr1::bind(&obj_to_obj_converter::geometric_vertex_callback, this, _1, _2, _3)); 00250 obj_parser.texture_vertex_callback(std::tr1::bind(&obj_to_obj_converter::texture_vertex_callback, this, _1, _2)); 00251 obj_parser.vertex_normal_callback(std::tr1::bind(&obj_to_obj_converter::vertex_normal_callback, this, _1, _2, _3)); 00252 obj_parser.face_callbacks( 00253 std::tr1::bind(&obj_to_obj_converter::triangular_face_geometric_vertices_callback, this, _1, _2, _3), 00254 std::tr1::bind(&obj_to_obj_converter::triangular_face_geometric_vertices_texture_vertices_callback, this, _1, _2, _3), 00255 std::tr1::bind(&obj_to_obj_converter::triangular_face_geometric_vertices_vertex_normals_callback, this, _1, _2, _3), 00256 std::tr1::bind(&obj_to_obj_converter::triangular_face_geometric_vertices_texture_vertices_vertex_normals_callback, this, _1, _2, _3), 00257 std::tr1::bind(&obj_to_obj_converter::quadrilateral_face_geometric_vertices_callback, this, _1, _2, _3, _4), 00258 std::tr1::bind(&obj_to_obj_converter::quadrilateral_face_geometric_vertices_texture_vertices_callback, this, _1, _2, _3, _4), 00259 std::tr1::bind(&obj_to_obj_converter::quadrilateral_face_geometric_vertices_vertex_normals_callback, this, _1, _2, _3, _4), 00260 std::tr1::bind(&obj_to_obj_converter::quadrilateral_face_geometric_vertices_texture_vertices_vertex_normals_callback, this, _1, _2, _3, _4), 00261 std::tr1::bind(&obj_to_obj_converter::polygonal_face_geometric_vertices_begin_callback, this, _1, _2, _3), 00262 std::tr1::bind(&obj_to_obj_converter::polygonal_face_geometric_vertices_vertex_callback, this, _1), 00263 std::tr1::bind(&obj_to_obj_converter::polygonal_face_geometric_vertices_end_callback, this), 00264 std::tr1::bind(&obj_to_obj_converter::polygonal_face_geometric_vertices_texture_vertices_begin_callback, this, _1, _2, _3), 00265 std::tr1::bind(&obj_to_obj_converter::polygonal_face_geometric_vertices_texture_vertices_vertex_callback, this, _1), 00266 std::tr1::bind(&obj_to_obj_converter::polygonal_face_geometric_vertices_texture_vertices_end_callback, this), 00267 std::tr1::bind(&obj_to_obj_converter::polygonal_face_geometric_vertices_vertex_normals_begin_callback, this, _1, _2, _3), 00268 std::tr1::bind(&obj_to_obj_converter::polygonal_face_geometric_vertices_vertex_normals_vertex_callback, this, _1), 00269 std::tr1::bind(&obj_to_obj_converter::polygonal_face_geometric_vertices_vertex_normals_end_callback, this), 00270 std::tr1::bind(&obj_to_obj_converter::polygonal_face_geometric_vertices_texture_vertices_vertex_normals_begin_callback, this, _1, _2, _3), 00271 std::tr1::bind(&obj_to_obj_converter::polygonal_face_geometric_vertices_texture_vertices_vertex_normals_vertex_callback, this, _1), 00272 std::tr1::bind(&obj_to_obj_converter::polygonal_face_geometric_vertices_texture_vertices_vertex_normals_end_callback, this) 00273 ); 00274 obj_parser.group_name_callback(std::tr1::bind(&obj_to_obj_converter::group_name_callback, this, _1)); 00275 obj_parser.smoothing_group_callback(std::tr1::bind(&obj_to_obj_converter::smoothing_group_callback, this, _1)); 00276 obj_parser.object_name_callback(std::tr1::bind(&obj_to_obj_converter::object_name_callback, this, _1)); 00277 obj_parser.material_library_callback(std::tr1::bind(&obj_to_obj_converter::material_library_callback, this, _1)); 00278 obj_parser.material_name_callback(std::tr1::bind(&obj_to_obj_converter::material_name_callback, this, _1)); 00279 obj_parser.comment_callback(std::tr1::bind(&obj_to_obj_converter::comment_callback, this, _1)); 00280 00281 ostream_ = &ostream; 00282 00283 return obj_parser.parse(istream); 00284 } 00285 00286 int main(int argc, char* argv[]) 00287 { 00288 obj_to_obj_converter::flags_type obj_to_obj_converter_flags = 0; 00289 00290 int argi; 00291 for (argi = 1; argi < argc; ++argi) { 00292 00293 if (argv[argi][0] != '-') { 00294 break; 00295 } 00296 if (argv[argi][1] == 0) { 00297 ++argi; 00298 break; 00299 } 00300 char short_opt, *long_opt, *opt_arg; 00301 if (argv[argi][1] != '-') { 00302 short_opt = argv[argi][1]; 00303 opt_arg = &argv[argi][2]; 00304 long_opt = &argv[argi][2]; 00305 while (*long_opt != '\0') { 00306 ++long_opt; 00307 } 00308 } 00309 else { 00310 short_opt = 0; 00311 long_opt = &argv[argi][2]; 00312 opt_arg = long_opt; 00313 while ((*opt_arg != '=') && (*opt_arg != '\0')) { 00314 ++opt_arg; 00315 } 00316 if (*opt_arg == '=') { 00317 *opt_arg++ = '\0'; 00318 } 00319 } 00320 00321 if ((short_opt == 'h') || (std::strcmp(long_opt, "help") == 0)) { 00322 std::cout << "Usage: obj2obj [OPTION] [[INFILE] OUTFILE]\n"; 00323 std::cout << "Parse an OBJ file.\n"; 00324 std::cout << "\n"; 00325 std::cout << " -h, --help display this help and exit\n"; 00326 std::cout << " -v, --version output version information and exit\n"; 00327 std::cout << " -f, --flag=FLAG set flag\n"; 00328 std::cout << "\n"; 00329 std::cout << "FLAG may be one of the following: triangulate_faces, translate_negative_indices.\n"; 00330 std::cout << "\n"; 00331 std::cout << "With no INFILE/OUTFILE, or when INFILE/OUTFILE is -, read standard input/output.\n"; 00332 std::cout << "\n"; 00333 std::cout << "Report bugs to <" << PACKAGE_BUGREPORT << ">.\n"; 00334 return EXIT_SUCCESS; 00335 } 00336 00337 else if ((short_opt == 'v') || (std::strcmp(long_opt, "version") == 0)) { 00338 std::cout << "obj2obj (" << PACKAGE_NAME << ") " << PACKAGE_VERSION << "\n"; 00339 std::cout << "Copyright (C) 2007 " << PACKAGE_AUTHOR << "\n"; 00340 std::cout << "\n"; 00341 std::cout << "This program is free software; you can redistribute it and/or modify\n"; 00342 std::cout << "it under the terms of the GNU General Public License as published by\n"; 00343 std::cout << "the Free Software Foundation; either version 2 of the License, or\n"; 00344 std::cout << "(at your option) any later version.\n"; 00345 std::cout << "\n"; 00346 std::cout << "This program is distributed in the hope that it will be useful,\n"; 00347 std::cout << "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"; 00348 std::cout << "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"; 00349 std::cout << "GNU General Public License for more details.\n"; 00350 std::cout << "\n"; 00351 std::cout << "You should have received a copy of the GNU General Public License\n"; 00352 std::cout << "along with this program; if not, write to the Free Software\n"; 00353 std::cout << "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n"; 00354 return EXIT_SUCCESS; 00355 } 00356 00357 else if ((short_opt == 'f') || (std::strcmp(long_opt, "flag") == 0)) { 00358 if (strcmp(opt_arg, "triangulate_faces") == 0) { 00359 obj_to_obj_converter_flags |= obj_to_obj_converter::triangulate_faces; 00360 } 00361 else if (strcmp(opt_arg, "translate_negative_indices") == 0) { 00362 obj_to_obj_converter_flags |= obj_to_obj_converter::translate_negative_indices; 00363 } 00364 else { 00365 std::cerr << "obj2obj: " << "invalid option `" << argv[argi] << "'" << "\n"; 00366 std::cerr << "Try `" << argv[0] << " --help' for more information.\n"; 00367 return EXIT_FAILURE; 00368 } 00369 } 00370 00371 else { 00372 std::cerr << "obj2obj: " << "invalid option `" << argv[argi] << "'" << "\n"; 00373 std::cerr << "Try `" << argv[0] << " --help' for more information.\n"; 00374 return EXIT_FAILURE; 00375 } 00376 } 00377 00378 int parc = argc - argi; 00379 char** parv = argv + argi; 00380 if (parc > 2) { 00381 std::cerr << "obj2obj: " << "too many parameters" << "\n"; 00382 std::cerr << "Try `" << argv[0] << " --help' for more information.\n"; 00383 return EXIT_FAILURE; 00384 } 00385 00386 std::ifstream ifstream; 00387 const char* ifilename = ""; 00388 if (parc > 0) { 00389 ifilename = parv[0]; 00390 if (std::strcmp(ifilename, "-") != 0) { 00391 ifstream.open(ifilename); 00392 if (!ifstream.is_open()) { 00393 std::cerr << "obj2obj: " << ifilename << ": " << "no such file or directory" << "\n"; 00394 return EXIT_FAILURE; 00395 } 00396 } 00397 } 00398 00399 std::ofstream ofstream; 00400 const char* ofilename = ""; 00401 if (parc > 1) { 00402 ofilename = parv[1]; 00403 if (std::strcmp(ofilename, "-") != 0) { 00404 ofstream.open(ofilename); 00405 if (!ofstream.is_open()) { 00406 std::cerr << "obj2obj: " << ofilename << ": " << "could not open file" << "\n"; 00407 return EXIT_FAILURE; 00408 } 00409 } 00410 } 00411 00412 std::istream& istream = ifstream.is_open() ? ifstream : std::cin; 00413 std::ostream& ostream = ofstream.is_open() ? ofstream : std::cout; 00414 00415 class obj_to_obj_converter obj_to_obj_converter(obj_to_obj_converter_flags); 00416 return obj_to_obj_converter.convert(istream, ostream); 00417 }