Panda3D
Loading...
Searching...
No Matches
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"
20#include "fltError.h"
21#include "dcast.h"
22
23/**
24 *
25 */
26FltCopy::
27FltCopy() {
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 */
49void FltCopy::
50run() {
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 */
68bool FltCopy::
69copy_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 */
87bool FltCopy::
88copy_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 */
177bool FltCopy::
178copy_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 */
203void FltCopy::
204scan_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
232int main(int argc, char *argv[]) {
233 FltCopy prog;
234 prog.parse_command_line(argc, argv);
235 prog.run();
236 return 0;
237}
This represents one particular directory in the hierarchy of source directory files.
Filename get_rel_from(const CVSSourceDirectory *other) const
Returns the relative path to this file as seen from the indicated source directory.
bool is_valid() const
Returns true if this FilePath represents a valid file, or false if it represents an error return.
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
std::string get_fullpath() const
Returns the entire filename: directory, basename, extension.
Definition filename.I:338
bool exists() const
Returns true if the filename exists on the physical disk, false otherwise.
A program to copy Multigen .flt files into the cvs tree.
Definition fltCopy.h:34
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.
void set_ref_filename(const Filename &filename)
Changes the name of the referenced file.
A single face bead, e.g.
Definition fltFace.h:24
bool has_texture() const
Returns true if the face has a texture applied, false otherwise.
Definition fltGeometry.I:18
FltTexture * get_texture() const
Returns the texture applied to this face, or NULL if no texture was applied.
Definition fltGeometry.I:27
This is the first bead in the file, the top of the bead hierarchy, and the primary interface to readi...
Definition fltHeader.h:44
The base class for all kinds of records in a MultiGen OpenFlight file.
Definition fltRecord.h:36
Represents a single texture in the texture palette.
Definition fltTexture.h:27
FltError write_attr_data() const
Writes the texture's .attr file.
void set_texture_filename(const Filename &filename)
Changes the name of the texture image file.
Filename get_texture_filename() const
Returns the name of the texture image file.
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_...
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.