mirror of
https://github.com/blender/blender
synced 2026-09-26 16:15:47 +03:00
Merge branch 'blender-v4.1-release'
This commit is contained in:
commit
5001a1a4a7
3 changed files with 146 additions and 17 deletions
|
|
@ -1495,6 +1495,7 @@ void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *re
|
|||
|
||||
if ((lapp_context->params->flag & FILE_LINK) != 0) {
|
||||
blendfile_link_append_proxies_convert(lapp_context->params->bmain, reports);
|
||||
BKE_main_mesh_legacy_convert_auto_smooth(*lapp_context->params->bmain);
|
||||
}
|
||||
|
||||
BKE_main_namemap_clear(lapp_context->params->bmain);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "BKE_customdata.hh"
|
||||
#include "BKE_global.hh"
|
||||
#include "BKE_idprop.hh"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_mesh_legacy_convert.hh"
|
||||
|
|
@ -2233,17 +2234,105 @@ static bNodeTree *add_auto_smooth_node_tree(Main &bmain)
|
|||
nodeSetSelected(node, false);
|
||||
}
|
||||
|
||||
BKE_ntree_update_main_tree(&bmain, group, nullptr);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
static ModifierData *create_auto_smooth_modifier(Object &object,
|
||||
const FunctionRef<bNodeTree *()> get_node_group,
|
||||
const float angle)
|
||||
static VectorSet<const bNodeSocket *> build_socket_indices(const Span<const bNode *> nodes)
|
||||
{
|
||||
VectorSet<const bNodeSocket *> result;
|
||||
for (const bNode *node : nodes) {
|
||||
LISTBASE_FOREACH (const bNodeSocket *, socket, &node->inputs) {
|
||||
result.add_new(socket);
|
||||
}
|
||||
LISTBASE_FOREACH (const bNodeSocket *, socket, &node->outputs) {
|
||||
result.add_new(socket);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Checks if the node group is the same as the one generated by #create_auto_smooth_modifier. */
|
||||
static bool is_auto_smooth_node_tree(const bNodeTree &group)
|
||||
{
|
||||
if (group.type != NTREE_GEOMETRY) {
|
||||
return false;
|
||||
}
|
||||
const Span<const bNode *> nodes = group.all_nodes();
|
||||
if (nodes.size() != 10) {
|
||||
return false;
|
||||
}
|
||||
if (!group.geometry_node_asset_traits) {
|
||||
return false;
|
||||
}
|
||||
if (group.geometry_node_asset_traits->flag != GEO_NODE_ASSET_MODIFIER) {
|
||||
return false;
|
||||
}
|
||||
const std::array<StringRef, 10> idnames({"NodeGroupOutput",
|
||||
"NodeGroupInput",
|
||||
"NodeGroupInput",
|
||||
"GeometryNodeSetShadeSmooth",
|
||||
"GeometryNodeSetShadeSmooth",
|
||||
"GeometryNodeInputMeshEdgeAngle",
|
||||
"GeometryNodeInputEdgeSmooth",
|
||||
"GeometryNodeInputShadeSmooth",
|
||||
"FunctionNodeBooleanMath",
|
||||
"FunctionNodeCompare"});
|
||||
for (const int i : nodes.index_range()) {
|
||||
if (nodes[i]->idname != idnames[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (nodes[3]->custom1 != int16_t(bke::AttrDomain::Edge)) {
|
||||
return false;
|
||||
}
|
||||
if (static_cast<bNodeSocket *>(nodes[4]->inputs.last)
|
||||
->default_value_typed<bNodeSocketValueBoolean>()
|
||||
->value != true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (nodes[4]->custom1 != int16_t(bke::AttrDomain::Face)) {
|
||||
return false;
|
||||
}
|
||||
if (nodes[8]->custom1 != NODE_BOOLEAN_MATH_AND) {
|
||||
return false;
|
||||
}
|
||||
if (static_cast<NodeFunctionCompare *>(nodes[9]->storage)->operation != NODE_COMPARE_LESS_EQUAL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (BLI_listbase_count(&group.links) != 9) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::array<int, 9> link_from_socket_indices({16, 15, 3, 36, 19, 5, 18, 11, 22});
|
||||
const std::array<int, 9> link_to_socket_indices({23, 0, 24, 20, 21, 8, 9, 12, 10});
|
||||
const VectorSet<const bNodeSocket *> socket_indices = build_socket_indices(nodes);
|
||||
int i;
|
||||
LISTBASE_FOREACH_INDEX (const bNodeLink *, link, &group.links, i) {
|
||||
if (socket_indices.index_of(link->fromsock) != link_from_socket_indices[i]) {
|
||||
return false;
|
||||
}
|
||||
if (socket_indices.index_of(link->tosock) != link_to_socket_indices[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static ModifierData *create_auto_smooth_modifier(
|
||||
Object &object,
|
||||
const FunctionRef<bNodeTree *(Library *library)> get_node_group,
|
||||
const float angle)
|
||||
{
|
||||
auto *md = reinterpret_cast<NodesModifierData *>(BKE_modifier_new(eModifierType_Nodes));
|
||||
STRNCPY(md->modifier.name, DATA_("Auto Smooth"));
|
||||
BKE_modifier_unique_name(&object.modifiers, &md->modifier);
|
||||
md->node_group = get_node_group();
|
||||
md->node_group = get_node_group(object.id.lib);
|
||||
id_us_plus(&md->node_group->id);
|
||||
|
||||
md->settings.properties = idprop::create_group("Nodes Modifier Settings").release();
|
||||
IDProperty *angle_prop = idprop::create("Socket_1", angle).release();
|
||||
|
|
@ -2263,14 +2352,43 @@ static ModifierData *create_auto_smooth_modifier(Object &object,
|
|||
|
||||
void BKE_main_mesh_legacy_convert_auto_smooth(Main &bmain)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
|
||||
/* Add the node group lazily and share it among all objects in the main database. */
|
||||
bNodeTree *node_group = nullptr;
|
||||
const auto add_node_group = [&]() {
|
||||
node_group = add_auto_smooth_node_tree(bmain);
|
||||
BKE_ntree_update_main_tree(&bmain, node_group, nullptr);
|
||||
return node_group;
|
||||
/* Add the node group lazily and share it among all objects in the same library. */
|
||||
Map<Library *, bNodeTree *> group_by_library;
|
||||
const auto add_node_group = [&](Library *library) {
|
||||
if (bNodeTree **group = group_by_library.lookup_ptr(library)) {
|
||||
/* Node tree has already been found/created for this versioning call. */
|
||||
return *group;
|
||||
}
|
||||
/* Try to find an existing group added by previous versioning to avoid adding duplicates. */
|
||||
LISTBASE_FOREACH (bNodeTree *, existing_group, &bmain.nodetrees) {
|
||||
if (existing_group->id.lib != library) {
|
||||
continue;
|
||||
}
|
||||
if (is_auto_smooth_node_tree(*existing_group)) {
|
||||
group_by_library.add_new(library, existing_group);
|
||||
return existing_group;
|
||||
}
|
||||
}
|
||||
bNodeTree *new_group = add_auto_smooth_node_tree(bmain);
|
||||
/* Remove the default user. The count is tracked manually when assigning to modifiers. */
|
||||
id_us_min(&new_group->id);
|
||||
|
||||
if (new_group->id.lib != library) {
|
||||
/* Move the node group to the requested library so that library data-blocks don't point to
|
||||
* local data-blocks. This requires making sure the name is unique in that library and
|
||||
* changing the name maps to be consistent with the new state. */
|
||||
new_group->id.lib = library;
|
||||
BKE_id_new_name_validate(&bmain, &bmain.nodetrees, &new_group->id, nullptr, false);
|
||||
if (library) {
|
||||
new_group->id.tag |= LIB_TAG_INDIRECT;
|
||||
}
|
||||
}
|
||||
|
||||
group_by_library.add_new(library, new_group);
|
||||
return new_group;
|
||||
};
|
||||
|
||||
LISTBASE_FOREACH (Object *, object, &bmain.objects) {
|
||||
|
|
@ -2282,7 +2400,6 @@ void BKE_main_mesh_legacy_convert_auto_smooth(Main &bmain)
|
|||
if (!(mesh->flag & ME_AUTOSMOOTH_LEGACY)) {
|
||||
continue;
|
||||
}
|
||||
mesh->flag &= ~ME_AUTOSMOOTH_LEGACY;
|
||||
|
||||
/* Auto-smooth disabled sharp edge tagging when the evaluated mesh had custom normals.
|
||||
* When the original mesh has custom normals, that's a good sign the evaluated mesh will
|
||||
|
|
@ -2299,6 +2416,12 @@ void BKE_main_mesh_legacy_convert_auto_smooth(Main &bmain)
|
|||
if (ELEM(md->type, eModifierType_WeightedNormal, eModifierType_NormalEdit)) {
|
||||
has_custom_normals = true;
|
||||
}
|
||||
if (md->type == eModifierType_Bevel) {
|
||||
BevelModifierData *bmd = reinterpret_cast<BevelModifierData *>(md);
|
||||
if (bmd->flags & MOD_BEVEL_HARDEN_NORMALS) {
|
||||
has_custom_normals = true;
|
||||
}
|
||||
}
|
||||
if (md->type == eModifierType_WeightedNormal) {
|
||||
WeightedNormalModifierData *nmd = reinterpret_cast<WeightedNormalModifierData *>(md);
|
||||
if ((nmd->flag & MOD_WEIGHTEDNORMAL_KEEP_SHARP) != 0) {
|
||||
|
|
@ -2311,13 +2434,11 @@ void BKE_main_mesh_legacy_convert_auto_smooth(Main &bmain)
|
|||
/* Some modifiers always generate custom normals which disabled sharp edge tagging, making
|
||||
* adding a modifier at the end unnecessary. Conceptually this is similar to checking if the
|
||||
* evaluated mesh had custom normals. */
|
||||
ModifierData *last_md = static_cast<ModifierData *>(object->modifiers.last);
|
||||
if (last_md) {
|
||||
if (ELEM(last_md->type, eModifierType_WeightedNormal, eModifierType_NormalEdit)) {
|
||||
continue;
|
||||
}
|
||||
if (has_custom_normals) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ModifierData *last_md = static_cast<ModifierData *>(object->modifiers.last);
|
||||
ModifierData *new_md = create_auto_smooth_modifier(*object, add_node_group, angle);
|
||||
if (last_md && last_md->type == eModifierType_Subsurf && has_custom_normals &&
|
||||
(reinterpret_cast<SubsurfModifierData *>(last_md)->flags &
|
||||
|
|
@ -2331,6 +2452,10 @@ void BKE_main_mesh_legacy_convert_auto_smooth(Main &bmain)
|
|||
BLI_addtail(&object->modifiers, new_md);
|
||||
}
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (Mesh *, mesh, &bmain.meshes) {
|
||||
mesh->flag &= ~ME_AUTOSMOOTH_LEGACY;
|
||||
}
|
||||
}
|
||||
|
||||
namespace blender::bke {
|
||||
|
|
|
|||
|
|
@ -531,7 +531,10 @@ void do_versions_after_setup(Main *new_bmain, BlendFileReadReport *reports)
|
|||
BKE_lib_override_library_main_hierarchy_root_ensure(new_bmain);
|
||||
}
|
||||
|
||||
if (!blendfile_or_libraries_versions_atleast(new_bmain, 401, 2)) {
|
||||
if (!blendfile_or_libraries_versions_atleast(new_bmain, 402, 22)) {
|
||||
/* Initial auto smooth versioning started at (401, 2), but a bug caused the legacy flag to not
|
||||
* be cleared, so it is re-run in a later version when the bug is fixed and the versioning has
|
||||
* been made idempotent. */
|
||||
BKE_main_mesh_legacy_convert_auto_smooth(*new_bmain);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue