31 _no_data_nan_num_channels = 0;
32 _got_transform =
false;
33 _transform = LMatrix4::ident_mat();
38 set_program_brief(
"transform .pfm files");
39 set_program_description
40 (
"pfm-trans reads an pfm file and transforms it, filters it, " 41 "operates on it, writing the output to another pfm file. A pfm " 42 "file contains a 2-d table of floating-point values.");
46 "Treats (0,0,0) in the pfm file as a special don't-touch value.",
47 &PfmTrans::dispatch_none, &_got_zero_special);
50 (
"nan",
"num_channels", 0,
51 "Treats a NaN in any of the first num_channels channels as a special don't-touch value.",
52 &PfmTrans::dispatch_int, &_got_no_data_nan, &_no_data_nan_num_channels);
55 (
"resize",
"width,height", 0,
56 "Resamples the pfm file to scale it to the indicated grid size. " 57 "A simple box filter is applied during the scale. Don't confuse this " 58 "with -TS, which scales the individual point values, but doesn't " 59 "change the number of points.",
60 &PfmTrans::dispatch_int_pair, &_got_resize, &_resize);
63 (
"crop",
"xbegin,xend,ybegin,yend", 0,
64 "Crops the pfm file to the indicated subregion.",
65 &PfmTrans::dispatch_int_quad, &_got_crop, &_crop);
69 "Automatically crops to the smallest possible rectangle that includes " 70 "all points. Requires -z or -nan.",
71 &PfmTrans::dispatch_none, &_got_autocrop);
74 (
"rotate",
"degrees", 0,
75 "Rotates the pfm file the specified number of degrees counterclockwise, " 76 "which must be a multiple of 90.",
77 &PfmTrans::dispatch_int,
nullptr, &_rotate);
81 "Flips the pfm file about the x axis.",
82 &PfmTrans::dispatch_none, &_got_mirror_x);
86 "Flips the pfm file about the y axis.",
87 &PfmTrans::dispatch_none, &_got_mirror_y);
91 "Specify the filename to which the resulting pfm file will be written. " 92 "This is only valid when there is only one input pfm file on the command " 93 "line. If you want to process multiple files simultaneously, you must " 95 &PfmTrans::dispatch_filename, &_got_output_filename, &_output_filename);
99 "Specify the name of the directory in which to write the processed pfm " 100 "files. If you are processing only one pfm file, this may be omitted " 101 "in lieu of the -o option.",
102 &PfmTrans::dispatch_filename, &_got_output_dirname, &_output_dirname);
105 (
"vis",
"filename.bam", 60,
106 "Generates a bam file that represents a visualization of the pfm file " 107 "as a 3-D geometric mesh. If -vistex is specified, the mesh is " 109 &PfmTrans::dispatch_filename, &_got_vis_filename, &_vis_filename);
113 "Inverts the visualization, generating a uniform 2-d mesh with the " 114 "3-d depth values encoded in the texture coordinates.",
115 &PfmTrans::dispatch_none, &_got_vis_inverse);
119 "Respect only the first two components of each depth value, ignoring z.",
120 &PfmTrans::dispatch_none, &_got_vis_2d);
123 (
"vistex",
"texture.jpg", 60,
124 "Specifies the name of the texture to apply to the visualization.",
125 &PfmTrans::dispatch_filename, &_got_vistex_filename, &_vistex_filename);
128 (
"ls",
"filename.txt", 60,
129 "Lists the points in the file to the indicated text file.",
130 &PfmTrans::dispatch_filename, &_got_ls_filename, &_ls_filename);
139 if ((
int)(_rotate / 90) * 90 != _rotate) {
140 nout <<
"-rotate can only accept a multiple of 90 degrees.\n";
144 if (_got_vis_filename) {
148 Filenames::const_iterator fi;
149 for (fi = _input_filenames.begin(); fi != _input_filenames.end(); ++fi) {
151 if (!file.
read(*fi)) {
152 nout <<
"Cannot read " << *fi <<
"\n";
160 if (_got_vis_filename) {
171 if (_got_no_data_nan) {
173 }
else if (_got_zero_special) {
180 _got_crop = file.
calc_autocrop(_crop[0], _crop[1], _crop[2], _crop[3]);
184 file.
apply_crop(_crop[0], _crop[1], _crop[2], _crop[3]);
188 file.
resize(_resize[0], _resize[1]);
192 int r = (_rotate / 90) % 4;
201 file.
flip(
true,
false,
true);
208 file.
flip(
true,
false,
false);
209 file.
flip(
false,
true,
false);
213 file.
flip(
false,
true,
true);
216 nassertr(
false,
false);
221 file.
flip(
true,
false,
false);
225 file.
flip(
false,
true,
false);
228 if (_got_transform) {
229 file.
xform(LCAST(PN_float32, _transform));
232 if (_got_vis_filename) {
234 if (_got_vistex_filename) {
236 if (tex ==
nullptr) {
237 nout <<
"Couldn't find " << _vistex_filename <<
"\n";
239 tex->set_minfilter(SamplerState::FT_linear_mipmap_linear);
241 if (tex->has_alpha(tex->get_format())) {
250 if (_got_ls_filename) {
254 for (
int yi = 0; yi < file.
get_y_size(); ++yi) {
255 for (
int xi = 0; xi < file.
get_x_size(); ++xi) {
257 out <<
"(" << xi <<
", " << yi <<
"):";
269 if (_got_output_filename) {
270 output_filename = _output_filename;
271 }
else if (_got_output_dirname) {
275 if (!output_filename.empty()) {
276 return file.
write(output_filename);
290 (
"TS",
"sx[,sy,sz]", 49,
291 "Scale the model uniformly by the given factor (if only one number " 292 "is given) or in each axis by sx, sy, sz (if three numbers are given).",
293 &PfmTrans::dispatch_scale, &_got_transform, &_transform);
297 "Rotate the model x degrees about the x axis, then y degrees about the " 298 "y axis, and then z degrees about the z axis.",
299 &PfmTrans::dispatch_rotate_xyz, &_got_transform, &_transform);
302 (
"TA",
"angle,x,y,z", 49,
303 "Rotate the model angle degrees counterclockwise about the given " 305 &PfmTrans::dispatch_rotate_axis, &_got_transform, &_transform);
309 "Translate the model by the indicated amount.\n\n" 310 "All transformation options (-TS, -TR, -TA, -TT) are cumulative and are " 311 "applied in the order they are encountered on the command line.",
312 &PfmTrans::dispatch_translate, &_got_transform, &_transform);
323 nout <<
"You must specify the pfm file(s) to read on the command line.\n";
327 if (_got_output_filename && args.size() == 1) {
328 if (_got_output_dirname) {
329 nout <<
"Cannot specify both -o and -d.\n";
334 if (_got_output_filename) {
335 nout <<
"Cannot use -o when multiple pfm files are specified.\n";
340 Args::const_iterator ai;
341 for (ai = args.begin(); ai != args.end(); ++ai) {
352 dispatch_scale(
const string &opt,
const string &arg,
void *var) {
353 LMatrix4 *transform = (LMatrix4 *)var;
358 PN_stdfloat sx, sy, sz;
361 if (words.size() == 3) {
363 string_to_stdfloat(words[0], sx) &&
364 string_to_stdfloat(words[1], sy) &&
365 string_to_stdfloat(words[2], sz);
367 }
else if (words.size() == 1) {
369 string_to_stdfloat(words[0], sx);
375 <<
" requires one or three numbers separated by commas.\n";
379 *transform = (*transform) * LMatrix4::scale_mat(sx, sy, sz);
389 dispatch_rotate_xyz(
ProgramBase *
self,
const string &opt,
const string &arg,
void *var) {
391 return base->ns_dispatch_rotate_xyz(opt, arg, var);
399 ns_dispatch_rotate_xyz(
const string &opt,
const string &arg,
void *var) {
400 LMatrix4 *transform = (LMatrix4 *)var;
408 if (words.size() == 3) {
410 string_to_stdfloat(words[0], xyz[0]) &&
411 string_to_stdfloat(words[1], xyz[1]) &&
412 string_to_stdfloat(words[2], xyz[2]);
417 <<
" requires three numbers separated by commas.\n";
422 LMatrix4::rotate_mat(xyz[0], LVector3(1.0, 0.0, 0.0)) *
423 LMatrix4::rotate_mat(xyz[1], LVector3(0.0, 1.0, 0.0)) *
424 LMatrix4::rotate_mat(xyz[2], LVector3(0.0, 0.0, 1.0));
426 *transform = (*transform) * mat;
436 dispatch_rotate_axis(
ProgramBase *
self,
const string &opt,
const string &arg,
void *var) {
438 return base->ns_dispatch_rotate_axis(opt, arg, var);
446 ns_dispatch_rotate_axis(
const string &opt,
const string &arg,
void *var) {
447 LMatrix4 *transform = (LMatrix4 *)var;
456 if (words.size() == 4) {
458 string_to_stdfloat(words[0], angle) &&
459 string_to_stdfloat(words[1], axis[0]) &&
460 string_to_stdfloat(words[2], axis[1]) &&
461 string_to_stdfloat(words[3], axis[2]);
466 <<
" requires four numbers separated by commas.\n";
470 *transform = (*transform) * LMatrix4::rotate_mat(angle, axis);
479 dispatch_translate(
const string &opt,
const string &arg,
void *var) {
480 LMatrix4 *transform = (LMatrix4 *)var;
488 if (words.size() == 3) {
490 string_to_stdfloat(words[0], trans[0]) &&
491 string_to_stdfloat(words[1], trans[1]) &&
492 string_to_stdfloat(words[2], trans[2]);
497 <<
" requires three numbers separated by commas.\n";
501 *transform = (*transform) * LMatrix4::translate_mat(trans);
507 int main(
int argc,
char *argv[]) {
This is intended to be the base class for most general-purpose utility programs in the PANDATOOL tree...
bool open_write(std::ofstream &stream, bool truncate=true) const
Opens the indicated ifstream for writing the file, if possible.
void set_vis_inverse(bool vis_inverse)
Sets the vis_inverse flag.
bool has_point(int x, int y) const
Returns true if there is a valid point at x, y.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
set_name
Changes the name of the referenced node.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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_...
NodePath generate_vis_mesh(MeshFace face=MF_front) const
Creates a triangle mesh with the points of the pfm as 3-d coordinates in space, and texture coordinat...
std::string get_basename_wo_extension() const
Returns the basename part of the filename, without the file extension.
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
void set_text()
Indicates that the filename represents a text file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_vis_2d(bool vis_2d)
Sets the vis_2d flag.
void set_texture(Texture *tex, int priority=0)
Adds the indicated texture to the list of textures that will be rendered on the default texture stage...
void resize(int new_x_size, int new_y_size)
Applies a simple filter to resample the pfm file in-place to the indicated size.
bool read(const Filename &fullpath)
Reads the PFM data from the indicated file, returning true on success, false on failure.
bool write(const Filename &fullpath)
Writes the PFM data to the indicated file, returning true on success, false on failure.
void reparent_to(const NodePath &other, int sort=0, Thread *current_thread=Thread::get_current_thread())
Removes the referenced node of the NodePath from its current parent and attaches it to the referenced...
void apply_crop(int x_begin, int x_end, int y_begin, int y_end)
Reduces the PFM file to the cells in the rectangle bounded by (x_begin, x_end, y_begin,...
The name of a file, such as a texture file or an Egg file.
Defines a pfm file, a 2-d table of floating-point numbers, either 3-component or 1-component,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool write_bam_file(const Filename &filename) const
Writes the contents of this node and below out to a bam file with the indicated filename.
PN_float32 get_channel(int x, int y, int c) const
Returns the cth channel of the point value at the indicated point.
static Texture * load_texture(const Filename &filename, int primary_file_num_channels=0, bool read_mipmaps=false, const LoaderOptions &options=LoaderOptions())
Loads the given filename up into a texture, if it has not already been loaded, and returns the new te...
void flip(bool flip_x, bool flip_y, bool transpose)
Reverses, transposes, and/or rotates the table in-place according to the specified parameters.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::string get_basename() const
Returns the basename part of the filename.
void tokenize(const string &str, vector_string &words, const string &delimiters, bool discard_repeated_delimiters)
Chops the source string up into pieces delimited by any of the characters specified in delimiters.
void xform(const LMatrix4f &transform)
Applies the indicated transform matrix to all points in-place.
void set_zero_special(bool zero_special)
Sets the zero_special flag.
bool process_pfm(const Filename &input_filename, PfmFile &file)
Handles a single pfm file.
void set_transparency(TransparencyAttrib::Mode mode, int priority=0)
Specifically sets or disables transparent rendering mode on this particular node.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add_transform_options()
Adds -TS, -TT, etc.
bool calc_autocrop(int &x_begin, int &x_end, int &y_begin, int &y_end) const
Computes the minimum range of x and y across the PFM file that include all points.
NodePath is the fundamental system for disambiguating instances, and also provides a higher-level int...
void set_no_data_nan(int num_channels)
Sets the no_data_nan flag.
static Filename from_os_specific(const std::string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes,...
This class aids in the visualization and manipulation of PfmFile objects.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.