Curves: initial geometry nodes support for curves objects

* Curves objects now support the geometry nodes modifier.
* It's possible to use the curves object with the Object Info node.
* The spreadsheet shows the curve data.

The main thing holding this back currently is that the drawing code
for the curves object is very incomplete. E.g. it resamples the curves
always in the end, which is not expected for curves in general.

Differential Revision: https://developer.blender.org/D14277
This commit is contained in:
Jacques Lucke 2022-04-15 09:07:00 +02:00
parent db6287873c
commit 2839fe9a4d
Notes: blender-bot 2023-02-14 00:29:15 +01:00
Referenced by issue #96215, Support Curves object in Object Info node.
5 changed files with 32 additions and 33 deletions

View File

@ -26,8 +26,9 @@ def geometry_node_group_empty_new():
def geometry_modifier_poll(context):
ob = context.object
# Test object support for geometry node modifier (No curves object support yet)
if not ob or ob.type not in {'MESH', 'POINTCLOUD', 'VOLUME', 'CURVE', 'FONT'}:
# Test object support for geometry node modifier
if not ob or ob.type not in {'MESH', 'POINTCLOUD', 'VOLUME', 'CURVE', 'FONT', 'CURVES'}:
return False
return True

View File

@ -402,7 +402,8 @@ std::unique_ptr<CurveEval> curves_to_curve_eval(const Curves &curves)
const IndexRange point_range = geometry.points_for_curve(curve_index);
std::unique_ptr<Spline> spline;
switch (curve_types[curve_index]) {
/* #CurveEval does not support catmull rom curves, so convert those to poly splines. */
switch (std::max<int8_t>(1, curve_types[curve_index])) {
case CURVE_TYPE_POLY: {
spline = std::make_unique<PolySpline>();
spline->resize(point_range.size());

View File

@ -27,6 +27,7 @@
#include "BKE_anim_data.h"
#include "BKE_curves.hh"
#include "BKE_customdata.h"
#include "BKE_geometry_set.hh"
#include "BKE_global.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
@ -282,13 +283,11 @@ Curves *BKE_curves_copy_for_eval(Curves *curves_src, bool reference)
return result;
}
static Curves *curves_evaluate_modifiers(struct Depsgraph *depsgraph,
struct Scene *scene,
Object *object,
Curves *curves_input)
static void curves_evaluate_modifiers(struct Depsgraph *depsgraph,
struct Scene *scene,
Object *object,
GeometrySet &geometry_set)
{
Curves *curves = curves_input;
/* Modifier evaluation modes. */
const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
const int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime;
@ -308,27 +307,10 @@ static Curves *curves_evaluate_modifiers(struct Depsgraph *depsgraph,
continue;
}
if ((mti->type == eModifierTypeType_OnlyDeform) &&
(mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly)) {
/* Ensure we are not modifying the input. */
if (curves == curves_input) {
curves = BKE_curves_copy_for_eval(curves, true);
}
/* Created deformed coordinates array on demand. */
blender::bke::CurvesGeometry &geometry = blender::bke::CurvesGeometry::wrap(
curves->geometry);
MutableSpan<float3> positions = geometry.positions_for_write();
mti->deformVerts(md,
&mectx,
nullptr,
reinterpret_cast<float(*)[3]>(positions.data()),
curves->geometry.point_size);
if (mti->modifyGeometrySet != nullptr) {
mti->modifyGeometrySet(md, &mectx, &geometry_set);
}
}
return curves;
}
void BKE_curves_data_update(struct Depsgraph *depsgraph, struct Scene *scene, Object *object)
@ -338,11 +320,20 @@ void BKE_curves_data_update(struct Depsgraph *depsgraph, struct Scene *scene, Ob
/* Evaluate modifiers. */
Curves *curves = static_cast<Curves *>(object->data);
Curves *curves_eval = curves_evaluate_modifiers(depsgraph, scene, object, curves);
GeometrySet geometry_set = GeometrySet::create_with_curves(curves,
GeometryOwnershipType::ReadOnly);
curves_evaluate_modifiers(depsgraph, scene, object, geometry_set);
/* Assign evaluated object. */
const bool is_owned = (curves != curves_eval);
BKE_object_eval_assign_data(object, &curves_eval->id, is_owned);
Curves *curves_eval = const_cast<Curves *>(geometry_set.get_curves_for_read());
if (curves_eval == nullptr) {
curves_eval = blender::bke::curves_new_nomain(0, 0);
BKE_object_eval_assign_data(object, &curves_eval->id, true);
}
else {
BKE_object_eval_assign_data(object, &curves_eval->id, false);
}
object->runtime.geometry_set_eval = new GeometrySet(std::move(geometry_set));
}
/* Draw Cache */

View File

@ -787,7 +787,7 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx,
dupli->ob_data = (ID *)volume;
}
}
if (!ELEM(ctx->object->type, OB_CURVES_LEGACY, OB_FONT) || geometry_set_is_instance) {
if (!ELEM(ctx->object->type, OB_CURVES_LEGACY, OB_FONT, OB_CURVES) || geometry_set_is_instance) {
if (const CurveComponent *component = geometry_set.get_component_for_read<CurveComponent>()) {
if (const Curve *curve = component->get_curve_for_render()) {
DupliObject *dupli = make_dupli(ctx, ctx->object, parent_transform, component_index++);

View File

@ -264,7 +264,13 @@ Object *spreadsheet_get_object_eval(const SpaceSpreadsheet *sspreadsheet,
return nullptr;
}
Object *object_orig = (Object *)used_id;
if (!ELEM(object_orig->type, OB_MESH, OB_POINTCLOUD, OB_VOLUME, OB_CURVES_LEGACY, OB_FONT)) {
if (!ELEM(object_orig->type,
OB_MESH,
OB_POINTCLOUD,
OB_VOLUME,
OB_CURVES_LEGACY,
OB_FONT,
OB_CURVES)) {
return nullptr;
}