00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "fltCopy.h"
00016
00017 #include "cvsSourceDirectory.h"
00018 #include "fltHeader.h"
00019 #include "fltFace.h"
00020 #include "fltExternalReference.h"
00021 #include "fltError.h"
00022 #include "dcast.h"
00023 #include "pystub.h"
00024
00025
00026
00027
00028
00029
00030 FltCopy::
00031 FltCopy() {
00032 set_program_description
00033 ("fltcopy copies one or more MultiGen .flt files into a "
00034 "CVS source hierarchy. "
00035 "Rather than copying the named files immediately into the current "
00036 "directory, it first scans the entire source hierarchy, identifying all "
00037 "the already-existing files. If the named file to copy matches the "
00038 "name of an already-existing file in the current directory or elsewhere "
00039 "in the hierarchy, that file is overwritten. Other .flt files, as "
00040 "well as texture files, that are externally referenced by the "
00041 "named .flt file(s) are similarly copied.");
00042
00043 clear_runlines();
00044 add_runline("[opts] file.flt [file.flt ... ]");
00045
00046 add_path_replace_options();
00047 }
00048
00049
00050
00051
00052
00053
00054 void FltCopy::
00055 run() {
00056 SourceFiles::iterator fi;
00057 for (fi = _source_files.begin(); fi != _source_files.end(); ++fi) {
00058 ExtraData ed;
00059 ed._type = FT_flt;
00060
00061 CVSSourceTree::FilePath dest = import(*fi, &ed, _model_dir);
00062 if (!dest.is_valid()) {
00063 exit(1);
00064 }
00065 }
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 bool FltCopy::
00077 copy_file(const Filename &source, const Filename &dest,
00078 CVSSourceDirectory *dir, void *extra_data, bool new_file) {
00079 ExtraData *ed = (ExtraData *)extra_data;
00080 switch (ed->_type) {
00081 case FT_flt:
00082 return copy_flt_file(source, dest, dir);
00083
00084 case FT_texture:
00085 return copy_texture(source, dest, dir, ed->_texture, new_file);
00086 }
00087
00088 nout << "Internal error: invalid type " << (int)ed->_type << "\n";
00089 return false;
00090 }
00091
00092
00093
00094
00095
00096
00097 bool FltCopy::
00098 copy_flt_file(const Filename &source, const Filename &dest,
00099 CVSSourceDirectory *dir) {
00100 PT(FltHeader) header = new FltHeader(_path_replace);
00101
00102
00103
00104 header->set_auto_attr_update(FltHeader::AU_none);
00105
00106 FltError result = header->read_flt(source);
00107 if (result != FE_ok) {
00108 nout << "Cannot read " << source << ": " << result << "\n";
00109 return false;
00110 }
00111
00112 header->check_version();
00113
00114
00115 Refs refs;
00116 Textures textures;
00117 scan_flt(header, refs, textures);
00118
00119 Refs::const_iterator ri;
00120 for (ri = refs.begin(); ri != refs.end(); ++ri) {
00121 FltExternalReference *ref = (*ri);
00122 Filename ref_filename = ref->get_ref_filename();
00123
00124 if (!ref_filename.exists()) {
00125 nout << "*** Warning: external reference " << ref_filename
00126 << " does not exist.\n";
00127 } else {
00128 ExtraData ed;
00129 ed._type = FT_flt;
00130
00131 CVSSourceTree::FilePath ref_path =
00132 import(ref_filename, &ed, _model_dir);
00133 if (!ref_path.is_valid()) {
00134 return false;
00135 }
00136
00137
00138
00139 ref->set_ref_filename(ref_path.get_rel_from(dir));
00140 }
00141 }
00142
00143
00144
00145
00146 header->clear_textures();
00147
00148 Textures::const_iterator ti;
00149 for (ti = textures.begin(); ti != textures.end(); ++ti) {
00150 FltTexture *tex = (*ti);
00151 Filename texture_filename = tex->get_texture_filename();
00152
00153 if (!texture_filename.exists()) {
00154 nout << "*** Warning: texture " << texture_filename
00155 << " does not exist.\n";
00156 } else {
00157 ExtraData ed;
00158 ed._type = FT_texture;
00159 ed._texture = tex;
00160
00161 CVSSourceTree::FilePath texture_path =
00162 import(texture_filename, &ed, _map_dir);
00163 if (!texture_path.is_valid()) {
00164 return false;
00165 }
00166
00167
00168
00169 tex->set_texture_filename(texture_path.get_rel_from(dir));
00170 header->add_texture(tex);
00171 }
00172 }
00173
00174
00175 result = header->write_flt(dest);
00176 if (result != FE_ok) {
00177 nout << "Cannot write " << dest << "\n";
00178 return false;
00179 }
00180
00181 return true;
00182 }
00183
00184
00185
00186
00187
00188
00189 bool FltCopy::
00190 copy_texture(const Filename &source, const Filename &dest,
00191 CVSSourceDirectory *dir, FltTexture *tex, bool new_file) {
00192 if (!copy_binary_file(source, dest)) {
00193 return false;
00194 }
00195
00196
00197 Filename attr_filename = dest.get_fullpath() + ".attr";
00198 if (!attr_filename.exists()) {
00199 new_file = true;
00200 }
00201
00202 tex->write_attr_data(attr_filename);
00203
00204 if (new_file) {
00205 cvs_add(attr_filename);
00206 }
00207
00208 return true;
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218 void FltCopy::
00219 scan_flt(FltRecord *record, FltCopy::Refs &refs, FltCopy::Textures &textures) {
00220 if (record->is_of_type(FltFace::get_class_type())) {
00221 FltFace *face;
00222 DCAST_INTO_V(face, record);
00223 if (face->has_texture()) {
00224 textures.insert(face->get_texture());
00225 }
00226
00227 } else if (record->is_of_type(FltExternalReference::get_class_type())) {
00228 FltExternalReference *ref;
00229 DCAST_INTO_V(ref, record);
00230
00231 refs.insert(ref);
00232 }
00233
00234 int i;
00235 int num_subfaces = record->get_num_subfaces();
00236 for (i = 0; i < num_subfaces; i++) {
00237 scan_flt(record->get_subface(i), refs, textures);
00238 }
00239
00240 int num_children = record->get_num_children();
00241 for (i = 0; i < num_children; i++) {
00242 scan_flt(record->get_child(i), refs, textures);
00243 }
00244 }
00245
00246
00247 int main(int argc, char *argv[]) {
00248
00249 pystub();
00250
00251 FltCopy prog;
00252 prog.parse_command_line(argc, argv);
00253 prog.run();
00254 return 0;
00255 }