Merge branch 'blender-v4.1-release'
This commit is contained in:
@@ -2115,9 +2115,10 @@ void BKE_mesh_legacy_convert_polys_to_offsets(Mesh *mesh)
|
||||
/** \name Auto Smooth Conversion
|
||||
* \{ */
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
static bNodeTree *add_auto_smooth_node_tree(Main &bmain)
|
||||
{
|
||||
using namespace blender;
|
||||
bNodeTree *group = ntreeAddTree(&bmain, DATA_("Auto Smooth"), "GeometryNodeTree");
|
||||
if (!group->geometry_node_asset_traits) {
|
||||
group->geometry_node_asset_traits = MEM_new<GeometryNodeAssetTraits>(__func__);
|
||||
@@ -2235,65 +2236,96 @@ static bNodeTree *add_auto_smooth_node_tree(Main &bmain)
|
||||
return group;
|
||||
}
|
||||
|
||||
static ModifierData *create_auto_smooth_modifier(Object &object,
|
||||
const FunctionRef<bNodeTree *()> 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->settings.properties = idprop::create_group("Nodes Modifier Settings").release();
|
||||
IDProperty *angle_prop = idprop::create(DATA_("Socket_1"), angle).release();
|
||||
auto *ui_data = reinterpret_cast<IDPropertyUIDataFloat *>(IDP_ui_data_ensure(angle_prop));
|
||||
ui_data->base.rna_subtype = PROP_ANGLE;
|
||||
ui_data->soft_min = 0.0f;
|
||||
ui_data->soft_max = DEG2RADF(180.0f);
|
||||
IDP_AddToGroup(md->settings.properties, angle_prop);
|
||||
IDP_AddToGroup(md->settings.properties,
|
||||
idprop::create(DATA_("Input_1_use_attribute"), 0).release());
|
||||
IDP_AddToGroup(md->settings.properties,
|
||||
idprop::create(DATA_("Input_1_attribute_name"), "").release());
|
||||
|
||||
BKE_modifiers_persistent_uid_init(object, md->modifier);
|
||||
return &md->modifier;
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
void BKE_main_mesh_legacy_convert_auto_smooth(Main &bmain)
|
||||
{
|
||||
using namespace blender;
|
||||
bNodeTree *auto_smooth_node_tree = nullptr;
|
||||
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;
|
||||
};
|
||||
|
||||
LISTBASE_FOREACH (Object *, object, &bmain.objects) {
|
||||
if (object->type != OB_MESH) {
|
||||
continue;
|
||||
}
|
||||
Mesh *mesh = static_cast<Mesh *>(object->data);
|
||||
const float angle = mesh->smoothresh_legacy;
|
||||
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
|
||||
* have custom normals as well. */
|
||||
if (CustomData_has_layer(&mesh->corner_data, CD_CUSTOMLOOPNORMAL)) {
|
||||
/* 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
|
||||
* have custom normals as well. */
|
||||
continue;
|
||||
}
|
||||
if (ModifierData *last_md = static_cast<ModifierData *>(object->modifiers.last)) {
|
||||
|
||||
/* The "Weighted Normal" modifier has a "Keep Sharp" option that used to recalculate the sharp
|
||||
* edge tags based on the mesh's smoothing angle. To keep the same behavior, a new modifier has
|
||||
* to be added before that modifier when the option is on. */
|
||||
LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
|
||||
if (md->type == eModifierType_WeightedNormal) {
|
||||
WeightedNormalModifierData *nmd = reinterpret_cast<WeightedNormalModifierData *>(md);
|
||||
if ((nmd->flag & MOD_WEIGHTEDNORMAL_KEEP_SHARP) != 0) {
|
||||
ModifierData *new_md = create_auto_smooth_modifier(*object, add_node_group, angle);
|
||||
BLI_insertlinkbefore(&object->modifiers, object->modifiers.last, new_md);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)) {
|
||||
/* These modifiers always generate custom normals which disabled sharp edge tagging. */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!auto_smooth_node_tree) {
|
||||
auto_smooth_node_tree = add_auto_smooth_node_tree(bmain);
|
||||
BKE_ntree_update_main_tree(&bmain, auto_smooth_node_tree, nullptr);
|
||||
}
|
||||
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 = auto_smooth_node_tree;
|
||||
mesh->flag &= ~ME_AUTOSMOOTH_LEGACY;
|
||||
|
||||
if (!BLI_listbase_is_empty(&object->modifiers) &&
|
||||
static_cast<ModifierData *>(object->modifiers.last)->type == eModifierType_Subsurf)
|
||||
{
|
||||
ModifierData *new_md = create_auto_smooth_modifier(*object, add_node_group, angle);
|
||||
if (last_md && last_md->type == eModifierType_Subsurf) {
|
||||
/* Add the auto smooth node group before the last subdivision surface modifier if possible.
|
||||
* Subdivision surface modifiers have special handling for interpolating face corner normals,
|
||||
* and recalculating them afterwards isn't usually helpful and can be much slower. */
|
||||
BLI_insertlinkbefore(&object->modifiers, object->modifiers.last, md);
|
||||
BLI_insertlinkbefore(&object->modifiers, object->modifiers.last, new_md);
|
||||
}
|
||||
else {
|
||||
BLI_addtail(&object->modifiers, md);
|
||||
BLI_addtail(&object->modifiers, new_md);
|
||||
}
|
||||
BKE_modifiers_persistent_uid_init(*object, md->modifier);
|
||||
|
||||
md->settings.properties = bke::idprop::create_group("Nodes Modifier Settings").release();
|
||||
IDProperty *angle_prop =
|
||||
bke::idprop::create(DATA_("Socket_1"), mesh->smoothresh_legacy).release();
|
||||
auto *ui_data = reinterpret_cast<IDPropertyUIDataFloat *>(IDP_ui_data_ensure(angle_prop));
|
||||
ui_data->base.rna_subtype = PROP_ANGLE;
|
||||
ui_data->soft_min = 0.0f;
|
||||
ui_data->soft_max = DEG2RADF(180.0f);
|
||||
IDP_AddToGroup(md->settings.properties, angle_prop);
|
||||
IDP_AddToGroup(md->settings.properties,
|
||||
bke::idprop::create(DATA_("Input_1_use_attribute"), 0).release());
|
||||
IDP_AddToGroup(md->settings.properties,
|
||||
bke::idprop::create(DATA_("Input_1_attribute_name"), "").release());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user