diff options
author | Jacques Lucke <jacques@blender.org> | 2021-11-15 15:21:15 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2021-11-15 15:21:15 +0300 |
commit | a9ac8b44d5aea5d56eb132d3ff1ed3934478ea9c (patch) | |
tree | 1b52fdbcfd23e54d4cadf4f54d4a48a0b1451ee4 /source/blender/modifiers | |
parent | 36bf158e5c184e048d59d3da202c8e1a5a109140 (diff) | |
parent | c2c65cc4bf9467c180387ae791bd4fe3e7fbba8c (diff) |
Merge branch 'master' into node-tree-update-refactor
Diffstat (limited to 'source/blender/modifiers')
-rw-r--r-- | source/blender/modifiers/intern/MOD_meshdeform.c | 2 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_nodes.cc | 47 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_uvproject.c | 4 |
3 files changed, 34 insertions, 19 deletions
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index c997cd7377f..cb043643dd9 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -426,7 +426,7 @@ static void meshdeformModifier_do(ModifierData *md, bindcagecos = (float(*)[3])mmd->bindcagecos; for (a = 0; a < totcagevert; a++) { - /* get cage vertex in world space with binding transform */ + /* Get cage vertex in world-space with binding transform. */ float co[3]; mul_v3_m4v3(co, mmd->bindmat, dco[a]); /* compute difference with world space bind coord */ diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 218493a53cf..fb9dbc0ad0a 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -89,6 +89,7 @@ #include "MOD_ui_common.h" #include "ED_object.h" +#include "ED_screen.h" #include "ED_spreadsheet.h" #include "ED_undo.h" @@ -1026,17 +1027,22 @@ static void check_property_socket_sync(const Object *ob, ModifierData *md) { NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md); - int i = 0; + int geometry_socket_count = 0; + + int i; LISTBASE_FOREACH_INDEX (const bNodeSocket *, socket, &nmd->node_group->inputs, i) { /* The first socket is the special geometry socket for the modifier object. */ - if (i == 0 && socket->type == SOCK_GEOMETRY) { - continue; + if (i == 0) { + if (socket->type == SOCK_GEOMETRY) { + continue; + } + BKE_modifier_set_error(ob, md, "The first node group input must be a geometry"); } IDProperty *property = IDP_GetPropertyFromGroup(nmd->settings.properties, socket->identifier); if (property == nullptr) { if (socket->type == SOCK_GEOMETRY) { - BKE_modifier_set_error(ob, md, "Node group can only have one geometry input"); + geometry_socket_count++; } else { BKE_modifier_set_error(ob, md, "Missing property for input socket \"%s\"", socket->name); @@ -1051,15 +1057,8 @@ static void check_property_socket_sync(const Object *ob, ModifierData *md) } } - bool has_geometry_output = false; - LISTBASE_FOREACH (const bNodeSocket *, socket, &nmd->node_group->outputs) { - if (socket->type == SOCK_GEOMETRY) { - has_geometry_output = true; - } - } - - if (!has_geometry_output) { - BKE_modifier_set_error(ob, md, "Node group must have a geometry output"); + if (geometry_socket_count > 1) { + BKE_modifier_set_error(ob, md, "Node group can only have one geometry input"); } } @@ -1079,6 +1078,7 @@ static void modifyGeometry(ModifierData *md, if (tree.has_link_cycles()) { BKE_modifier_set_error(ctx->object, md, "Node group has cycles"); + geometry_set.clear(); return; } @@ -1086,17 +1086,23 @@ static void modifyGeometry(ModifierData *md, Span<const NodeRef *> input_nodes = root_tree_ref.nodes_by_type("NodeGroupInput"); Span<const NodeRef *> output_nodes = root_tree_ref.nodes_by_type("NodeGroupOutput"); if (output_nodes.size() != 1) { + BKE_modifier_set_error(ctx->object, md, "Node group must have a single output node"); + geometry_set.clear(); return; } const NodeRef &output_node = *output_nodes[0]; Span<const InputSocketRef *> group_outputs = output_node.inputs().drop_back(1); if (group_outputs.is_empty()) { + BKE_modifier_set_error(ctx->object, md, "Node group must have an output socket"); + geometry_set.clear(); return; } const InputSocketRef *first_output_socket = group_outputs[0]; if (first_output_socket->idname() != "NodeSocketGeometry") { + BKE_modifier_set_error(ctx->object, md, "Node group's first output must be a geometry"); + geometry_set.clear(); return; } @@ -1133,8 +1139,17 @@ struct AttributeSearchData { /* This class must not have a destructor, since it is used by buttons and freed with #MEM_freeN. */ BLI_STATIC_ASSERT(std::is_trivially_destructible_v<AttributeSearchData>, ""); -static NodesModifierData *get_modifier_data(Main &bmain, const AttributeSearchData &data) +static NodesModifierData *get_modifier_data(Main &bmain, + const wmWindowManager &wm, + const AttributeSearchData &data) { + if (ED_screen_animation_playing(&wm)) { + /* Work around an issue where the attribute search exec function has stale pointers when data + * is reallocated when evaluating the node tree, causing a crash. This would be solved by + * allowing the UI search data to own arbitrary memory rather than just referencing it. */ + return nullptr; + } + const Object *object = (Object *)BKE_libblock_find_session_uuid( &bmain, ID_OB, data.object_session_uid); if (object == nullptr) { @@ -1152,7 +1167,7 @@ static void attribute_search_update_fn( const bContext *C, void *arg, const char *str, uiSearchItems *items, const bool is_first) { AttributeSearchData &data = *static_cast<AttributeSearchData *>(arg); - const NodesModifierData *nmd = get_modifier_data(*CTX_data_main(C), data); + const NodesModifierData *nmd = get_modifier_data(*CTX_data_main(C), *CTX_wm_manager(C), data); if (nmd == nullptr) { return; } @@ -1186,7 +1201,7 @@ static void attribute_search_exec_fn(bContext *C, void *data_v, void *item_v) } AttributeSearchData &data = *static_cast<AttributeSearchData *>(data_v); const GeometryAttributeInfo &item = *static_cast<const GeometryAttributeInfo *>(item_v); - const NodesModifierData *nmd = get_modifier_data(*CTX_data_main(C), data); + const NodesModifierData *nmd = get_modifier_data(*CTX_data_main(C), *CTX_wm_manager(C), data); if (nmd == nullptr) { return; } diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c index 2c28e9710ef..238952fde00 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.c +++ b/source/blender/modifiers/intern/MOD_uvproject.c @@ -192,7 +192,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, mul_m4_m4m4(projectors[i].projmat, offsetmat, tmpmat); - /* calculate worldspace projector normal (for best projector test) */ + /* Calculate world-space projector normal (for best projector test). */ projectors[i].normal[0] = 0; projectors[i].normal[1] = 0; projectors[i].normal[2] = 1; @@ -208,7 +208,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, coords = BKE_mesh_vert_coords_alloc(mesh, &numVerts); - /* convert coords to world space */ + /* Convert coords to world-space. */ for (i = 0, co = coords; i < numVerts; i++, co++) { mul_m4_v3(ob->obmat, *co); } |