Panda3D
 All Classes Functions Variables Enumerations
eggMultiFilter.cxx
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 }
 All Classes Functions Variables Enumerations