From dc31e2438870730a6b6f7d540301333bf7f4d9de Mon Sep 17 00:00:00 2001 From: Michael Kowalski Date: Tue, 28 Dec 2021 21:55:38 -0500 Subject: USD material import format fixes. --- source/blender/io/usd/intern/usd_reader_mesh.cc | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc index 98d21c6138e..45972471473 100644 --- a/source/blender/io/usd/intern/usd_reader_mesh.cc +++ b/source/blender/io/usd/intern/usd_reader_mesh.cc @@ -92,15 +92,16 @@ static pxr::UsdShadeMaterial compute_bound_material(const pxr::UsdPrim &prim) /* Returns an existing Blender material that corresponds to the USD * material with with the given path. Returns null if no such material * exists. */ -static Material *find_existing_material(const pxr::SdfPath &usd_mat_path, - const USDImportParams ¶ms, - const std::map &mat_map, - const std::map &usd_path_to_mat_name) +static Material *find_existing_material( + const pxr::SdfPath &usd_mat_path, + const USDImportParams ¶ms, + const std::map &mat_map, + const std::map &usd_path_to_mat_name) { if (params.mtl_name_collision_mode == USD_MTL_NAME_COLLISION_UNIQUE_NAME) { /* Check if we've already created the Blender material with a modified name. */ std::map::const_iterator path_to_name_iter = - usd_path_to_mat_name.find(usd_mat_path.GetAsString()); + usd_path_to_mat_name.find(usd_mat_path.GetAsString()); if (path_to_name_iter != usd_path_to_mat_name.end()) { std::string mat_name = path_to_name_iter->second; @@ -110,8 +111,8 @@ static Material *find_existing_material(const pxr::SdfPath &usd_mat_path, } else { std::cout - << "WARNING: Couldn't find previously assigned Blender material for USD material " - << usd_mat_path << std::endl; + << "WARNING: Couldn't find previously assigned Blender material for USD material " + << usd_mat_path << std::endl; } } } @@ -156,10 +157,8 @@ static void assign_materials(Main *bmain, for (it = mat_index_map.begin(); it != mat_index_map.end(); ++it) { - Material *assigned_mat = find_existing_material(it->first, - params, - mat_map, - usd_path_to_mat_name); + Material *assigned_mat = find_existing_material( + it->first, params, mat_map, usd_path_to_mat_name); if (!assigned_mat) { /* Blender material doesn't exist, so create it now. */ -- cgit v1.2.3 From 95d6c29fbf46c4dfa4cdcc2cbdcc24fa07b11e9c Mon Sep 17 00:00:00 2001 From: Michael Kowalski Date: Wed, 5 Jan 2022 19:30:19 -0500 Subject: USD import: use new UDIM virtual filepath API. Applied Jesse Yurkovich's patch to update the UDIM tile loading code to conform to the new virtual filepath specification requirements. --- .../blender/io/usd/intern/usd_reader_material.cc | 95 +++++----------------- 1 file changed, 21 insertions(+), 74 deletions(-) diff --git a/source/blender/io/usd/intern/usd_reader_material.cc b/source/blender/io/usd/intern/usd_reader_material.cc index 38a1614a96d..6f0134b17d4 100644 --- a/source/blender/io/usd/intern/usd_reader_material.cc +++ b/source/blender/io/usd/intern/usd_reader_material.cc @@ -41,10 +41,6 @@ #include #include -/* The result of querying UDIM information for a texture, - * the path to the first tile and a list of tile indices. */ -typedef std::pair> UDIMQueryResult; - namespace usdtokens { /* Parameter names. */ @@ -137,83 +133,38 @@ static bool is_udim_path(const std::string &path) return path.find("") != std::string::npos; } -/* For the given UDIM path (assumed to contain the UDIM token), examine files - * on disk to determine the indices of the UDIM tiles that are available - * to load. Returns a pair representing the path to the file corresponding - * to the lowest tile index and an array containing valid tile indices. +/* For the given UDIM path (assumed to contain the UDIM token), returns an array + * containing valid tile indices. * Returns std::nullopt if no tiles were found. */ -static std::optional get_udim_tiles(const std::string &file_path) +static std::optional> get_udim_tiles(const std::string &file_path) { /* Check if we have a UDIM path. */ std::size_t udim_token_offset = file_path.find(""); - BLI_assert(udim_token_offset != std::string::npos); - /* Create a dummy UDIM path by replacing the '' token - * with an arbitrary index, since this is the format expected - * as input to the call BLI_path_sequence_decode(). We use the - * index 1001, but this will be replaced by the actual index - * of the first tile found on disk. */ - std::string base_udim_path(file_path); - base_udim_path.replace(udim_token_offset, 6, "1001"); - - /* Extract the file and directory names from the path. */ - char filename[FILE_MAX], dirname[FILE_MAXDIR]; - BLI_split_dirfile(base_udim_path.c_str(), dirname, filename, sizeof(dirname), sizeof(filename)); - - /* Split the base and head portions of the file name. */ - ushort digits = 0; - char base_head[FILE_MAX], base_tail[FILE_MAX]; - BLI_path_sequence_decode(filename, base_head, base_tail, &digits); - - /* Iterate over the directory contents to find files - * with matching names and with the expected index format - * for UDIMS. */ - struct direntry *dir = nullptr; - uint totfile = BLI_filelist_dir_contents(dirname, &dir); - - if (!dir) { - return std::nullopt; - } - - /* Keep track of the lowest tile index. */ - int min_id = IMA_UDIM_MAX; - std::pair> result; - - for (int i = 0; i < totfile; ++i) { - if (!(dir[i].type & S_IFREG)) { - continue; - } - - char head[FILE_MAX], tail[FILE_MAX]; - int id = BLI_path_sequence_decode(dir[i].relname, head, tail, &digits); - - if (digits == 0 || digits > 4 || !(STREQLEN(base_head, head, FILE_MAX)) || - !(STREQLEN(base_tail, tail, FILE_MAX))) { - continue; - } + char base_udim_path[FILE_MAX]; + BLI_strncpy(base_udim_path, file_path.c_str(), sizeof(base_udim_path)); - if (id < 1001 || id >= IMA_UDIM_MAX) { - continue; - } + blender::Vector udim_tiles; - if (id < min_id) { - min_id = id; + /* Extract the tile numbers from all files on disk. */ + ListBase tiles = {nullptr, nullptr}; + int tile_start, tile_range; + bool result = BKE_image_get_tile_info(base_udim_path, &tiles, &tile_start, &tile_range); + if (result) { + LISTBASE_FOREACH (LinkData *, tile, &tiles) { + int tile_number = POINTER_AS_INT(tile->data); + udim_tiles.append(tile_number); } - result.second.append(id); } - BLI_filelist_free(dir, totfile); + BLI_freelistN(&tiles); - if (result.second.is_empty()) { + if (udim_tiles.is_empty()) { return std::nullopt; } - /* Finally, use the lowest index we found to create the first tile path. */ - result.first = file_path; - result.first.replace(udim_token_offset, 6, std::to_string(min_id)); - - return result; + return udim_tiles; } /* Add tiles with the given indices to the given image. */ @@ -746,14 +697,10 @@ void USDMaterialReader::load_tex_image(const pxr::UsdShadeShader &usd_shader, /* If this is a UDIM texture, this will store the * UDIM tile indices. */ - std::optional udim_result; + std::optional> udim_tiles; if (is_udim_path(file_path)) { - udim_result = get_udim_tiles(file_path); - - if (udim_result) { - file_path = udim_result->first; - } + udim_tiles = get_udim_tiles(file_path); } if (file_path.empty()) { @@ -770,8 +717,8 @@ void USDMaterialReader::load_tex_image(const pxr::UsdShadeShader &usd_shader, return; } - if (udim_result) { - add_udim_tiles(image, udim_result->second); + if (udim_tiles) { + add_udim_tiles(image, udim_tiles.value()); } tex_image->id = &image->id; -- cgit v1.2.3