Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

pandatool/src/fltprogs/fltCopy.cxx

Go to the documentation of this file.
00001 // Filename: fltCopy.cxx
00002 // Created by:  drose (01Nov00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "fltCopy.h"
00020 
00021 #include "cvsSourceDirectory.h"
00022 #include "fltHeader.h"
00023 #include "fltFace.h"
00024 #include "fltExternalReference.h"
00025 #include "fltError.h"
00026 #include "dcast.h"
00027 
00028 ////////////////////////////////////////////////////////////////////
00029 //     Function: FltCopy::Constructor
00030 //       Access: Public
00031 //  Description:
00032 ////////////////////////////////////////////////////////////////////
00033 FltCopy::
00034 FltCopy() {
00035   set_program_description
00036     ("fltcopy copies one or more MultiGen .flt files into a "
00037      "CVS source hierarchy.  "
00038      "Rather than copying the named files immediately into the current "
00039      "directory, it first scans the entire source hierarchy, identifying all "
00040      "the already-existing files.  If the named file to copy matches the "
00041      "name of an already-existing file in the current directory or elsewhere "
00042      "in the hierarchy, that file is overwritten.  Other .flt files, as "
00043      "well as texture files, that are externally referenced by the "
00044      "named .flt file(s) are similarly copied.");
00045 
00046   clear_runlines();
00047   add_runline("[opts] file.flt [file.flt ... ]");
00048 
00049   add_path_replace_options();
00050 }
00051 
00052 ////////////////////////////////////////////////////////////////////
00053 //     Function: FltCopy::run
00054 //       Access: Public
00055 //  Description:
00056 ////////////////////////////////////////////////////////////////////
00057 void FltCopy::
00058 run() {
00059   SourceFiles::iterator fi;
00060   for (fi = _source_files.begin(); fi != _source_files.end(); ++fi) {
00061     ExtraData ed;
00062     ed._type = FT_flt;
00063 
00064     CVSSourceDirectory *dest = import(*fi, &ed, _model_dir);
00065     if (dest == (CVSSourceDirectory *)NULL) {
00066       exit(1);
00067     }
00068   }
00069 }
00070 
00071 ////////////////////////////////////////////////////////////////////
00072 //     Function: FltCopy::copy_file
00073 //       Access: Protected, Virtual
00074 //  Description: Called by import() if verify_file() indicates that a
00075 //               file needs to be copied.  This does the actual copy
00076 //               of a file from source to destination.  If new_file is
00077 //               true, then dest does not already exist.
00078 ////////////////////////////////////////////////////////////////////
00079 bool FltCopy::
00080 copy_file(const Filename &source, const Filename &dest,
00081           CVSSourceDirectory *dir, void *extra_data, bool new_file) {
00082   ExtraData *ed = (ExtraData *)extra_data;
00083   switch (ed->_type) {
00084   case FT_flt:
00085     return copy_flt_file(source, dest, dir);
00086 
00087   case FT_texture:
00088     return copy_texture(source, dest, dir, ed->_texture, new_file);
00089   }
00090 
00091   nout << "Internal error: invalid type " << (int)ed->_type << "\n";
00092   return false;
00093 }
00094 
00095 ////////////////////////////////////////////////////////////////////
00096 //     Function: FltCopy::copy_flt_file
00097 //       Access: Private
00098 //  Description:
00099 ////////////////////////////////////////////////////////////////////
00100 bool FltCopy::
00101 copy_flt_file(const Filename &source, const Filename &dest,
00102               CVSSourceDirectory *dir) {
00103   PT(FltHeader) header = new FltHeader(_path_replace);
00104 
00105   // We don't want to automatically generate .attr files--we'd rather
00106   // write them out explicitly.
00107   header->set_auto_attr_update(FltHeader::AU_none);
00108 
00109   FltError result = header->read_flt(source);
00110   if (result != FE_ok) {
00111     nout << "Cannot read " << source << ": " << result << "\n";
00112     return false;
00113   }
00114 
00115   header->check_version();
00116 
00117   // Now scan the flt file for nested references.
00118   Refs refs;
00119   Textures textures;
00120   scan_flt(header, refs, textures);
00121 
00122   Refs::const_iterator ri;
00123   for (ri = refs.begin(); ri != refs.end(); ++ri) {
00124     FltExternalReference *ref = (*ri);
00125     Filename ref_filename = ref->get_ref_filename();
00126 
00127     if (!ref_filename.exists()) {
00128       nout << "*** Warning: external reference " << ref_filename
00129            << " does not exist.\n";
00130     } else {
00131       ExtraData ed;
00132       ed._type = FT_flt;
00133 
00134       CVSSourceDirectory *ref_dir =
00135         import(ref_filename, &ed, _model_dir);
00136       if (ref_dir == (CVSSourceDirectory *)NULL) {
00137         return false;
00138       }
00139 
00140       // Update the reference to point to the new flt filename, relative
00141       // to the base flt file.
00142       ref->set_ref_filename(dir->get_rel_to(ref_dir) + "/" +
00143                 ref_filename.get_basename());
00144     }
00145   }
00146 
00147   // Remove all the textures from the palette, and then add back only
00148   // those we found in use.  This way we don't copy a file that
00149   // references bogus textures.
00150   header->clear_textures();
00151 
00152   Textures::const_iterator ti;
00153   for (ti = textures.begin(); ti != textures.end(); ++ti) {
00154     FltTexture *tex = (*ti);
00155     Filename texture_filename = tex->get_texture_filename();
00156 
00157     if (!texture_filename.exists()) {
00158       nout << "*** Warning: texture " << texture_filename
00159            << " does not exist.\n";
00160     } else {
00161       ExtraData ed;
00162       ed._type = FT_texture;
00163       ed._texture = tex;
00164 
00165       CVSSourceDirectory *texture_dir =
00166         import(texture_filename, &ed, _map_dir);
00167       if (texture_dir == (CVSSourceDirectory *)NULL) {
00168         return false;
00169       }
00170 
00171       // Update the texture reference to point to the new texture
00172       // filename, relative to the flt file.
00173       tex->set_texture_filename(dir->get_rel_to(texture_dir) + "/" +
00174                 texture_filename.get_basename());
00175       header->add_texture(tex);
00176     }
00177   }
00178 
00179   // Finally, write the resulting file out.
00180   result = header->write_flt(dest);
00181   if (result != FE_ok) {
00182     nout << "Cannot write " << dest << "\n";
00183     return false;
00184   }
00185 
00186   return true;
00187 }
00188 
00189 ////////////////////////////////////////////////////////////////////
00190 //     Function: FltCopy::copy_texture
00191 //       Access: Private
00192 //  Description:
00193 ////////////////////////////////////////////////////////////////////
00194 bool FltCopy::
00195 copy_texture(const Filename &source, const Filename &dest,
00196              CVSSourceDirectory *dir, FltTexture *tex, bool new_file) {
00197   if (!copy_binary_file(source, dest)) {
00198     return false;
00199   }
00200 
00201   // Also write out the .attr file.
00202   Filename attr_filename = dest.get_fullpath() + ".attr";
00203   if (!attr_filename.exists()) {
00204     new_file = true;
00205   }
00206 
00207   tex->write_attr_data(attr_filename);
00208 
00209   if (new_file) {
00210     cvs_add(attr_filename);
00211   }
00212 
00213   return true;
00214 }
00215 
00216 ////////////////////////////////////////////////////////////////////
00217 //     Function: FltCopy::scan_flt
00218 //       Access: Private
00219 //  Description: Recursively walks through the flt file hierarchy,
00220 //               looking for texture references and external flt file
00221 //               references.
00222 ////////////////////////////////////////////////////////////////////
00223 void FltCopy::
00224 scan_flt(FltRecord *record, FltCopy::Refs &refs, FltCopy::Textures &textures) {
00225   if (record->is_of_type(FltFace::get_class_type())) {
00226     FltFace *face;
00227     DCAST_INTO_V(face, record);
00228     if (face->has_texture()) {
00229       textures.insert(face->get_texture());
00230     }
00231 
00232   } else if (record->is_of_type(FltExternalReference::get_class_type())) {
00233     FltExternalReference *ref;
00234     DCAST_INTO_V(ref, record);
00235 
00236     refs.insert(ref);
00237   }
00238 
00239   int i;
00240   int num_subfaces = record->get_num_subfaces();
00241   for (i = 0; i < num_subfaces; i++) {
00242     scan_flt(record->get_subface(i), refs, textures);
00243   }
00244 
00245   int num_children = record->get_num_children();
00246   for (i = 0; i < num_children; i++) {
00247     scan_flt(record->get_child(i), refs, textures);
00248   }
00249 }
00250 
00251 
00252 int main(int argc, char *argv[]) {
00253   FltCopy prog;
00254   prog.parse_command_line(argc, argv);
00255   prog.run();
00256   return 0;
00257 }

Generated on Fri May 2 03:19:57 2003 for Panda-Tool by doxygen1.3