[Bf-blender-cvs] [f59767ff972] master: Curves: Changes to the new curves data-block

Hans Goudey noreply at git.blender.org
Thu Feb 3 17:50:03 CET 2022


Commit: f59767ff97295404dade1bc0d494cfe81e8a97bb
Author: Hans Goudey
Date:   Thu Feb 3 10:49:51 2022 -0600
Branches: master
https://developer.blender.org/rBf59767ff97295404dade1bc0d494cfe81e8a97bb

Curves: Changes to the new curves data-block

This patch refactors the "Hair" data-block, which will soon be renamed
to "Curves". The larger change is switching from an array of `HairCurve`
to find indices in the points array to simply storing an array of offsets.
Using a single integer instead of two halves the amount of memory for that
particular array.

Besides that, there are some other changes in this patch:
- Split the data-structure to a separate `CurveGeometry`
  DNA struct so it is usable for grease pencil too.
- Update naming to be more aligned with newer code and the style guide.
- Add direct access to some arrays in RNA
-- Radius is now retrieved as a regular attribute in Cycles.
-- `HairPoint` has been renamed to `CurvePoint`
-- `HairCurve` has been renamed to `CurveSlice`
- Add comments to the struct in DNA.

The next steps are renaming `Hair` -> `Curves`, and adding support
for other curve types: Bezier, Poly, and NURBS.

Ref T95355

Differential Revision: https://developer.blender.org/D13987

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

M	intern/cycles/blender/curves.cpp
M	source/blender/blenkernel/intern/attribute.c
M	source/blender/blenkernel/intern/customdata.cc
M	source/blender/blenkernel/intern/hair.cc
M	source/blender/blenloader/intern/versioning_290.c
M	source/blender/draw/intern/draw_cache_impl_hair.cc
M	source/blender/makesdna/DNA_hair_types.h
M	source/blender/makesrna/intern/rna_hair.c

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

diff --git a/intern/cycles/blender/curves.cpp b/intern/cycles/blender/curves.cpp
index 65a02d041cc..4206a1d8a8b 100644
--- a/intern/cycles/blender/curves.cpp
+++ b/intern/cycles/blender/curves.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <optional>
+
 #include "blender/sync.h"
 #include "blender/util.h"
 
@@ -625,14 +627,35 @@ void BlenderSync::sync_particle_hair(
 }
 
 #ifdef WITH_HAIR_NODES
-static float4 hair_point_as_float4(BL::HairPoint b_point)
+
+static std::optional<BL::FloatAttribute> find_curves_radius_attribute(BL::Hair b_hair)
+{
+  for (BL::Attribute &b_attribute : b_hair.attributes) {
+    if (b_attribute.name() != "radius") {
+      continue;
+    }
+    if (b_attribute.domain() != BL::Attribute::domain_POINT) {
+      continue;
+    }
+    if (b_attribute.data_type() != BL::Attribute::data_type_FLOAT) {
+      continue;
+    }
+    return BL::FloatAttribute{b_attribute};
+  }
+  return std::nullopt;
+}
+
+static float4 hair_point_as_float4(BL::Hair b_hair,
+                                   std::optional<BL::FloatAttribute> b_attr_radius,
+                                   const int index)
 {
-  float4 mP = float3_to_float4(get_float3(b_point.co()));
-  mP.w = b_point.radius();
+  float4 mP = float3_to_float4(get_float3(b_hair.position_data[index].vector()));
+  mP.w = b_attr_radius ? b_attr_radius->data[index].value() : 0.0f;
   return mP;
 }
 
 static float4 interpolate_hair_points(BL::Hair b_hair,
+                                      std::optional<BL::FloatAttribute> b_attr_radius,
                                       const int first_point_index,
                                       const int num_points,
                                       const float step)
