From 82b1ac94c46cfcf8c1d22df0f9fe232a434699d1 Mon Sep 17 00:00:00 2001 From: Josh Yelon Date: Mon, 8 Aug 2005 01:57:40 +0000 Subject: [PATCH] Fixes related to -ps keep, -ps rel --- pandatool/src/eggbase/eggBase.cxx | 21 +-- pandatool/src/eggbase/eggMultiBase.cxx | 4 +- pandatool/src/eggbase/eggReader.cxx | 4 +- pandatool/src/eggbase/eggWriter.cxx | 1 + pandatool/src/eggbase/somethingToEgg.cxx | 5 + pandatool/src/maxegg/maxToEggConverter.cxx | 102 ++++++------ pandatool/src/mayaegg/mayaToEggConverter.cxx | 18 ++- pandatool/src/pandatoolbase/pathReplace.I | 4 +- pandatool/src/pandatoolbase/pathReplace.cxx | 162 +++++++++++++++++++ pandatool/src/pandatoolbase/pathReplace.h | 5 + 10 files changed, 258 insertions(+), 68 deletions(-) diff --git a/pandatool/src/eggbase/eggBase.cxx b/pandatool/src/eggbase/eggBase.cxx index f2c142cba4..92e12abbbe 100644 --- a/pandatool/src/eggbase/eggBase.cxx +++ b/pandatool/src/eggbase/eggBase.cxx @@ -153,24 +153,27 @@ convert_paths(EggNode *node, PathReplace *path_replace, const DSearchPath &additional_path) { if (node->is_of_type(EggTexture::get_class_type())) { EggTexture *egg_tex = DCAST(EggTexture, node); - Filename fullpath = - path_replace->match_path(egg_tex->get_filename(), additional_path); - egg_tex->set_filename(path_replace->store_path(fullpath)); + Filename fullpath, outpath; + path_replace->full_convert_path(egg_tex->get_filename(), additional_path, + fullpath, outpath); + egg_tex->set_filename(outpath); egg_tex->set_fullpath(fullpath); if (egg_tex->has_alpha_filename()) { - Filename alpha_fullpath = - path_replace->match_path(egg_tex->get_alpha_filename(), additional_path); - egg_tex->set_alpha_filename(path_replace->store_path(alpha_fullpath)); + Filename alpha_fullpath, alpha_outpath; + path_replace->full_convert_path(egg_tex->get_alpha_filename(), additional_path, + alpha_fullpath, alpha_outpath); + egg_tex->set_alpha_filename(alpha_outpath); egg_tex->set_alpha_fullpath(alpha_fullpath); } } else if (node->is_of_type(EggFilenameNode::get_class_type())) { EggFilenameNode *egg_fnode = DCAST(EggFilenameNode, node); - Filename fullpath = - path_replace->match_path(egg_fnode->get_filename(), additional_path); - egg_fnode->set_filename(path_replace->store_path(fullpath)); + Filename fullpath, outpath; + path_replace->full_convert_path(egg_fnode->get_filename(), additional_path, + fullpath, outpath); + egg_fnode->set_filename(outpath); egg_fnode->set_fullpath(fullpath); } else if (node->is_of_type(EggGroupNode::get_class_type())) { diff --git a/pandatool/src/eggbase/eggMultiBase.cxx b/pandatool/src/eggbase/eggMultiBase.cxx index 0b403e0778..cec3fad69f 100644 --- a/pandatool/src/eggbase/eggMultiBase.cxx +++ b/pandatool/src/eggbase/eggMultiBase.cxx @@ -145,7 +145,9 @@ read_egg(const Filename &filename) { // filename, since egg files almost always store relative paths. // This is a temporary kludge around integrating the path_replace // system with the EggData better. - data->resolve_filenames(file_path); + // + // Update: I believe this kludge is obsolete. Commenting out. - Josh. + // data->resolve_filenames(file_path); if (_force_complete) { if (!data->load_externals()) { diff --git a/pandatool/src/eggbase/eggReader.cxx b/pandatool/src/eggbase/eggReader.cxx index 816acbfc62..6de0425968 100644 --- a/pandatool/src/eggbase/eggReader.cxx +++ b/pandatool/src/eggbase/eggReader.cxx @@ -198,7 +198,9 @@ handle_args(ProgramBase::Args &args) { // filename, since egg files almost always store relative paths. // This is a temporary kludge around integrating the path_replace // system with the EggData better. - file_data.resolve_filenames(file_path); + // + // Update: I believe this kludge is obsolete. Commenting out. - Josh. + // file_data.resolve_filenames(file_path); if (_force_complete) { if (!file_data.load_externals()) { diff --git a/pandatool/src/eggbase/eggWriter.cxx b/pandatool/src/eggbase/eggWriter.cxx index ebe4a8d382..6f92318d3b 100644 --- a/pandatool/src/eggbase/eggWriter.cxx +++ b/pandatool/src/eggbase/eggWriter.cxx @@ -220,6 +220,7 @@ handle_args(ProgramBase::Args &args) { if (!_got_path_directory && _got_output_filename) { // Put in the name of the output directory. _path_replace->_path_directory = _output_filename.get_dirname(); + cerr << "_path_directory defaults to " << _path_replace->_path_directory << " in eggWriter\n"; } return true; diff --git a/pandatool/src/eggbase/somethingToEgg.cxx b/pandatool/src/eggbase/somethingToEgg.cxx index 746602b051..20cd4cfd09 100644 --- a/pandatool/src/eggbase/somethingToEgg.cxx +++ b/pandatool/src/eggbase/somethingToEgg.cxx @@ -291,6 +291,11 @@ handle_args(Args &args) { return false; } + if (!_got_path_directory && _got_output_filename) { + // Put in the name of the output directory. + _path_replace->_path_directory = _output_filename.get_dirname(); + } + return true; } diff --git a/pandatool/src/maxegg/maxToEggConverter.cxx b/pandatool/src/maxegg/maxToEggConverter.cxx index ce89e38584..e74a83f8a9 100755 --- a/pandatool/src/maxegg/maxToEggConverter.cxx +++ b/pandatool/src/maxegg/maxToEggConverter.cxx @@ -1865,9 +1865,10 @@ set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader) { if (color_def._has_texture) { // If we have a texture on color, apply it as the filename. Filename filename = Filename::from_os_specific(color_def._texture); - Filename fullpath = - _path_replace->match_path(filename, get_texture_path()); - tex.set_filename(_path_replace->store_path(fullpath)); + Filename fullpath,outpath; + _path_replace->full_convert_path(filename, get_texture_path(), + fullpath, outpath); + tex.set_filename(outpath); tex.set_fullpath(fullpath); apply_texture_properties(tex, color_def); @@ -1910,8 +1911,9 @@ set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader) { // set_alpha_file_channel()), but for now we assume it comes // from the grayscale data. filename = Filename::from_os_specific(trans_def._texture); - fullpath = _path_replace->match_path(filename, get_texture_path()); - tex.set_alpha_filename(_path_replace->store_path(fullpath)); + _path_replace->full_convert_path(filename, get_texture_path(), + fullpath, outpath); + tex.set_alpha_filename(outpath); tex.set_alpha_fullpath(fullpath); } @@ -1926,9 +1928,10 @@ set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader) { // We have a texture on transparency only. Apply it as the // primary filename, and set the format accordingly. Filename filename = Filename::from_os_specific(trans_def._texture); - Filename fullpath = - _path_replace->match_path(filename, get_texture_path()); - tex.set_filename(_path_replace->store_path(fullpath)); + Filename fullpath, outpath; + _path_replace->full_convert_path(filename, get_texture_path(), + fullpath, outpath); + tex.set_filename(outpath); tex.set_fullpath(fullpath); tex.set_format(EggTexture::F_alpha); apply_texture_properties(tex, trans_def); @@ -2014,9 +2017,10 @@ set_material_attributes(EggPrimitive &primitive, Mtl *maxMaterial, Face *face) { maxBitmapTex = (BitmapTex *) maxTexmap; Filename filename = Filename::from_os_specific(maxBitmapTex->GetMapName()); - Filename fullpath = - _path_replace->match_path(filename, get_texture_path()); - tex.set_filename(_path_replace->store_path(fullpath)); + Filename fullpath, outpath; + _path_replace->full_convert_path(filename, get_texture_path(), + fullpath, outpath); + tex.set_filename(outpath); tex.set_fullpath(fullpath); apply_texture_properties(tex, maxStandardMaterial); // *** Must add stuff here for looking for transparencies @@ -2142,54 +2146,56 @@ set_material_attributes(EggPrimitive &primitive, Mtl *maxMaterial, Face *face) { ostringstream name_strm; name_strm << "Tex" << ++_cur_tref; EggTexture tex(name_strm.str(), ""); - - if (has_diffuse_texture) { - // It is! - - Filename filename = Filename::from_os_specific(diffuseBitmapTex->GetMapName()); - Filename fullpath = - _path_replace->match_path(filename, get_texture_path()); - tex.set_filename(_path_replace->store_path(fullpath)); - tex.set_fullpath(fullpath); - apply_texture_properties(tex, maxStandardMaterial); - // *** Must add stuff here for looking for transparencies - diffuseBitmap = diffuseBitmapTex->GetBitmap(0); - //Query some parameters of the bitmap to get the format option. - if ( has_trans_texture ) { - tex.set_format(EggTexture::F_rgba); - if (stricmp(diffuseBitmapTex->GetMapName(), - transBitmapTex->GetMapName()) == 0) { - // nothing more needs to be done - } else { + + if (has_diffuse_texture) { + // It is! + Filename filename = Filename::from_os_specific(diffuseBitmapTex->GetMapName()); + Filename fullpath, outpath; + _path_replace->full_convert_path(filename, get_texture_path(), + fullpath, outpath); + tex.set_filename(outpath); + tex.set_fullpath(fullpath); + apply_texture_properties(tex, maxStandardMaterial); + // *** Must add stuff here for looking for transparencies + diffuseBitmap = diffuseBitmapTex->GetBitmap(0); + //Query some parameters of the bitmap to get the format option. + if ( has_trans_texture ) { + tex.set_format(EggTexture::F_rgba); + if (stricmp(diffuseBitmapTex->GetMapName(), + transBitmapTex->GetMapName()) == 0) { + // nothing more needs to be done + } else { filename = Filename::from_os_specific(transBitmapTex->GetMapName()); - fullpath = _path_replace->match_path(filename, get_texture_path()); - tex.set_alpha_filename(_path_replace->store_path(fullpath)); + _path_replace->full_convert_path(filename, get_texture_path(), + fullpath, outpath); + tex.set_alpha_filename(outpath); tex.set_alpha_fullpath(fullpath); - } - } else { - if ( diffuseBitmap && diffuseBitmap->HasAlpha()) { - tex.set_format(EggTexture::F_rgba); - } else { - tex.set_format(EggTexture::F_rgb); - } + } + } else { + if ( diffuseBitmap && diffuseBitmap->HasAlpha()) { + tex.set_format(EggTexture::F_rgba); + } else { + tex.set_format(EggTexture::F_rgb); + } } - } else { + } else { // We have a texture on transparency only. Apply it as the // primary filename, and set the format accordingly. Filename filename = Filename::from_os_specific(transBitmapTex->GetMapName()); - Filename fullpath = - _path_replace->match_path(filename, get_texture_path()); - tex.set_filename(_path_replace->store_path(fullpath)); + Filename fullpath, outpath; + _path_replace->full_convert_path(filename, get_texture_path(), + fullpath, outpath); + tex.set_filename(outpath); tex.set_fullpath(fullpath); tex.set_format(EggTexture::F_alpha); apply_texture_properties(tex, maxStandardMaterial); - } - EggTexture *new_tex = - _textures.create_unique_texture(tex, ~EggTexture::E_tref_name); - + } + EggTexture *new_tex = + _textures.create_unique_texture(tex, ~EggTexture::E_tref_name); + primitive.set_texture(new_tex); } - + // Also apply an overall color to the primitive. Colorf rgba(1.0f, 1.0f, 1.0f, 1.0f); diff --git a/pandatool/src/mayaegg/mayaToEggConverter.cxx b/pandatool/src/mayaegg/mayaToEggConverter.cxx index f1c8ef2eda..4bbd381369 100644 --- a/pandatool/src/mayaegg/mayaToEggConverter.cxx +++ b/pandatool/src/mayaegg/mayaToEggConverter.cxx @@ -2280,9 +2280,9 @@ set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader, // If we have a texture on color, apply it as the filename. //mayaegg_cat.debug() << "ssa:got texture name" << color_def->_texture_filename << endl; Filename filename = Filename::from_os_specific(color_def->_texture_filename); - Filename fullpath = - _path_replace->match_path(filename, get_texture_path()); - tex.set_filename(_path_replace->store_path(fullpath)); + Filename fullpath, outpath; + _path_replace->full_convert_path(filename, get_texture_path(), fullpath, outpath); + tex.set_filename(outpath); tex.set_fullpath(fullpath); apply_texture_properties(tex, *color_def); @@ -2325,8 +2325,9 @@ set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader, // set_alpha_file_channel()), but for now we assume it comes // from the grayscale data. filename = Filename::from_os_specific(trans_def._texture_filename); - fullpath = _path_replace->match_path(filename, get_texture_path()); - tex.set_alpha_filename(_path_replace->store_path(fullpath)); + _path_replace->full_convert_path(filename, get_texture_path(), + fullpath, outpath); + tex.set_alpha_filename(outpath); tex.set_alpha_fullpath(fullpath); } } else { @@ -2355,9 +2356,10 @@ set_shader_attributes(EggPrimitive &primitive, const MayaShader &shader, // We have a texture on transparency only. Apply it as the // primary filename, and set the format accordingly. Filename filename = Filename::from_os_specific(trans_def._texture_filename); - Filename fullpath = - _path_replace->match_path(filename, get_texture_path()); - tex.set_filename(_path_replace->store_path(fullpath)); + Filename fullpath,outpath; + _path_replace->full_convert_path(filename, get_texture_path(), + fullpath, outpath); + tex.set_filename(outpath); tex.set_fullpath(fullpath); apply_texture_properties(tex, trans_def); } diff --git a/pandatool/src/pandatoolbase/pathReplace.I b/pandatool/src/pandatoolbase/pathReplace.I index 0542f8b55f..13fb89221d 100755 --- a/pandatool/src/pandatoolbase/pathReplace.I +++ b/pandatool/src/pandatoolbase/pathReplace.I @@ -119,7 +119,9 @@ is_empty() const { //////////////////////////////////////////////////////////////////// INLINE Filename PathReplace:: convert_path(const Filename &orig_filename, const DSearchPath &additional_path) { - return store_path(match_path(orig_filename, additional_path)); + Filename fullpath, outpath; + full_convert_path(orig_filename, additional_path, fullpath, outpath); + return outpath; } //////////////////////////////////////////////////////////////////// diff --git a/pandatool/src/pandatoolbase/pathReplace.cxx b/pandatool/src/pandatoolbase/pathReplace.cxx index a16b677366..d7ee7c3a50 100755 --- a/pandatool/src/pandatoolbase/pathReplace.cxx +++ b/pandatool/src/pandatoolbase/pathReplace.cxx @@ -201,6 +201,168 @@ store_path(const Filename &orig_filename) { return filename; } +//////////////////////////////////////////////////////////////////// +// Function: PathReplace::full_convert_path +// Access: Public +// Description: Converts the input path into two different forms: +// A resolved path, and an output path. The resolved +// path is an absolute path if at all possible. The +// output path is in the form specified by the -ps +// path store option. +//////////////////////////////////////////////////////////////////// +void PathReplace:: +full_convert_path(const Filename &orig_filename, + const DSearchPath &additional_path, + Filename &resolved_path, + Filename &output_path) { + Filename match; + bool got_match = false; + + VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr(); + + Entries::const_iterator ei; + for (ei = _entries.begin(); ei != _entries.end(); ++ei) { + const Entry &entry = (*ei); + Filename new_filename; + if (entry.try_match(orig_filename, new_filename)) { + // The prefix matches. Save the resulting filename for + // posterity. + got_match = true; + match = new_filename; + + if (new_filename.is_fully_qualified()) { + // If the resulting filename is fully qualified, it's a match + // if and only if it exists. + if (vfs->exists(new_filename)) { + resolved_path = new_filename; + goto calculate_output_path; + } + + } else { + // Otherwise, if it's a relative filename, attempt to look it + // up on the search path. + if (vfs->resolve_filename(new_filename, _path) || + vfs->resolve_filename(new_filename, additional_path) || + vfs->resolve_filename(new_filename, get_model_path())) { + // Found it! + resolved_path = new_filename; + goto calculate_output_path; + } + } + + // The prefix matched, but it didn't exist. Keep looking. + } + } + + // The file couldn't be found anywhere. Did we at least get any + // prefix match? + if (got_match) { + if (_exists) { + _error_flag = true; + pandatoolbase_cat.error() + << "File does not exist: " << match << "\n"; + } else if (pandatoolbase_cat.is_debug()) { + pandatoolbase_cat.debug() + << "File does not exist: " << match << "\n"; + } + + resolved_path = match; + goto calculate_output_path; + } + + if (!orig_filename.is_local()) { + // Ok, we didn't match any specified prefixes. If the file is an + // absolute pathname and we have _noabs set, that's an error. + if (_noabs) { + _error_flag = true; + pandatoolbase_cat.error() + << "Absolute pathname: " << orig_filename << "\n"; + } else if (pandatoolbase_cat.is_debug()) { + pandatoolbase_cat.debug() + << "Absolute pathname: " << orig_filename << "\n"; + } + } + + // Well, we still haven't found it; look it up on the search path as + // is. + { + Filename new_filename = orig_filename; + if (vfs->resolve_filename(new_filename, _path) || + vfs->resolve_filename(new_filename, additional_path) || + vfs->resolve_filename(new_filename, get_model_path())) { + // Found it! + match = orig_filename; + resolved_path = new_filename; + goto calculate_output_path; + } + } + + // Nope, couldn't find anything. This is an error, but just return + // the original filename. + if (_exists) { + _error_flag = true; + pandatoolbase_cat.error() + << "File does not exist: " << orig_filename << "\n"; + } else if (pandatoolbase_cat.is_debug()) { + pandatoolbase_cat.debug() + << "File does not exist: " << orig_filename << "\n"; + } + match = orig_filename; + resolved_path = orig_filename; + + // To calculate the output path, we need two inputs: + // the match, and the resolved path. Which one is used + // depends upon the path-store mode. + calculate_output_path: + + switch (_path_store) { + case PS_relative: + if (resolved_path.empty()) + output_path = resolved_path; + else { + if (_path_directory.is_local()) + _path_directory.make_absolute(); + output_path = resolved_path; + output_path.make_absolute(); + output_path.make_relative_to(_path_directory); + } + break; + + case PS_absolute: + if (resolved_path.empty()) + output_path = resolved_path; + else { + output_path = resolved_path; + output_path.make_absolute(); + } + break; + + case PS_rel_abs: + if (resolved_path.empty()) + output_path = resolved_path; + else { + if (_path_directory.is_local()) + _path_directory.make_absolute(); + output_path = resolved_path; + output_path.make_absolute(); + output_path.make_relative_to(_path_directory, false); + } + break; + + case PS_strip: + output_path = match.get_basename(); + break; + + case PS_keep: + output_path = match; + break; + + case PS_invalid: + output_path = ""; + break; + } +} + //////////////////////////////////////////////////////////////////// // Function: PathReplace::write // Access: Public diff --git a/pandatool/src/pandatoolbase/pathReplace.h b/pandatool/src/pandatoolbase/pathReplace.h index e5fbdc47fd..111ef6019a 100755 --- a/pandatool/src/pandatoolbase/pathReplace.h +++ b/pandatool/src/pandatoolbase/pathReplace.h @@ -63,6 +63,11 @@ public: INLINE Filename convert_path(const Filename &orig_filename, const DSearchPath &additional_path = DSearchPath()); + + void full_convert_path(const Filename &orig_filename, + const DSearchPath &additional_path, + Filename &resolved_path, + Filename &output_path); void write(ostream &out, int indent_level = 0) const;