Mesh: Replace auto smooth with node group #108014

Merged
Hans Goudey merged 149 commits from HooglyBoogly/blender:refactor-mesh-corner-normals-lazy into main 2023-10-20 16:54:20 +02:00
3 changed files with 95 additions and 47 deletions
Showing only changes of commit 8807f27bf5 - Show all commits

View File

@ -218,9 +218,10 @@ void AssetList::ensurePreviewsJob(const bContext *C)
int numfiles = filelist_files_ensure(files);
filelist_cache_previews_set(files, true);
filelist_file_cache_slidingwindow_set(files, 128);
/* TODO fetch all previews for now. */
filelist_file_cache_block(files, numfiles / 2);
/* Add one extra entry to ensure nothing is lost because of integer division. */
filelist_file_cache_slidingwindow_set(files, numfiles / 2 + 1);
filelist_file_cache_block(files, 0);
filelist_cache_previews_update(files);
{

View File

@ -84,6 +84,29 @@ static const char *temp_textures_dir()
return temp_dir;
}
using blender::io::usd::ShaderToNodeMap;
/* Returns the Blender node previously cached for
* the given USD shader in the given map. Returns
* null if no cached shader was found. */
static bNode *get_cached_node(const ShaderToNodeMap &node_cache,
const pxr::UsdShadeShader &usd_shader)
{
if (bNode *const *node_ptr = node_cache.lookup_ptr(usd_shader.GetPath().GetAsString())) {
return *node_ptr;
}
return nullptr;
}
/* Cache the Blender node translated from the given USD shader
* in the given map. */
static void cache_node(ShaderToNodeMap &node_cache,
const pxr::UsdShadeShader &usd_shader,
bNode *node)
{
node_cache.add(usd_shader.GetPath().GetAsString(), node);
}
/* Add a node of the given type at the given location coordinates. */
static bNode *add_node(
const bContext *C, bNodeTree *ntree, const int type, const float locx, const float locy)
@ -627,22 +650,29 @@ void USDMaterialReader::convert_usd_uv_texture(const pxr::UsdShadeShader &usd_sh
return;
}
float locx = 0.0f;
float locy = 0.0f;
compute_node_loc(column, &locx, &locy, r_ctx);
bNode *tex_image = get_cached_node(r_ctx->node_cache, usd_shader);
/* Create the Texture Image node. */
bNode *tex_image = add_node(nullptr, ntree, SH_NODE_TEX_IMAGE, locx, locy);
if (tex_image == nullptr) {
float locx = 0.0f;
float locy = 0.0f;
compute_node_loc(column, &locx, &locy, r_ctx);
if (!tex_image) {
std::cerr << "ERROR: Couldn't create SH_NODE_TEX_IMAGE for node input " << dest_socket_name
<< std::endl;
return;
/* Create the Texture Image node. */
tex_image = add_node(nullptr, ntree, SH_NODE_TEX_IMAGE, locx, locy);
if (!tex_image) {
std::cerr << "ERROR: Couldn't create SH_NODE_TEX_IMAGE for node input " << dest_socket_name
<< std::endl;
return;
}
/* Cache newly created node. */
cache_node(r_ctx->node_cache, usd_shader, tex_image);
/* Load the texture image. */
load_tex_image(usd_shader, tex_image);
}
/* Load the texture image. */
load_tex_image(usd_shader, tex_image);
/* Connect to destination node input. */
/* Get the source socket name. */
@ -779,45 +809,52 @@ void USDMaterialReader::convert_usd_primvar_reader_float2(
return;
}
float locx = 0.0f;
float locy = 0.0f;
compute_node_loc(column, &locx, &locy, r_ctx);
bNode *uv_map = get_cached_node(r_ctx->node_cache, usd_shader);
/* Create the UV Map node. */
bNode *uv_map = add_node(nullptr, ntree, SH_NODE_UVMAP, locx, locy);
if (uv_map == nullptr) {
float locx = 0.0f;
float locy = 0.0f;
compute_node_loc(column, &locx, &locy, r_ctx);
if (!uv_map) {
std::cerr << "ERROR: Couldn't create SH_NODE_UVMAP for node input " << dest_socket_name
<< std::endl;
return;
}
/* Create the UV Map node. */
uv_map = add_node(nullptr, ntree, SH_NODE_UVMAP, locx, locy);
/* Set the texmap name. */
pxr::UsdShadeInput varname_input = usd_shader.GetInput(usdtokens::varname);
if (!uv_map) {
std::cerr << "ERROR: Couldn't create SH_NODE_UVMAP for node input " << dest_socket_name
<< std::endl;
return;
}
/* First check if the shader's "varname" input is connected to another source,
* and use that instead if so. */
if (varname_input) {
for (const pxr::UsdShadeConnectionSourceInfo &source_info :
varname_input.GetConnectedSources()) {
pxr::UsdShadeShader shader = pxr::UsdShadeShader(source_info.source.GetPrim());
pxr::UsdShadeInput secondary_varname_input = shader.GetInput(source_info.sourceName);
if (secondary_varname_input) {
varname_input = secondary_varname_input;
break;
/* Cache newly created node. */
cache_node(r_ctx->node_cache, usd_shader, uv_map);
/* Set the texmap name. */
pxr::UsdShadeInput varname_input = usd_shader.GetInput(usdtokens::varname);
/* First check if the shader's "varname" input is connected to another source,
* and use that instead if so. */
if (varname_input) {
for (const pxr::UsdShadeConnectionSourceInfo &source_info :
varname_input.GetConnectedSources()) {
pxr::UsdShadeShader shader = pxr::UsdShadeShader(source_info.source.GetPrim());
pxr::UsdShadeInput secondary_varname_input = shader.GetInput(source_info.sourceName);
if (secondary_varname_input) {
varname_input = secondary_varname_input;
break;
}
}
}
}
if (varname_input) {
pxr::VtValue varname_val;
/* The varname input may be a string or TfToken, so just cast it to a string.
* The Cast function is defined to provide an empty result if it fails. */
if (varname_input.Get(&varname_val) && varname_val.CanCastToTypeid(typeid(std::string))) {
std::string varname = varname_val.Cast<std::string>().Get<std::string>();
if (!varname.empty()) {
NodeShaderUVMap *storage = (NodeShaderUVMap *)uv_map->storage;
BLI_strncpy(storage->uv_map, varname.c_str(), sizeof(storage->uv_map));
if (varname_input) {
pxr::VtValue varname_val;
/* The varname input may be a string or TfToken, so just cast it to a string.
* The Cast function is defined to provide an empty result if it fails. */
if (varname_input.Get(&varname_val) && varname_val.CanCastToTypeid(typeid(std::string))) {
std::string varname = varname_val.Cast<std::string>().Get<std::string>();
if (!varname.empty()) {
NodeShaderUVMap *storage = (NodeShaderUVMap *)uv_map->storage;
BLI_strncpy(storage->uv_map, varname.c_str(), sizeof(storage->uv_map));
}
}
}
}

View File

@ -4,9 +4,11 @@
#include "usd.h"
#include "BLI_map.hh"
#include <pxr/usd/usdShade/material.h>
#include <map>
#include <string>
struct Main;
struct Material;
@ -15,6 +17,8 @@ struct bNodeTree;
namespace blender::io::usd {
using ShaderToNodeMap = blender::Map<std::string, bNode *>;
/* Helper struct used when arranging nodes in columns, keeping track the
* occupancy information for a given column. I.e., for column n,
* column_offsets[n] is the y-offset (from top to bottom) of the occupied
@ -26,6 +30,12 @@ struct NodePlacementContext {
const float horizontal_step;
const float vertical_step;
/* Map a USD shader prim path to the Blender node converted
* from that shader. This map is updated during shader
* conversion and is used to avoid creating duplicate nodes
* for a given shader. */
ShaderToNodeMap node_cache;
NodePlacementContext(float in_origx,
float in_origy,
float in_horizontal_step = 300.0f,