[Bf-blender-cvs] [241d87e9f41] master: Curves: Add RNA access to evaluated normals per control point

Hans Goudey noreply at git.blender.org
Fri Jan 20 00:45:04 CET 2023


Commit: 241d87e9f41983daf757cbd126e35f0910c3a094
Author: Hans Goudey
Date:   Thu Jan 19 17:43:55 2023 -0600
Branches: master
https://developer.blender.org/rB241d87e9f41983daf757cbd126e35f0910c3a094

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

===================================================================

M	source/blender/editors/curves/CMakeLists.txt
A	source/blender/editors/curves/intern/curves_data.cc
M	source/blender/editors/include/ED_curves.h
M	source/blender/makesrna/intern/rna_curves.c
M	source/blender/makesrna/intern/rna_mesh.c

===================================================================

diff --git a/source/blender/editors/curves/CMakeLists.txt b/source/blender/editors/curves/CMakeLists.txt
index 4d81b4454ac..bba85f9c77a 100644
--- a/source/blender/editors/curves/CMakeLists.txt
+++ b/source/blender/editors/curves/CMakeLists.txt
@@ -21,6 +21,7 @@ set(INC
 
 set(SRC
   intern/curves_add.cc
+  intern/curves_data.cc
   intern/curves_ops.cc
   intern/curves_selection.cc
 )
diff --git a/source/blender/editors/curves/intern/curves_data.cc b/source/blender/editors/curves/intern/curves_data.cc
new file mode 100644
index 00000000000..bcec7156bf3
--- /dev/null
+++ b/source/blender/editors/curves/intern/curves_data.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);
+}
diff --git a/source/blender/editors/include/ED_curves.h b/source/blender/editors/include/ED_curves.h
index 7d2bad635b5..bf6b78676b9 100644
--- a/source/blender/editors/include/ED_curves.h
+++ b/source/blender/editors/include/ED_curves.h
@@ -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
diff --git a/source/blender/makesrna/intern/rna_curves.c b/source/blender/makesrna/intern/rna_curves.c
index 3db4695a9b9..7560e1a60cb 100644
--- a/source/blender/makesrna/intern/rna_curves.c
+++ b/source/blender/makesrna/intern/rna_curves.c
@@ -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");
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index f1247c551a0..7c8e7431652 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -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);



More information about the Bf-blender-cvs mailing list