Panda3D
eggWriter.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 eggWriter.cxx
10  * @author drose
11  * @date 2000-02-14
12  */
13 
14 #include "eggWriter.h"
15 
16 #include "string_utils.h"
17 #include "compose_matrix.h"
18 #include "globPattern.h"
19 
20 /**
21  * Egg-writing type programs may specify their output file using either the
22  * last-filename convention, the -o convention, and/or implicitly writing the
23  * result to standard output. Not all interfaces are appropriate for all
24  * applications; some may be confusing or dangerous.
25  *
26  * The calling application should pass allow_last_param true to allow the user
27  * to specify the output filename as the last parameter on the command line
28  * (the most dangerous, but convenient, method), and allow_stdout true to
29  * allow the user to omit the output filename altogether and have the output
30  * implicitly go to standard output (not terribly dangerous, but inappropriate
31  * when writing binary file formats).
32  */
34 EggWriter(bool allow_last_param, bool allow_stdout) :
35  WithOutputFile(allow_last_param, allow_stdout, false)
36 {
37  // Indicate the extension name we expect the user to supply for output
38  // files.
39  _preferred_extension = ".egg";
40 
41  clear_runlines();
42  if (_allow_last_param) {
43  add_runline("[opts] output.egg");
44  }
45  add_runline("[opts] -o output.egg");
46  if (_allow_stdout) {
47  add_runline("[opts] >output.egg");
48  }
49 
50  std::string o_description;
51 
52  if (_allow_stdout) {
53  if (_allow_last_param) {
54  o_description =
55  "Specify the filename to which the resulting egg file will be written. "
56  "If this option is omitted, the last parameter name is taken to be the "
57  "name of the output file, or standard output is used if there are no "
58  "other parameters.";
59  } else {
60  o_description =
61  "Specify the filename to which the resulting egg file will be written. "
62  "If this option is omitted, the egg file is written to standard output.";
63  }
64  } else {
65  if (_allow_last_param) {
66  o_description =
67  "Specify the filename to which the resulting egg file will be written. "
68  "If this option is omitted, the last parameter name is taken to be the "
69  "name of the output file.";
70  } else {
71  o_description =
72  "Specify the filename to which the resulting egg file will be written.";
73  }
74  }
75 
76  add_option
77  ("o", "filename", 50, o_description,
78  &EggWriter::dispatch_filename, &_got_output_filename, &_output_filename);
79 
80  redescribe_option
81  ("cs",
82  "Specify the coordinate system of the resulting egg file. This may be "
83  "one of 'y-up', 'z-up', 'y-up-left', or 'z-up-left'. The default is "
84  "y-up.");
85 }
86 
87 
88 /**
89  * Returns this object as an EggWriter pointer, if it is in fact an EggWriter,
90  * or NULL if it is not.
91  *
92  * This is intended to work around the C++ limitation that prevents downcasts
93  * past virtual inheritance. Since both EggReader and EggWriter inherit
94  * virtually from EggSingleBase, we need functions like this to downcast to
95  * the appropriate pointer.
96  */
99  return this;
100 }
101 
102 /**
103  * Performs any processing of the egg file that is appropriate before writing
104  * it out. This includes any normal adjustments the user requested via -np,
105  * etc.
106  *
107  * Normally, you should not need to call this function directly;
108  * write_egg_file() calls it for you. You should call this only if you do not
109  * use write_egg_file() to write out the resulting egg file.
110  */
111 void EggWriter::
113  if (_got_transform) {
114  nout << "Applying transform matrix:\n";
115  _transform.write(nout, 2);
116  LVecBase3d scale, hpr, translate;
117  if (decompose_matrix(_transform, scale, hpr, translate,
118  _data->get_coordinate_system())) {
119  nout << "(scale " << scale << ", hpr " << hpr << ", translate "
120  << translate << ")\n";
121  }
122  _data->transform(_transform);
123  }
124 
125  if (_make_points) {
126  nout << "Making points\n";
127  _data->make_point_primitives();
128  }
129 
130  bool needs_remove = false;
131 
132  switch (_normals_mode) {
133  case NM_strip:
134  nout << "Stripping normals.\n";
135  _data->strip_normals();
136  needs_remove = true;
137  break;
138 
139  case NM_polygon:
140  nout << "Recomputing polygon normals.\n";
141  _data->recompute_polygon_normals();
142  needs_remove = true;
143  break;
144 
145  case NM_vertex:
146  nout << "Recomputing vertex normals.\n";
147  _data->recompute_vertex_normals(_normals_threshold);
148  needs_remove = true;
149  break;
150 
151  case NM_preserve:
152  // Do nothing.
153  break;
154  }
155 
156  if (_got_tbnall) {
157  needs_remove |= _data->recompute_tangent_binormal(GlobPattern("*"));
158  } else {
159  if (_got_tbnauto) {
160  needs_remove |= _data->recompute_tangent_binormal_auto();
161  }
162  needs_remove |= _data->recompute_tangent_binormal(_tbn_names);
163  }
164 
165  if (needs_remove) {
166  _data->remove_unused_vertices(true);
167  }
168 }
169 
170 /**
171  * Writes out the egg file as the normal result of the program. This calls
172  * post_process_egg_file() to perform any last minute processing (like normal
173  * computation) and then writes out the file to the output stream returned by
174  * get_output().
175  */
176 void EggWriter::
179  _data->write_egg(get_output());
180 }
181 
182 /**
183  * Does something with the additional arguments on the command line (after all
184  * the -options have been parsed). Returns true if the arguments are good,
185  * false otherwise.
186  */
187 bool EggWriter::
188 handle_args(ProgramBase::Args &args) {
189  if (!check_last_arg(args, 0)) {
190  return false;
191  }
192 
193  if (!args.empty()) {
194  nout << "Unexpected arguments on command line:\n";
195  Args::const_iterator ai;
196  for (ai = args.begin(); ai != args.end(); ++ai) {
197  nout << (*ai) << " ";
198  }
199  nout << "\r";
200  return false;
201  }
202 
203  if (!_got_path_directory && _got_output_filename) {
204  // Put in the name of the output directory.
205  _path_replace->_path_directory = _output_filename.get_dirname();
206  }
207 
208  return true;
209 }
210 
211 /**
212  *
213  */
214 bool EggWriter::
215 post_command_line() {
216  if (!_allow_stdout && !_got_output_filename) {
217  nout << "You must specify the filename to write with -o.\n";
218  return false;
219  }
220 
221  append_command_comment(_data);
222 
223  return EggSingleBase::post_command_line();
224 }
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void post_process_egg_file()
Performs any processing of the egg file that is appropriate before writing it out.
Definition: eggWriter.cxx:112
void write_egg_file()
Writes out the egg file as the normal result of the program.
Definition: eggWriter.cxx:177
virtual EggWriter * as_writer()
Returns this object as an EggWriter pointer, if it is in fact an EggWriter, or NULL if it is not.
Definition: eggWriter.cxx:98
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the bare functionality (intended to be inherited from along with ProgramBase or some derivati...
This is the base class for a program that generates an egg file output, but doesn't read any for inpu...
Definition: eggWriter.h:28
EggWriter(bool allow_last_param=false, bool allow_stdout=true)
Egg-writing type programs may specify their output file using either the last-filename convention,...
Definition: eggWriter.cxx:34
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::ostream & get_output()
Returns an output stream that corresponds to the user's intended egg file output–either stdout,...
This class can be used to test for string matches against standard Unix- shell filename globbing conv...
Definition: globPattern.h:32