Curves: Add RNA access to evaluated normals per control point
Add an RNA API function that gives an array of the normals for every control point. The normals depend on the `normal_mode` attribute, which can currently be minumum twist or Z-up, though more options are planned. Normals are currently evaluated on the evaluated points and then sampled back to the control points. Because that can be expensive, a normal mode that only does a first evaluation on control points may be important The function is intended to be used by Cycles, so it doesn't have to implement the calculation of normals itself. They can be interpolated between control points and normalized. For best performance, the function should only be called once, since it does the full calculation for every control point every time it is called. Differential Revision: https://developer.blender.org/D17024
This commit is contained in:
parent
203ab983ce
commit
241d87e9f4
|
@ -21,6 +21,7 @@ set(INC
|
|||
|
||||
set(SRC
|
||||
intern/curves_add.cc
|
||||
intern/curves_data.cc
|
||||
intern/curves_ops.cc
|
||||
intern/curves_selection.cc
|
||||
)
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_geometry_fields.hh"
|
||||
|
||||
#include "ED_curves.h"
|
||||
|
||||
float (*ED_curves_point_normals_array_create(const Curves *curves_id))[3]
|
||||
{
|
||||
using namespace blender;
|
||||
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry);
|
||||
const int size = curves.points_num();
|
||||
|
||||
float3 *data = static_cast<float3 *>(MEM_malloc_arrayN(size, sizeof(float3), __func__));
|
||||
|
||||
const bke::CurvesFieldContext context(curves, ATTR_DOMAIN_POINT);
|
||||
fn::FieldEvaluator evaluator(context, size);
|
||||
fn::Field<float3> field(std::make_shared<bke::NormalFieldInput>());
|
||||
evaluator.add_with_destination(std::move(field), {data, size});
|
||||
evaluator.evaluate();
|
||||
|
||||
return reinterpret_cast<float(*)[3]>(data);
|
||||
}
|
|
@ -7,13 +7,27 @@
|
|||
#pragma once
|
||||
|
||||
struct bContext;
|
||||
struct Curves;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name C Wrappers
|
||||
* \{ */
|
||||
|
||||
void ED_operatortypes_curves(void);
|
||||
|
||||
/**
|
||||
* Return an owning pointer to an array of point normals the same size as the number of control
|
||||
* points. The normals depend on the normal mode for each curve and the "tilt" attribute and may be
|
||||
* calculated for the evaluated points and sampled back to the control points.
|
||||
*/
|
||||
float (*ED_curves_point_normals_array_create(const struct Curves *curves_id))[3];
|
||||
|
||||
/** \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -50,6 +50,8 @@ const EnumPropertyItem rna_enum_curve_normal_modes[] = {
|
|||
|
||||
# include "DEG_depsgraph.h"
|
||||
|
||||
# include "ED_curves.h"
|
||||
|
||||
# include "WM_api.h"
|
||||
# include "WM_types.h"
|
||||
|
||||
|
@ -217,6 +219,14 @@ static void rna_CurveSlice_points_begin(CollectionPropertyIterator *iter, Pointe
|
|||
rna_iterator_array_begin(iter, co, sizeof(float[3]), size, 0, NULL);
|
||||
}
|
||||
|
||||
static void rna_Curves_normals_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||
{
|
||||
Curves *curves = rna_curves(ptr);
|
||||
float(*positions)[3] = ED_curves_point_normals_array_create(curves);
|
||||
const int size = curves->geometry.point_num;
|
||||
rna_iterator_array_begin(iter, positions, sizeof(float[3]), size, true, NULL);
|
||||
}
|
||||
|
||||
static void rna_Curves_update_data(struct Main *UNUSED(bmain),
|
||||
struct Scene *UNUSED(scene),
|
||||
PointerRNA *ptr)
|
||||
|
@ -268,6 +278,20 @@ static void rna_def_curves_point(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Index", "Index of this points");
|
||||
}
|
||||
|
||||
/* Defines a read-only vector type since normals can not be modified manually. */
|
||||
static void rna_def_read_only_float_vector(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna = RNA_def_struct(brna, "FloatVectorValueReadOnly", NULL);
|
||||
RNA_def_struct_sdna(srna, "vec3f");
|
||||
RNA_def_struct_ui_text(srna, "Read-Only Vector", "");
|
||||
|
||||
PropertyRNA *prop = RNA_def_property(srna, "vector", PROP_FLOAT, PROP_DIRECTION);
|
||||
RNA_def_property_ui_text(prop, "Vector", "3D vector");
|
||||
RNA_def_property_float_sdna(prop, NULL, "x");
|
||||
RNA_def_property_array(prop, 3);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
}
|
||||
|
||||
static void rna_def_curves_curve(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
@ -365,6 +389,24 @@ static void rna_def_curves(BlenderRNA *brna)
|
|||
NULL);
|
||||
RNA_def_property_update(prop, 0, "rna_Curves_update_data");
|
||||
|
||||
rna_def_read_only_float_vector(brna);
|
||||
|
||||
prop = RNA_def_property(srna, "normals", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "FloatVectorValueReadOnly");
|
||||
/* `lookup_int` isn't provided since the entire normals array is allocated and calculated when
|
||||
* it's accessed. */
|
||||
RNA_def_property_collection_funcs(prop,
|
||||
"rna_Curves_normals_begin",
|
||||
"rna_iterator_array_next",
|
||||
"rna_iterator_array_end",
|
||||
"rna_iterator_array_get",
|
||||
"rna_Curves_position_data_length",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Normals", "The curve normal value at each of the curve's control points");
|
||||
|
||||
/* materials */
|
||||
prop = RNA_def_property(srna, "materials", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "mat", "totcol");
|
||||
|
|
|
@ -3239,7 +3239,7 @@ static void rna_def_mesh_polygons(BlenderRNA *brna, PropertyRNA *cprop)
|
|||
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
|
||||
}
|
||||
|
||||
/* Defines a read-only vector type since normals should not be modified manually. */
|
||||
/* Defines a read-only vector type since normals can not be modified manually. */
|
||||
static void rna_def_normal_layer_value(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna = RNA_def_struct(brna, "MeshNormalValue", NULL);
|
||||
|
|
Loading…
Reference in New Issue