From e2be6bc03fbab9783f117de95d560fbc09442de2 Mon Sep 17 00:00:00 2001 From: Aras Pranckevicius Date: Mon, 1 Aug 2022 13:39:08 +0300 Subject: Fix T100076: OBJ import: new importer doesn't use //relative/image/paths The Python based importer had logic to immediately turn image paths into relative-to-blender-file paths, if user preference for relative paths is used (which is on by default). The new importer code did not have that. Fixes T100076. --- .../io/wavefront_obj/importer/obj_import_mesh.cc | 13 +++++---- .../io/wavefront_obj/importer/obj_import_mesh.hh | 3 +- .../io/wavefront_obj/importer/obj_import_mtl.cc | 32 +++++++++++++++------- .../io/wavefront_obj/importer/obj_import_mtl.hh | 4 +-- 4 files changed, 34 insertions(+), 18 deletions(-) (limited to 'source/blender/io/wavefront_obj/importer') diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc index 01f05466b3a..6f66ce5a6bd 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc @@ -57,7 +57,7 @@ Object *MeshFromGeometry::create_mesh(Main *bmain, create_uv_verts(mesh); create_normals(mesh); create_colors(mesh); - create_materials(bmain, materials, created_materials, obj); + create_materials(bmain, materials, created_materials, obj, import_params.relative_paths); if (import_params.validate_meshes || mesh_geometry_.has_invalid_polys_) { bool verbose_validate = false; @@ -277,7 +277,8 @@ void MeshFromGeometry::create_uv_verts(Mesh *mesh) static Material *get_or_create_material(Main *bmain, const std::string &name, Map> &materials, - Map &created_materials) + Map &created_materials, + bool relative_paths) { /* Have we created this material already? */ Material **found_mat = created_materials.lookup_ptr(name); @@ -291,7 +292,7 @@ static Material *get_or_create_material(Main *bmain, const MTLMaterial &mtl = *materials.lookup_or_add(name, std::make_unique()); Material *mat = BKE_material_add(bmain, name.c_str()); - ShaderNodetreeWrap mat_wrap{bmain, mtl, mat}; + ShaderNodetreeWrap mat_wrap{bmain, mtl, mat, relative_paths}; mat->use_nodes = true; mat->nodetree = mat_wrap.get_nodetree(); BKE_ntree_update_main_tree(bmain, mat->nodetree, nullptr); @@ -303,10 +304,12 @@ static Material *get_or_create_material(Main *bmain, void MeshFromGeometry::create_materials(Main *bmain, Map> &materials, Map &created_materials, - Object *obj) + Object *obj, + bool relative_paths) { for (const std::string &name : mesh_geometry_.material_order_) { - Material *mat = get_or_create_material(bmain, name, materials, created_materials); + Material *mat = get_or_create_material( + bmain, name, materials, created_materials, relative_paths); if (mat == nullptr) { continue; } diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mesh.hh b/source/blender/io/wavefront_obj/importer/obj_import_mesh.hh index 591a7b81e63..cdc88528f1e 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.hh +++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.hh @@ -62,7 +62,8 @@ class MeshFromGeometry : NonMovable, NonCopyable { void create_materials(Main *bmain, Map> &materials, Map &created_materials, - Object *obj); + Object *obj, + bool relative_paths); void create_normals(Mesh *mesh); void create_colors(Mesh *mesh); void create_vertex_groups(Object *obj); diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc b/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc index f7685ba0b7b..099929b0e67 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc @@ -5,10 +5,12 @@ */ #include "BKE_image.h" +#include "BKE_main.h" #include "BKE_node.h" #include "BLI_map.hh" #include "BLI_math_vector.h" +#include "BLI_path_util.h" #include "DNA_material_types.h" #include "DNA_node_types.h" @@ -63,7 +65,8 @@ static void set_property_of_socket(eNodeSocketDatatype property_type, static bool load_texture_image_at_path(Main *bmain, const tex_map_XX &tex_map, bNode *r_node, - const std::string &path) + const std::string &path, + bool relative_paths) { Image *tex_image = BKE_image_load_exists(bmain, path.c_str()); if (!tex_image) { @@ -71,6 +74,9 @@ static bool load_texture_image_at_path(Main *bmain, return false; } fprintf(stderr, "Loaded image from: '%s'\n", path.c_str()); + if (relative_paths) { + BLI_path_rel(tex_image->filepath, BKE_main_blendfile_path(bmain)); + } r_node->id = reinterpret_cast(tex_image); NodeTexImage *image = static_cast(r_node->storage); image->projection = tex_map.projection_type; @@ -81,18 +87,21 @@ static bool load_texture_image_at_path(Main *bmain, * Load image for Image Texture node and set the node properties. * Return success if Image can be loaded successfully. */ -static bool load_texture_image(Main *bmain, const tex_map_XX &tex_map, bNode *r_node) +static bool load_texture_image(Main *bmain, + const tex_map_XX &tex_map, + bNode *r_node, + bool relative_paths) { BLI_assert(r_node && r_node->type == SH_NODE_TEX_IMAGE); /* First try treating texture path as relative. */ std::string tex_path{tex_map.mtl_dir_path + tex_map.image_path}; - if (load_texture_image_at_path(bmain, tex_map, r_node, tex_path)) { + if (load_texture_image_at_path(bmain, tex_map, r_node, tex_path, relative_paths)) { return true; } /* Then try using it directly as absolute path. */ std::string raw_path{tex_map.image_path}; - if (load_texture_image_at_path(bmain, tex_map, r_node, raw_path)) { + if (load_texture_image_at_path(bmain, tex_map, r_node, raw_path, relative_paths)) { return true; } /* Try removing quotes. */ @@ -100,21 +109,24 @@ static bool load_texture_image(Main *bmain, const tex_map_XX &tex_map, bNode *r_ auto end_pos = std::remove(no_quote_path.begin(), no_quote_path.end(), '"'); no_quote_path.erase(end_pos, no_quote_path.end()); if (no_quote_path != tex_path && - load_texture_image_at_path(bmain, tex_map, r_node, no_quote_path)) { + load_texture_image_at_path(bmain, tex_map, r_node, no_quote_path, relative_paths)) { return true; } /* Try replacing underscores with spaces. */ std::string no_underscore_path{no_quote_path}; std::replace(no_underscore_path.begin(), no_underscore_path.end(), '_', ' '); if (no_underscore_path != no_quote_path && no_underscore_path != tex_path && - load_texture_image_at_path(bmain, tex_map, r_node, no_underscore_path)) { + load_texture_image_at_path(bmain, tex_map, r_node, no_underscore_path, relative_paths)) { return true; } return false; } -ShaderNodetreeWrap::ShaderNodetreeWrap(Main *bmain, const MTLMaterial &mtl_mat, Material *mat) +ShaderNodetreeWrap::ShaderNodetreeWrap(Main *bmain, + const MTLMaterial &mtl_mat, + Material *mat, + bool relative_paths) : mtl_mat_(mtl_mat) { nodetree_.reset(ntreeAddTree(nullptr, "Shader Nodetree", ntreeType_Shader->idname)); @@ -122,7 +134,7 @@ ShaderNodetreeWrap::ShaderNodetreeWrap(Main *bmain, const MTLMaterial &mtl_mat, shader_output_ = add_node_to_tree(SH_NODE_OUTPUT_MATERIAL); set_bsdf_socket_values(mat); - add_image_textures(bmain, mat); + add_image_textures(bmain, mat, relative_paths); link_sockets(bsdf_, "BSDF", shader_output_, "Surface", 4); nodeSetActive(nodetree_.get(), shader_output_); @@ -325,7 +337,7 @@ void ShaderNodetreeWrap::set_bsdf_socket_values(Material *mat) } } -void ShaderNodetreeWrap::add_image_textures(Main *bmain, Material *mat) +void ShaderNodetreeWrap::add_image_textures(Main *bmain, Material *mat, bool relative_paths) { for (const Map::Item texture_map : mtl_mat_.texture_maps.items()) { @@ -335,7 +347,7 @@ void ShaderNodetreeWrap::add_image_textures(Main *bmain, Material *mat) } bNode *image_texture = add_node_to_tree(SH_NODE_TEX_IMAGE); - if (!load_texture_image(bmain, texture_map.value, image_texture)) { + if (!load_texture_image(bmain, texture_map.value, image_texture, relative_paths)) { /* Image could not be added, so don't add or link further nodes. */ continue; } diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mtl.hh b/source/blender/io/wavefront_obj/importer/obj_import_mtl.hh index 12bea1cdc5a..17dd0106fea 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_mtl.hh +++ b/source/blender/io/wavefront_obj/importer/obj_import_mtl.hh @@ -49,7 +49,7 @@ class ShaderNodetreeWrap { * Initializes a nodetree with a p-BSDF node's BSDF socket connected to shader output node's * surface socket. */ - ShaderNodetreeWrap(Main *bmain, const MTLMaterial &mtl_mat, Material *mat); + ShaderNodetreeWrap(Main *bmain, const MTLMaterial &mtl_mat, Material *mat, bool relative_paths); ~ShaderNodetreeWrap(); /** @@ -87,7 +87,7 @@ class ShaderNodetreeWrap { * Create image texture, vector and normal mapping nodes from MTL materials and link the * nodes to p-BSDF node. */ - void add_image_textures(Main *bmain, Material *mat); + void add_image_textures(Main *bmain, Material *mat, bool relative_paths); }; } // namespace blender::io::obj -- cgit v1.2.3