Panda3D
|
00001 // Filename: eggWriter.cxx 00002 // Created by: drose (14Feb00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "eggWriter.h" 00016 00017 #include "string_utils.h" 00018 #include "compose_matrix.h" 00019 #include "globPattern.h" 00020 00021 //////////////////////////////////////////////////////////////////// 00022 // Function: EggWriter::Constructor 00023 // Access: Public 00024 // Description: Egg-writing type programs may specify their output 00025 // file using either the last-filename convention, the 00026 // -o convention, and/or implicitly writing the result 00027 // to standard output. Not all interfaces are 00028 // appropriate for all applications; some may be 00029 // confusing or dangerous. 00030 // 00031 // The calling application should pass allow_last_param 00032 // true to allow the user to specify the output filename 00033 // as the last parameter on the command line (the most 00034 // dangerous, but convenient, method), and allow_stdout 00035 // true to allow the user to omit the output filename 00036 // altogether and have the output implicitly go to 00037 // standard output (not terribly dangerous, but 00038 // inappropriate when writing binary file formats). 00039 //////////////////////////////////////////////////////////////////// 00040 EggWriter:: 00041 EggWriter(bool allow_last_param, bool allow_stdout) : 00042 WithOutputFile(allow_last_param, allow_stdout, false) 00043 { 00044 // Indicate the extension name we expect the user to supply for 00045 // output files. 00046 _preferred_extension = ".egg"; 00047 00048 clear_runlines(); 00049 if (_allow_last_param) { 00050 add_runline("[opts] output.egg"); 00051 } 00052 add_runline("[opts] -o output.egg"); 00053 if (_allow_stdout) { 00054 add_runline("[opts] >output.egg"); 00055 } 00056 00057 string o_description; 00058 00059 if (_allow_stdout) { 00060 if (_allow_last_param) { 00061 o_description = 00062 "Specify the filename to which the resulting egg file will be written. " 00063 "If this option is omitted, the last parameter name is taken to be the " 00064 "name of the output file, or standard output is used if there are no " 00065 "other parameters."; 00066 } else { 00067 o_description = 00068 "Specify the filename to which the resulting egg file will be written. " 00069 "If this option is omitted, the egg file is written to standard output."; 00070 } 00071 } else { 00072 if (_allow_last_param) { 00073 o_description = 00074 "Specify the filename to which the resulting egg file will be written. " 00075 "If this option is omitted, the last parameter name is taken to be the " 00076 "name of the output file."; 00077 } else { 00078 o_description = 00079 "Specify the filename to which the resulting egg file will be written."; 00080 } 00081 } 00082 00083 add_option 00084 ("o", "filename", 50, o_description, 00085 &EggWriter::dispatch_filename, &_got_output_filename, &_output_filename); 00086 00087 redescribe_option 00088 ("cs", 00089 "Specify the coordinate system of the resulting egg file. This may be " 00090 "one of 'y-up', 'z-up', 'y-up-left', or 'z-up-left'. The default is " 00091 "y-up."); 00092 } 00093 00094 00095 //////////////////////////////////////////////////////////////////// 00096 // Function: EggWriter::as_writer 00097 // Access: Public, Virtual 00098 // Description: Returns this object as an EggWriter pointer, if it is 00099 // in fact an EggWriter, or NULL if it is not. 00100 // 00101 // This is intended to work around the C++ limitation 00102 // that prevents downcasts past virtual inheritance. 00103 // Since both EggReader and EggWriter inherit virtually 00104 // from EggSingleBase, we need functions like this to downcast 00105 // to the appropriate pointer. 00106 //////////////////////////////////////////////////////////////////// 00107 EggWriter *EggWriter:: 00108 as_writer() { 00109 return this; 00110 } 00111 00112 //////////////////////////////////////////////////////////////////// 00113 // Function: EggWriter::post_process_egg_file 00114 // Access: Public, Virtual 00115 // Description: Performs any processing of the egg file that is 00116 // appropriate before writing it out. This includes any 00117 // normal adjustments the user requested via -np, etc. 00118 // 00119 // Normally, you should not need to call this function 00120 // directly; write_egg_file() calls it for you. You 00121 // should call this only if you do not use 00122 // write_egg_file() to write out the resulting egg file. 00123 //////////////////////////////////////////////////////////////////// 00124 void EggWriter:: 00125 post_process_egg_file() { 00126 if (_got_transform) { 00127 nout << "Applying transform matrix:\n"; 00128 _transform.write(nout, 2); 00129 LVecBase3d scale, hpr, translate; 00130 if (decompose_matrix(_transform, scale, hpr, translate, 00131 _data->get_coordinate_system())) { 00132 nout << "(scale " << scale << ", hpr " << hpr << ", translate " 00133 << translate << ")\n"; 00134 } 00135 _data->transform(_transform); 00136 } 00137 00138 if (_make_points) { 00139 nout << "Making points\n"; 00140 _data->make_point_primitives(); 00141 } 00142 00143 bool needs_remove = false; 00144 00145 switch (_normals_mode) { 00146 case NM_strip: 00147 nout << "Stripping normals.\n"; 00148 _data->strip_normals(); 00149 needs_remove = true; 00150 break; 00151 00152 case NM_polygon: 00153 nout << "Recomputing polygon normals.\n"; 00154 _data->recompute_polygon_normals(); 00155 needs_remove = true; 00156 break; 00157 00158 case NM_vertex: 00159 nout << "Recomputing vertex normals.\n"; 00160 _data->recompute_vertex_normals(_normals_threshold); 00161 needs_remove = true; 00162 break; 00163 00164 case NM_preserve: 00165 // Do nothing. 00166 break; 00167 } 00168 00169 if (_got_tbnall) { 00170 needs_remove |= _data->recompute_tangent_binormal(GlobPattern("*")); 00171 } else { 00172 if (_got_tbnauto) { 00173 needs_remove |= _data->recompute_tangent_binormal_auto(); 00174 } 00175 needs_remove |= _data->recompute_tangent_binormal(_tbn_names); 00176 } 00177 00178 if (needs_remove) { 00179 _data->remove_unused_vertices(true); 00180 } 00181 } 00182 00183 //////////////////////////////////////////////////////////////////// 00184 // Function: EggWriter::write_egg_file 00185 // Access: Public 00186 // Description: Writes out the egg file as the normal result of the 00187 // program. This calls post_process_egg_file() to 00188 // perform any last minute processing (like normal 00189 // computation) and then writes out the file to the 00190 // output stream returned by get_output(). 00191 //////////////////////////////////////////////////////////////////// 00192 void EggWriter:: 00193 write_egg_file() { 00194 post_process_egg_file(); 00195 _data->write_egg(get_output()); 00196 } 00197 00198 //////////////////////////////////////////////////////////////////// 00199 // Function: EggWriter::handle_args 00200 // Access: Protected, Virtual 00201 // Description: Does something with the additional arguments on the 00202 // command line (after all the -options have been 00203 // parsed). Returns true if the arguments are good, 00204 // false otherwise. 00205 //////////////////////////////////////////////////////////////////// 00206 bool EggWriter:: 00207 handle_args(ProgramBase::Args &args) { 00208 if (!check_last_arg(args, 0)) { 00209 return false; 00210 } 00211 00212 if (!args.empty()) { 00213 nout << "Unexpected arguments on command line:\n"; 00214 Args::const_iterator ai; 00215 for (ai = args.begin(); ai != args.end(); ++ai) { 00216 nout << (*ai) << " "; 00217 } 00218 nout << "\r"; 00219 return false; 00220 } 00221 00222 if (!_got_path_directory && _got_output_filename) { 00223 // Put in the name of the output directory. 00224 _path_replace->_path_directory = _output_filename.get_dirname(); 00225 } 00226 00227 return true; 00228 } 00229 00230 //////////////////////////////////////////////////////////////////// 00231 // Function: EggWriter::post_command_line 00232 // Access: Protected, Virtual 00233 // Description: 00234 //////////////////////////////////////////////////////////////////// 00235 bool EggWriter:: 00236 post_command_line() { 00237 if (!_allow_stdout && !_got_output_filename) { 00238 nout << "You must specify the filename to write with -o.\n"; 00239 return false; 00240 } 00241 00242 append_command_comment(_data); 00243 00244 return EggSingleBase::post_command_line(); 00245 }