diff options
author | Aras Pranckevicius <aras@nesnausk.org> | 2022-05-10 11:34:42 +0300 |
---|---|---|
committer | Aras Pranckevicius <aras@nesnausk.org> | 2022-05-10 18:58:10 +0300 |
commit | 3bc037a7eb8d214aac9d755f8b2dd0e04cdf3a85 (patch) | |
tree | 050b1f21550517efd900e13a12a82b6b5d7cfd42 /source/blender/io/wavefront_obj/exporter | |
parent | 1dd177241908906254527052beb01aa52745b6a8 (diff) |
Fix T96399: New 3.1 OBJ exporter is missing Path Mode setting
New OBJ exporter is missing "Path Mode" setting for exporting .mtl
files. The options that used to be available were: Auto, Absolute,
Relative, Match, Strip Path, Copy. All of them are important. The new
behavior (without any UI option to control it) curiously does not match
any of the previous setting. New behavior is like "Relative, but to the
source blender file, and not the destination export file".
Most of the previous logic was only present in Python based code
(bpy_extras.io_utils.path_reference and friends). The bulk of this
commit is porting that to C++.
Reviewed By: Howard Trickey
Differential Revision: https://developer.blender.org/D14906
Diffstat (limited to 'source/blender/io/wavefront_obj/exporter')
4 files changed, 47 insertions, 15 deletions
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc index 194583e71fe..b027df73b1e 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc @@ -13,6 +13,8 @@ #include "BLI_path_util.h" #include "BLI_task.hh" +#include "IO_path_util.hh" + #include "obj_export_mesh.hh" #include "obj_export_mtl.hh" #include "obj_export_nurbs.hh" @@ -530,7 +532,11 @@ void MTLWriter::write_bsdf_properties(const MTLMaterial &mtl_material) void MTLWriter::write_texture_map( const MTLMaterial &mtl_material, - const Map<const eMTLSyntaxElement, tex_map_XX>::Item &texture_map) + const Map<const eMTLSyntaxElement, tex_map_XX>::Item &texture_map, + const char *blen_filedir, + const char *dest_dir, + ePathReferenceMode path_mode, + Set<std::pair<std::string, std::string>> ©_set) { std::string options; /* Option strings should have their own leading spaces. */ @@ -546,7 +552,11 @@ void MTLWriter::write_texture_map( #define SYNTAX_DISPATCH(eMTLSyntaxElement) \ if (texture_map.key == eMTLSyntaxElement) { \ - fmt_handler_.write<eMTLSyntaxElement>(options, texture_map.value.image_path); \ + std::string path = path_reference( \ + texture_map.value.image_path.c_str(), blen_filedir, dest_dir, path_mode, ©_set); \ + /* Always emit forward slashes for cross-platform compatibility. */ \ + std::replace(path.begin(), path.end(), '\\', '/'); \ + fmt_handler_.write<eMTLSyntaxElement>(options, path.c_str()); \ return; \ } @@ -561,25 +571,35 @@ void MTLWriter::write_texture_map( BLI_assert(!"This map type was not written to the file."); } -void MTLWriter::write_materials() +void MTLWriter::write_materials(const char *blen_filepath, + ePathReferenceMode path_mode, + const char *dest_dir) { if (mtlmaterials_.size() == 0) { return; } + + char blen_filedir[PATH_MAX]; + BLI_split_dir_part(blen_filepath, blen_filedir, PATH_MAX); + BLI_path_slash_native(blen_filedir); + BLI_path_normalize(nullptr, blen_filedir); + std::sort(mtlmaterials_.begin(), mtlmaterials_.end(), [](const MTLMaterial &a, const MTLMaterial &b) { return a.name < b.name; }); + Set<std::pair<std::string, std::string>> copy_set; for (const MTLMaterial &mtlmat : mtlmaterials_) { fmt_handler_.write<eMTLSyntaxElement::string>("\n"); fmt_handler_.write<eMTLSyntaxElement::newmtl>(mtlmat.name); write_bsdf_properties(mtlmat); - for (const Map<const eMTLSyntaxElement, tex_map_XX>::Item &texture_map : - mtlmat.texture_maps.items()) { - if (!texture_map.value.image_path.empty()) { - write_texture_map(mtlmat, texture_map); + for (const auto &tex : mtlmat.texture_maps.items()) { + if (tex.value.image_path.empty()) { + continue; } + write_texture_map(mtlmat, tex, blen_filedir, dest_dir, path_mode, copy_set); } } + path_reference_copy(copy_set); } Vector<int> MTLWriter::add_materials(const OBJMesh &mesh_to_export) diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh index 96f7d434338..77da7b44276 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh @@ -9,6 +9,7 @@ #include "DNA_meshdata_types.h" #include "BLI_map.hh" +#include "BLI_set.hh" #include "BLI_vector.hh" #include "IO_wavefront_obj.h" @@ -181,7 +182,9 @@ class MTLWriter : NonMovable, NonCopyable { * For consistency of output from run to run (useful for testing), * the materials are sorted by name before writing. */ - void write_materials(); + void write_materials(const char *blen_filepath, + ePathReferenceMode path_mode, + const char *dest_dir); StringRefNull mtl_file_path() const; /** * Add the materials of the given object to #MTLWriter, de-duplicating @@ -203,6 +206,10 @@ class MTLWriter : NonMovable, NonCopyable { * Write a texture map in the form "map_XX -s 1. 1. 1. -o 0. 0. 0. [-bm 1.] path/to/image". */ void write_texture_map(const MTLMaterial &mtl_material, - const Map<const eMTLSyntaxElement, tex_map_XX>::Item &texture_map); + const Map<const eMTLSyntaxElement, tex_map_XX>::Item &texture_map, + const char *blen_filedir, + const char *dest_dir, + ePathReferenceMode mode, + Set<std::pair<std::string, std::string>> ©_set); }; } // namespace blender::io::obj diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc index c48d5a5f7f0..4ed148ec64e 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc @@ -113,8 +113,7 @@ static const bNode *get_node_of_type(Span<const nodes::OutputSocketRef *> socket /** * From a texture image shader node, get the image's filepath. - * Returned filepath is stripped of initial "//". If packed image is found, - * only the file "name" is returned. + * If packed image is found, only the file "name" is returned. */ static const char *get_image_filepath(const bNode *tex_node) { @@ -134,9 +133,6 @@ static const char *get_image_filepath(const bNode *tex_node) "directory as the .MTL file.\n", path); } - if (path[0] == '/' && path[1] == '/') { - path += 2; - } return path; } diff --git a/source/blender/io/wavefront_obj/exporter/obj_exporter.cc b/source/blender/io/wavefront_obj/exporter/obj_exporter.cc index 78b709c884a..b6e636b389d 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_exporter.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_exporter.cc @@ -284,7 +284,16 @@ void export_frame(Depsgraph *depsgraph, const OBJExportParams &export_params, co std::move(exportable_as_mesh), *frame_writer, mtl_writer.get(), export_params); if (mtl_writer) { mtl_writer->write_header(export_params.blen_filepath); - mtl_writer->write_materials(); + char dest_dir[PATH_MAX]; + if (export_params.file_base_for_tests[0] == '\0') { + BLI_split_dir_part(export_params.filepath, dest_dir, PATH_MAX); + } + else { + BLI_strncpy(dest_dir, export_params.file_base_for_tests, PATH_MAX); + } + BLI_path_slash_native(dest_dir); + BLI_path_normalize(nullptr, dest_dir); + mtl_writer->write_materials(export_params.blen_filepath, export_params.path_mode, dest_dir); } write_nurbs_curve_objects(std::move(exportable_as_nurbs), *frame_writer); } |