Panda3D
|
00001 // Filename: eggMultiFilter.cxx 00002 // Created by: drose (02Nov00) 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 "eggMultiFilter.h" 00016 00017 #include "pnotify.h" 00018 #include "eggData.h" 00019 00020 //////////////////////////////////////////////////////////////////// 00021 // Function: EggMultiFilter::Constructor 00022 // Access: Public 00023 // Description: 00024 //////////////////////////////////////////////////////////////////// 00025 EggMultiFilter:: 00026 EggMultiFilter(bool allow_empty) : _allow_empty(allow_empty) { 00027 clear_runlines(); 00028 add_runline("-o output.egg [opts] input.egg"); 00029 add_runline("-d dirname [opts] file.egg [file.egg ...]"); 00030 add_runline("-inplace [opts] file.egg [file.egg ...]"); 00031 add_runline("-inf input_list_filename [opts]"); 00032 00033 add_option 00034 ("o", "filename", 50, 00035 "Specify the filename to which the resulting egg file will be written. " 00036 "This is only valid when there is only one input egg file on the command " 00037 "line. If you want to process multiple files simultaneously, you must " 00038 "use either -d or -inplace.", 00039 &EggMultiFilter::dispatch_filename, &_got_output_filename, &_output_filename); 00040 00041 add_option 00042 ("d", "dirname", 50, 00043 "Specify the name of the directory in which to write the resulting egg " 00044 "files. If you are processing only one egg file, this may be omitted " 00045 "in lieu of the -o option. If you are processing multiple egg files, " 00046 "this may be omitted only if you specify -inplace instead.", 00047 &EggMultiFilter::dispatch_filename, &_got_output_dirname, &_output_dirname); 00048 00049 add_option 00050 ("inplace", "", 50, 00051 "If this option is given, the input egg files will be rewritten in " 00052 "place with the results. This obviates the need to specify -d " 00053 "for an output directory; however, it's risky because the original " 00054 "input egg files are lost.", 00055 &EggMultiFilter::dispatch_none, &_inplace); 00056 00057 add_option 00058 ("inf", "filename", 95, 00059 "Reads input args from a text file instead of the command line. " 00060 "Useful for really, really large lists of args that break the " 00061 "OS-imposed limits on the length of command lines.", 00062 &EggMultiFilter::dispatch_filename, &_got_input_filename, &_input_filename); 00063 00064 // Derived programs will set this true when they discover some 00065 // command-line option that will prevent the program from generating 00066 // output. This removes some checks for an output specification in 00067 // handle_args. 00068 _read_only = false; 00069 } 00070 00071 00072 //////////////////////////////////////////////////////////////////// 00073 // Function: EggMultiFilter::handle_args 00074 // Access: Protected, Virtual 00075 // Description: Does something with the additional arguments on the 00076 // command line (after all the -options have been 00077 // parsed). Returns true if the arguments are good, 00078 // false otherwise. 00079 //////////////////////////////////////////////////////////////////// 00080 bool EggMultiFilter:: 00081 handle_args(ProgramBase::Args &args) { 00082 if (_got_input_filename) { 00083 nout << "Populating args from input file: " << _input_filename << "\n"; 00084 // Makes sure the file is set is_text 00085 _filename = Filename::text_filename(_input_filename); 00086 ifstream input; 00087 if (!_filename.open_read(input)) { 00088 nout << "Error opening file: " << _input_filename << "\n"; 00089 return false; 00090 } 00091 string line; 00092 // File should be a space-delimited list of egg files 00093 while (getline(input, line, ' ')) { 00094 args.push_back(line); 00095 } 00096 } 00097 if (args.empty()) { 00098 if (!_allow_empty) { 00099 nout << "You must specify the egg file(s) to read on the command line.\n"; 00100 return false; 00101 } 00102 } else { 00103 // These only apply if we have specified any egg files. 00104 if (_got_output_filename && args.size() == 1) { 00105 if (_got_output_dirname) { 00106 nout << "Cannot specify both -o and -d.\n"; 00107 return false; 00108 } else if (_inplace) { 00109 nout << "Cannot specify both -o and -inplace.\n"; 00110 return false; 00111 } 00112 00113 } else { 00114 if (_got_output_filename) { 00115 nout << "Cannot use -o when multiple egg files are specified.\n"; 00116 return false; 00117 } 00118 00119 if (_got_output_dirname && _inplace) { 00120 nout << "Cannot specify both -inplace and -d.\n"; 00121 return false; 00122 00123 } else if (!_got_output_dirname && !_inplace) { 00124 if (!_read_only) { 00125 nout << "You must specify either -inplace or -d.\n"; 00126 return false; 00127 } 00128 } 00129 } 00130 } 00131 00132 // We need to set up _path_replace before we call read_egg(). 00133 if (!_got_path_directory) { 00134 // Put in the name of the output directory. 00135 if (_got_output_filename) { 00136 _path_replace->_path_directory = _output_filename.get_dirname(); 00137 } else if (_got_output_dirname) { 00138 _path_replace->_path_directory = _output_dirname; 00139 } 00140 } 00141 00142 Args::const_iterator ai; 00143 for (ai = args.begin(); ai != args.end(); ++ai) { 00144 PT(EggData) data = read_egg(Filename::from_os_specific(*ai)); 00145 if (data == (EggData *)NULL) { 00146 // Rather than returning false, we simply exit here, so the 00147 // ProgramBase won't try to tell the user how to run the program 00148 // just because we got a bad egg file. 00149 exit(1); 00150 } 00151 00152 _eggs.push_back(data); 00153 } 00154 00155 return true; 00156 } 00157 00158 //////////////////////////////////////////////////////////////////// 00159 // Function: EggMultiFilter::post_command_line 00160 // Access: Protected, Virtual 00161 // Description: 00162 //////////////////////////////////////////////////////////////////// 00163 bool EggMultiFilter:: 00164 post_command_line() { 00165 Eggs::iterator ei; 00166 for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) { 00167 EggData *data = (*ei); 00168 if (_got_coordinate_system) { 00169 data->set_coordinate_system(_coordinate_system); 00170 } 00171 append_command_comment(data); 00172 } 00173 00174 return EggMultiBase::post_command_line(); 00175 } 00176 00177 //////////////////////////////////////////////////////////////////// 00178 // Function: EggMultiFilter::get_output_filename 00179 // Access: Protected 00180 // Description: Returns the output filename of the egg file with the 00181 // given input filename. This is based on the user's 00182 // choice of -inplace, -o, or -d. 00183 //////////////////////////////////////////////////////////////////// 00184 Filename EggMultiFilter:: 00185 get_output_filename(const Filename &source_filename) const { 00186 if (_got_output_filename) { 00187 nassertr(!_inplace && !_got_output_dirname && _eggs.size() == 1, Filename()); 00188 return _output_filename; 00189 00190 } else if (_got_output_dirname) { 00191 nassertr(!_inplace, Filename()); 00192 Filename result = source_filename; 00193 result.set_dirname(_output_dirname); 00194 return result; 00195 } 00196 00197 nassertr(_inplace, Filename()); 00198 return source_filename; 00199 } 00200 00201 //////////////////////////////////////////////////////////////////// 00202 // Function: EggMultiFilter::write_eggs 00203 // Access: Protected, Virtual 00204 // Description: Writes out all of the egg files in the _eggs vector, 00205 // to the output directory if one is specified, or over 00206 // the input files if -inplace was specified. 00207 //////////////////////////////////////////////////////////////////// 00208 void EggMultiFilter:: 00209 write_eggs() { 00210 nassertv(!_read_only); 00211 post_process_egg_files(); 00212 Eggs::iterator ei; 00213 for (ei = _eggs.begin(); ei != _eggs.end(); ++ei) { 00214 EggData *data = (*ei); 00215 Filename filename = get_output_filename(data->get_egg_filename()); 00216 00217 nout << "Writing " << filename << "\n"; 00218 filename.make_dir(); 00219 if (!data->write_egg(filename)) { 00220 // Error writing an egg file; abort. 00221 exit(1); 00222 } 00223 } 00224 }