@@ -641,8 +664,8 @@ static float4 interpolate_hair_points(BL::Hair b_hair,
   const int point_a = clamp((int)curve_t, 0, num_points - 1);
   const int point_b = min(point_a + 1, num_points - 1);
   const float t = curve_t - (float)point_a;
-  return lerp(hair_point_as_float4(b_hair.points[first_point_index + point_a]),
-              hair_point_as_float4(b_hair.points[first_point_index + point_b]),
+  return lerp(hair_point_as_float4(b_hair, b_attr_radius, first_point_index + point_a),
+              hair_point_as_float4(b_hair, b_attr_radius, first_point_index + point_b),
               t);
 }
 
@@ -671,12 +694,14 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
 
   hair->reserve_curves(num_curves, num_keys);
 
+  std::optional<BL::FloatAttribute> b_attr_radius = find_curves_radius_attribute(b_hair);
+
   /* Export curves and points. */
   vector<float> points_length;
 
-  for (BL::HairCurve &b_curve : b_hair.curves) {
-    const int first_point_index = b_curve.first_point_index();
-    const int num_points = b_curve.num_points();
+  for (int i = 0; i < num_curves; i++) {
+    const int first_point_index = b_hair.curve_offset_data[i].value();
+    const int num_points = b_hair.curve_offset_data[i + 1].value() - first_point_index;
 
     float3 prev_co = zero_float3();
     float length = 0.0f;
@@ -687,10 +712,9 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
 
     /* Position and radius. */
     for (int i = 0; i < num_points; i++) {
-      BL::HairPoint b_point = b_hair.points[first_point_index + i];
-
-      const float3 co = get_float3(b_point.co());
-      const float radius = b_point.radius();
+      const float3 co = get_float3(b_hair.position_data[first_point_index + i].vector());
+      const float radius = b_attr_radius ? b_attr_radius->data[first_point_index + i].value() :
+                                           0.0f;
       hair->add_curve_key(co, radius);
 
       if (attr_intercept) {
@@ -715,7 +739,7 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
 
     /* Random number per curve. */
     if (attr_random != NULL) {
-      attr_random->add(hash_uint2_to_float(b_curve.index(), 0));
+      attr_random->add(hash_uint2_to_float(i, 0));
     }
 
     /* Curve. */
@@ -737,14 +761,17 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st
 
   /* Export motion keys. */
   const int num_keys = hair->get_curve_keys().size();
+  const int num_curves = b_hair.curves.length();
   float4 *mP = attr_mP->data_float4() + motion_step * num_keys;
   bool have_motion = false;
   int num_motion_keys = 0;
   int curve_index = 0;
 
-  for (BL::HairCurve &b_curve : b_hair.curves) {
-    const int first_point_index = b_curve.first_point_index();
-    const int num_points = b_curve.num_points();
+  std::optional<BL::FloatAttribute> b_attr_radius = find_curves_radius_attribute(b_hair);
+
+  for (int i = 0; i < num_curves; i++) {
+    const int first_point_index = b_hair.curve_offset_data[i].value();
+    const int num_points = b_hair.curve_offset_data[i + 1].value() - first_point_index;
 
     Hair::Curve curve = hair->get_curve(curve_index);
     curve_index++;
@@ -755,7 +782,7 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st
         int point_index = first_point_index + i;
 
         if (point_index < num_keys) {
-          mP[num_motion_keys] = hair_point_as_float4(b_hair.points[point_index]);
+          mP[num_motion_keys] = hair_point_as_float4(b_hair, b_attr_radius, point_index);
           num_motion_keys++;
 
           if (!have_motion) {
@@ -774,7 +801,8 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st
       const float step_size = curve.num_keys > 1 ? 1.0f / (curve.num_keys - 1) : 0.0f;
       for (int i = 0; i < curve.num_keys; i++) {
         const float step = i * step_size;
-        mP[num_motion_keys] = interpolate_hair_points(b_hair, first_point_index, num_points, step);
+        mP[num_motion_keys] = interpolate_hair_points(
+            b_hair, b_attr_radius, first_point_index, num_points, step);
         num_motion_keys++;
       }
       have_motion = true;
diff --git a/source/blender/blenkernel/intern/attribute.c b/source/blender/blenkernel/intern/attribute.c
index ee8ef5e97f7..73e00398084 100644
--- a/source/blender/blenkernel/intern/attribute.c
+++ b/source/blender/blenkernel/intern/attribute.c
@@ -90,10 +90,10 @@ static void get_domains(const ID *id, DomainInfo info[ATTR_DOMAIN_NUM])
     }
     case ID_HA: {
       Hair *hair = (Hair *)id;
-      info[ATTR_DOMAIN_POINT].customdata = &hair->pdata;
-      info[ATTR_DOMAIN_POINT].length = hair->totpoint;
-      info[ATTR_DOMAIN_CURVE].customdata = &hair->cdata;
-      info[ATTR_DOMAIN_CURVE].length = hair->totcurve;
+      info[ATTR_DOMAIN_POINT].customdata = &hair->geometry.point_data;
+      info[ATTR_DOMAIN_POINT].length = hair->geometry.point_size;
+      info[ATTR_DOMAIN_CURVE].customdata = &hair->geometry.curve_data;
+      info[ATTR_DOMAIN_CURVE].length = hair->geometry.curve_size;
       break;
     }
     default:
diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc
index e4c18325d76..d235e6d15e1 100644
--- a/source/blender/blenkernel/intern/customdata.cc
+++ b/source/blender/blenkernel/intern/customdata.cc
@@ -1793,10 +1793,10 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
     {sizeof(float[3]), "vec3f", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
     /* 44: CD_RADIUS */
     {sizeof(float), "MFloatProperty", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
-    /* 45: CD_HAIRCURVE */
-    {sizeof(HairCurve), "HairCurve", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
-    /* 46: CD_HAIRMAPPING */
-    {sizeof(HairMapping), "HairMapping", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
+    /* 45: CD_HAIRCURVE */ /* DEPRECATED */
+    {-1, "HairCurve", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
+    /* 46: CD_HAIRMAPPING */ /* DEPRECATED */
+    {-1, "HairMapping", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
     /* 47: CD_PROP_COLOR */
     {sizeof(MPropCol),
      "MPropCol",
diff --git a/source/blender/blenkernel/intern/hair.cc b/source/blender/blenkernel/intern/hair.cc
index 5e8b81c03a4..bddadc3bcfd 100644
--- a/source/blender/blenkernel/intern/hair.cc
+++ b/source/blender/blenkernel/intern/hair.cc
@@ -28,6 +28,7 @@
 #include "DNA_material_types.h"
 #include "DNA_object_types.h"
 
+#include "BLI_index_range.hh"
 #include "BLI_listbase.h"
 #include "BLI_math_base.h"
 #include "BLI_math_vec_types.hh"
@@ -54,6 +55,8 @@
 #include "BLO_read_write.h"
 
 using blender::float3;
+using blender::IndexRange;
+using blender::MutableSpan;
 using blender::RandomNumberGenerator;
 
 static const char *HAIR_ATTR_POSITION = "position";
@@ -70,14 +73,22 @@ static void hair_init_data(ID *id)
 
   MEMCPY_STRUCT_AFTER(hair, DNA_struct_default_get(Hair), id);
 
-  CustomData_reset(&hair->pdata);
-  CustomData_reset(&hair->cdata);
+  CustomData_reset(&hair->geometry.point_data);
+  CustomData_reset(&hair->geometry.curve_data);
+
+  CustomData_add_layer_named(&hair->geometry.point_data,
+                             CD_PROP_FLOAT3,
+                             CD_CALLOC,
+                             nullptr,
+                             hair->geometry.point_size,
+                             HAIR_ATTR_POSITION);
+  CustomData_add_layer_named(&hair->geometry.point_data,
+                             CD_PROP_FLOAT,
+                             CD_CALLOC,
+                             nullptr,
+                             hair->geometry.point_size,
+                             HAIR_ATTR_RADIUS);
 
-  CustomData_add_layer_named(
-      &hair->pdata, CD_PROP_FLOAT3, CD_CALLOC, nullptr, hair->totpoint, HAIR_ATTR_POSITION);
-  CustomData_add_layer_named(
-      &hair->pdata, CD_PROP_FLOAT, CD_CALLOC, nullptr, hair->totpoint, HAIR_ATTR_RADIUS);
-  CustomData_add_layer(&hair->cdata, CD_HAIRCURVE, CD_CALLOC, nullptr, hair->totcurve);
   BKE_hair_update_customdata_pointers(hair);
 
   hair_random(hair);
@@ -89,11 +100,24 @@ static void hair_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, co
   const Hair *hair_src = (const Hair *)id_src;
   hair_dst->mat = static_cast<Material **>(MEM_dupallocN(hair_src->mat));
 
+  hair_dst->geometry.point_si

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list