00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00030
00031
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
00054
00055
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
00073
00074
00075
00076
00077
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
00097
00098
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
00106
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
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
00141
00142 ref->set_ref_filename(dir->get_rel_to(ref_dir) + "/" +
00143 ref_filename.get_basename());
00144 }
00145 }
00146
00147
00148
00149
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
00172
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
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
00191
00192
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
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
00218
00219
00220
00221
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 }