Panda3D
fltCopy.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file fltCopy.cxx
10  * @author drose
11  * @date 2000-11-01
12  */
13 
14 #include "fltCopy.h"
15 
16 #include "cvsSourceDirectory.h"
17 #include "fltHeader.h"
18 #include "fltFace.h"
19 #include "fltExternalReference.h"
20 #include "fltError.h"
21 #include "dcast.h"
22 
23 /**
24  *
25  */
26 FltCopy::
27 FltCopy() {
28  set_program_brief("copy MultiGen .flt files into a CVS source hierarchy");
29  set_program_description
30  ("fltcopy copies one or more MultiGen .flt files into a "
31  "CVS source hierarchy. "
32  "Rather than copying the named files immediately into the current "
33  "directory, it first scans the entire source hierarchy, identifying all "
34  "the already-existing files. If the named file to copy matches the "
35  "name of an already-existing file in the current directory or elsewhere "
36  "in the hierarchy, that file is overwritten. Other .flt files, as "
37  "well as texture files, that are externally referenced by the "
38  "named .flt file(s) are similarly copied.");
39 
40  clear_runlines();
41  add_runline("[opts] file.flt [file.flt ... ]");
42 
43  add_path_replace_options();
44 }
45 
46 /**
47  *
48  */
49 void FltCopy::
50 run() {
51  SourceFiles::iterator fi;
52  for (fi = _source_files.begin(); fi != _source_files.end(); ++fi) {
53  ExtraData ed;
54  ed._type = FT_flt;
55 
56  CVSSourceTree::FilePath dest = import(*fi, &ed, _model_dir);
57  if (!dest.is_valid()) {
58  exit(1);
59  }
60  }
61 }
62 
63 /**
64  * Called by import() if verify_file() indicates that a file needs to be
65  * copied. This does the actual copy of a file from source to destination.
66  * If new_file is true, then dest does not already exist.
67  */
68 bool FltCopy::
69 copy_file(const Filename &source, const Filename &dest,
70  CVSSourceDirectory *dir, void *extra_data, bool new_file) {
71  ExtraData *ed = (ExtraData *)extra_data;
72  switch (ed->_type) {
73  case FT_flt:
74  return copy_flt_file(source, dest, dir);
75 
76  case FT_texture:
77  return copy_texture(source, dest, dir, ed->_texture, new_file);
78  }
79 
80  nout << "Internal error: invalid type " << (int)ed->_type << "\n";
81  return false;
82 }
83 
84 /**
85  *
86  */
87 bool FltCopy::
88 copy_flt_file(const Filename &source, const Filename &dest,
89  CVSSourceDirectory *dir) {
90  PT(FltHeader) header = new FltHeader(_path_replace);
91 
92  // We don't want to automatically generate .attr files--we'd rather write
93  // them out explicitly.
94  header->set_auto_attr_update(FltHeader::AU_none);
95 
96  FltError result = header->read_flt(source);
97  if (result != FE_ok) {
98  nout << "Cannot read " << source << ": " << result << "\n";
99  return false;
100  }
101 
102  header->check_version();
103 
104  // Now scan the flt file for nested references.
105  Refs refs;
106  Textures textures;
107  scan_flt(header, refs, textures);
108 
109  Refs::const_iterator ri;
110  for (ri = refs.begin(); ri != refs.end(); ++ri) {
111  FltExternalReference *ref = (*ri);
112  Filename ref_filename = ref->get_ref_filename();
113 
114  if (!ref_filename.exists()) {
115  nout << "*** Warning: external reference " << ref_filename
116  << " does not exist.\n";
117  } else {
118  ExtraData ed;
119  ed._type = FT_flt;
120 
121  CVSSourceTree::FilePath ref_path =
122  import(ref_filename, &ed, _model_dir);
123  if (!ref_path.is_valid()) {
124  return false;
125  }
126 
127  // Update the reference to point to the new flt filename, relative to
128  // the base flt file.
129  ref->set_ref_filename(ref_path.get_rel_from(dir));
130  }
131  }
132 
133  // Remove all the textures from the palette, and then add back only those we
134  // found in use. This way we don't copy a file that references bogus
135  // textures.
136  header->clear_textures();
137 
138  Textures::const_iterator ti;
139  for (ti = textures.begin(); ti != textures.end(); ++ti) {
140  FltTexture *tex = (*ti);
141  Filename texture_filename = tex->get_texture_filename();
142 
143  if (!texture_filename.exists()) {
144  nout << "*** Warning: texture " << texture_filename
145  << " does not exist.\n";
146  } else {
147  ExtraData ed;
148  ed._type = FT_texture;
149  ed._texture = tex;
150 
151  CVSSourceTree::FilePath texture_path =
152  import(texture_filename, &ed, _map_dir);
153  if (!texture_path.is_valid()) {
154  return false;
155  }
156 
157  // Update the texture reference to point to the new texture filename,
158  // relative to the flt file.
159  tex->set_texture_filename(texture_path.get_rel_from(dir));
160  header->add_texture(tex);
161  }
162  }
163 
164  // Finally, write the resulting file out.
165  result = header->write_flt(dest);
166  if (result != FE_ok) {
167  nout << "Cannot write " << dest << "\n";
168  return false;
169  }
170 
171  return true;
172 }
173 
174 /**
175  *
176  */
177 bool FltCopy::
178 copy_texture(const Filename &source, const Filename &dest,
179  CVSSourceDirectory *dir, FltTexture *tex, bool new_file) {
180  if (!copy_binary_file(source, dest)) {
181  return false;
182  }
183 
184  // Also write out the .attr file.
185  Filename attr_filename = dest.get_fullpath() + ".attr";
186  if (!attr_filename.exists()) {
187  new_file = true;
188  }
189 
190  tex->write_attr_data(attr_filename);
191 
192  if (new_file) {
193  cvs_add(attr_filename);
194  }
195 
196  return true;
197 }
198 
199 /**
200  * Recursively walks through the flt file hierarchy, looking for texture
201  * references and external flt file references.
202  */
203 void FltCopy::
204 scan_flt(FltRecord *record, FltCopy::Refs &refs, FltCopy::Textures &textures) {
205  if (record->is_of_type(FltFace::get_class_type())) {
206  FltFace *face;
207  DCAST_INTO_V(face, record);
208  if (face->has_texture()) {
209  textures.insert(face->get_texture());
210  }
211 
212  } else if (record->is_of_type(FltExternalReference::get_class_type())) {
214  DCAST_INTO_V(ref, record);
215 
216  refs.insert(ref);
217  }
218 
219  int i;
220  int num_subfaces = record->get_num_subfaces();
221  for (i = 0; i < num_subfaces; i++) {
222  scan_flt(record->get_subface(i), refs, textures);
223  }
224 
225  int num_children = record->get_num_children();
226  for (i = 0; i < num_children; i++) {
227  scan_flt(record->get_child(i), refs, textures);
228  }
229 }
230 
231 
232 int main(int argc, char *argv[]) {
233  FltCopy prog;
234  prog.parse_command_line(argc, argv);
235  prog.run();
236  return 0;
237 }
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool is_valid() const
Returns true if this FilePath represents a valid file, or false if it represents an error return.
Filename get_texture_filename() const
Returns the name of the texture image file.
Definition: fltTexture.cxx:101
virtual void parse_command_line(int argc, char **argv)
Dispatches on each of the options on the command line, and passes the remaining parameters to handle_...
void set_texture_filename(const Filename &filename)
Changes the name of the texture image file.
Definition: fltTexture.cxx:109
void set_ref_filename(const Filename &filename)
Changes the name of the referenced file.
A single face bead, e.g.
Definition: fltFace.h:24
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the first bead in the file, the top of the bead hierarchy, and the primary interface to readi...
Definition: fltHeader.h:44
FltError write_attr_data() const
Writes the texture's .attr file.
Definition: fltTexture.cxx:171
This represents one particular directory in the hierarchy of source directory files.
Represents a single texture in the texture palette.
Definition: fltTexture.h:27
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::string get_fullpath() const
Returns the entire filename: directory, basename, extension.
Definition: filename.I:338
The base class for all kinds of records in a MultiGen OpenFlight file.
Definition: fltRecord.h:36
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A program to copy Multigen .flt files into the cvs tree.
Definition: fltCopy.h:34
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An external reference to another flt file (possibly to a specific bead within the flt file).
Filename get_ref_filename() const
Returns the name of the referenced file.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:28
This is our own Panda specialization on the default STL set.
Definition: pset.h:49
bool has_texture() const
Returns true if the face has a texture applied, false otherwise.
Definition: fltGeometry.I:18
Filename get_rel_from(const CVSSourceDirectory *other) const
Returns the relative path to this file as seen from the indicated source directory.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
FltTexture * get_texture() const
Returns the texture applied to this face, or NULL if no texture was applied.
Definition: fltGeometry.I:27
bool exists() const
Returns true if the filename exists on the disk, false otherwise.
Definition: filename.cxx:1267