Geometry Nodes: Store curves surface data before modifier stack evaluation

This commit stores the curves' attachment surface information on the geometry
bundle before the object's modifiers are evaluated.

Currently one needs to make sure that a modifier like "Generate Hair Curves"
is used at the beginning of the stack, or to add the "Set Attachment Surface"
modifier first. This can be confusing and inconsistent though, and since this
data is already configured automatically on the curves data-block, it makes
sense that this is done automatically for the vast majority of cases, even if
conceptually it's unfortunate that it doesn't use the generic/flexible modifier
system.

Note: Assets are not changed as part of this commit yet.

Co-authored-by: Jacques Lucke <jacques@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/159304
This commit is contained in:
Hans Goudey 2026-06-01 19:26:31 +02:00 • committed by Jacques Lucke
parent b6ef80f9b9
commit b10d29bb36
3 changed files with 22 additions and 9 deletions

View file

@ -43,6 +43,8 @@
#include "BLO_read_write.hh"
#include "NOD_geometry_nodes_bundle.hh"
namespace blender {
static const char *ATTR_POSITION = "position";
@ -188,6 +190,20 @@ Curves *BKE_curves_copy_for_eval(const Curves *curves_src)
BKE_id_copy_ex(nullptr, &curves_src->id, nullptr, LIB_ID_COPY_LOCALIZE));
}
static void store_surface(const Curves &curves_id, bke::GeometrySet &geometry_set)
{
if (!curves_id.surface) {
return;
}
if (!curves_id.surface_uv_map) {
return;
}
nodes::Bundle &bundle = geometry_set.bundle_for_write();
bundle.add(*nodes::BundleKey::from_ustr("surface_object"_ustr), curves_id.surface);
bundle.add(*nodes::BundleKey::from_ustr("surface_uv_map_name"_ustr),
std::string(curves_id.surface_uv_map));
}
static void curves_evaluate_modifiers(Depsgraph *depsgraph,
Scene *scene,
Object *object,
@ -242,6 +258,7 @@ void BKE_curves_data_update(Depsgraph *depsgraph, Scene *scene, Object *object)
edit_component.curves_edit_hints_ = std::make_unique<CurvesEditHints>(
*id_cast<const Curves *>(DEG_get_original(object)->data));
}
store_surface(*curves, geometry_set);
curves_evaluate_modifiers(depsgraph, scene, object, geometry_set);
/* Assign evaluated object. */

View file

@ -2836,8 +2836,11 @@ void DepsgraphRelationBuilder::build_object_data_geometry_datablock(ID *obdata)
if (curves_id->surface != nullptr) {
build_object(curves_id->surface);
/* The relations between the surface and the curves are handled as part of the modifier
* stack building. */
ComponentKey surface_geometry_key(&curves_id->surface->id, NodeType::GEOMETRY);
add_relation(surface_geometry_key, obdata_geom_eval_key, "Curves Object Surface");
ComponentKey surface_transform_key(&curves_id->surface->id, NodeType::TRANSFORM);
add_relation(surface_transform_key, obdata_geom_eval_key, "Curves Object Surface");
}
break;
}

View file

@ -182,13 +182,6 @@ static void update_depsgraph(ModifierData *md, const ModifierUpdateDepsgraphCont
/* Create dependencies to data-blocks referenced by the settings in the modifier. */
find_dependencies_from_settings(*nmd, eval_deps);
if (ctx->object->type == OB_CURVES) {
Curves *curves_id = id_cast<Curves *>(ctx->object->data);
if (curves_id->surface != nullptr) {
eval_deps.add_object(curves_id->surface);
}
}
for (const NodesModifierBake &bake : Span(nmd->bakes, nmd->bakes_num)) {
for (const NodesModifierDataBlock &data_block : Span(bake.data_blocks, bake.data_blocks_num)) {
if (data_block.id) {