Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2022-02-16 20:32:37 +0300
committerHans Goudey <h.goudey@me.com>2022-02-16 20:32:37 +0300
commitc324cf153924ae2ec5b7c59eabff71652847aeae (patch)
treef12f07ed61b018481e4bc45a7687567c48c952aa /source/blender/blenkernel/intern/curves.cc
parent5b73017ddb679bb050fe13e4d9e3e5b04ea559b9 (diff)
Curves: Further implementation of new curves data structure
The general idea here is to wrap the `CurvesGeometry` DNA struct with a C++ class that can do most of the heavy lifting for the curve geometry. Using a C++ class allows easier ways to group methods, easier const correctness, and code that's more readable and faster to write. This way, it works much more like a version of `CurveEval` that uses more efficient attribute storage. This commit adds the structure of some yet-to-be-implemented code, the largest thing being mutexes and vectors meant to hold lazily calculated evaluated positions, tangents, and normals. That part might change slightly, but it's helpful to be able to see the direction this commit is aiming in. In particular, the inherently single-threaded accumulated lengths and Bezier evaluated point offsets might be cached. Ref T95355 Differential Revision: https://developer.blender.org/D14054
Diffstat (limited to 'source/blender/blenkernel/intern/curves.cc')
-rw-r--r--source/blender/blenkernel/intern/curves.cc171
1 files changed, 66 insertions, 105 deletions
diff --git a/source/blender/blenkernel/intern/curves.cc b/source/blender/blenkernel/intern/curves.cc
index ccc20d5118a..e4a57ee1897 100644
--- a/source/blender/blenkernel/intern/curves.cc
+++ b/source/blender/blenkernel/intern/curves.cc
@@ -14,16 +14,18 @@
#include "DNA_material_types.h"
#include "DNA_object_types.h"
+#include "BLI_bounds.hh"
#include "BLI_index_range.hh"
#include "BLI_listbase.h"
#include "BLI_math_base.h"
#include "BLI_math_vector.hh"
#include "BLI_rand.hh"
+#include "BLI_span.hh"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BKE_anim_data.h"
-#include "BKE_curves.h"
+#include "BKE_curves.hh"
#include "BKE_customdata.h"
#include "BKE_global.h"
#include "BKE_idtype.h"
@@ -44,11 +46,12 @@ using blender::float3;
using blender::IndexRange;
using blender::MutableSpan;
using blender::RandomNumberGenerator;
+using blender::Span;
static const char *ATTR_POSITION = "position";
-static const char *ATTR_RADIUS = "radius";
static void curves_random(Curves *curves);
+static void update_custom_data_pointers(Curves &curves);
static void curves_init_data(ID *id)
{
@@ -57,50 +60,38 @@ static void curves_init_data(ID *id)
MEMCPY_STRUCT_AFTER(curves, DNA_struct_default_get(Curves), id);
- CustomData_reset(&curves->geometry.point_data);
- CustomData_reset(&curves->geometry.curve_data);
-
- CustomData_add_layer_named(&curves->geometry.point_data,
- CD_PROP_FLOAT3,
- CD_CALLOC,
- nullptr,
- curves->geometry.point_size,
- ATTR_POSITION);
- CustomData_add_layer_named(&curves->geometry.point_data,
- CD_PROP_FLOAT,
- CD_CALLOC,
- nullptr,
- curves->geometry.point_size,
- ATTR_RADIUS);
-
- BKE_curves_update_customdata_pointers(curves);
+ new (&curves->geometry) blender::bke::CurvesGeometry();
curves_random(curves);
}
static void curves_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
{
+ using namespace blender;
+
Curves *curves_dst = (Curves *)id_dst;
const Curves *curves_src = (const Curves *)id_src;
curves_dst->mat = static_cast<Material **>(MEM_dupallocN(curves_src->mat));
- curves_dst->geometry.point_size = curves_src->geometry.point_size;
- curves_dst->geometry.curve_size = curves_src->geometry.curve_size;
+ const bke::CurvesGeometry &src = bke::CurvesGeometry::wrap(curves_src->geometry);
+ bke::CurvesGeometry &dst = bke::CurvesGeometry::wrap(curves_dst->geometry);
+
+ /* We need special handling here because the generic ID management code has already done a
+ * shallow copy from the source to the destination, and because the copy-on-write functionality
+ * isn't supported more generically yet. */
+
+ dst.point_size = src.point_size;
+ dst.curve_size = src.curve_size;
const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE;
- CustomData_copy(&curves_src->geometry.point_data,
- &curves_dst->geometry.point_data,
- CD_MASK_ALL,
- alloc_type,
- curves_dst->geometry.point_size);
- CustomData_copy(&curves_src->geometry.curve_data,
- &curves_dst->geometry.curve_data,
- CD_MASK_ALL,
- alloc_type,
- curves_dst->geometry.curve_size);
- BKE_curves_update_customdata_pointers(curves_dst);
-
- curves_dst->geometry.offsets = static_cast<int *>(MEM_dupallocN(curves_src->geometry.offsets));
+ CustomData_copy(&src.point_data, &dst.point_data, CD_MASK_ALL, alloc_type, dst.point_size);
+ CustomData_copy(&src.curve_data, &dst.curve_data, CD_MASK_ALL, alloc_type, dst.curve_size);
+
+ dst.curve_offsets = static_cast<int *>(MEM_dupallocN(src.curve_offsets));
+
+ dst.runtime = MEM_new<bke::CurvesGeometryRuntime>(__func__);
+
+ dst.update_customdata_pointers();
curves_dst->batch_cache = nullptr;
}
@@ -110,12 +101,9 @@ static void curves_free_data(ID *id)
Curves *curves = (Curves *)id;
BKE_animdata_free(&curves->id, false);
- BKE_curves_batch_cache_free(curves);
-
- CustomData_free(&curves->geometry.point_data, curves->geometry.point_size);
- CustomData_free(&curves->geometry.curve_data, curves->geometry.curve_size);
+ blender::bke::CurvesGeometry::wrap(curves->geometry).~CurvesGeometry();
- MEM_SAFE_FREE(curves->geometry.offsets);
+ BKE_curves_batch_cache_free(curves);
MEM_SAFE_FREE(curves->mat);
}
@@ -157,7 +145,7 @@ static void curves_blend_write(BlendWriter *writer, ID *id, const void *id_addre
CD_MASK_ALL,
&curves->id);
- BLO_write_int32_array(writer, curves->geometry.curve_size + 1, curves->geometry.offsets);
+ BLO_write_int32_array(writer, curves->geometry.curve_size + 1, curves->geometry.curve_offsets);
BLO_write_pointer_array(writer, curves->totcol, curves->mat);
if (curves->adt) {
@@ -182,9 +170,11 @@ static void curves_blend_read_data(BlendDataReader *reader, ID *id)
/* Geometry */
CustomData_blend_read(reader, &curves->geometry.point_data, curves->geometry.point_size);
CustomData_blend_read(reader, &curves->geometry.curve_data, curves->geometry.curve_size);
- BKE_curves_update_customdata_pointers(curves);
+ update_custom_data_pointers(*curves);
+
+ BLO_read_int32_array(reader, curves->geometry.curve_size + 1, &curves->geometry.curve_offsets);
- BLO_read_int32_array(reader, curves->geometry.curve_size + 1, &curves->geometry.offsets);
+ curves->geometry.runtime = MEM_new<blender::bke::CurvesGeometryRuntime>(__func__);
/* Materials */
BLO_read_pointer_array(reader, (void **)&curves->mat);
@@ -236,34 +226,33 @@ IDTypeInfo IDType_ID_CV = {
/*lib_override_apply_post */ nullptr,
};
+static void update_custom_data_pointers(Curves &curves)
+{
+ blender::bke::CurvesGeometry::wrap(curves.geometry).update_customdata_pointers();
+}
+
static void curves_random(Curves *curves)
{
- CurvesGeometry &geometry = curves->geometry;
const int numpoints = 8;
- geometry.curve_size = 500;
-
- geometry.curve_size = 500;
- geometry.point_size = geometry.curve_size * numpoints;
+ blender::bke::CurvesGeometry &geometry = blender::bke::CurvesGeometry::wrap(curves->geometry);
+ geometry = blender::bke::CurvesGeometry(500 * numpoints, 500);
- curves->geometry.offsets = (int *)MEM_calloc_arrayN(
- curves->geometry.curve_size + 1, sizeof(int), __func__);
- CustomData_realloc(&geometry.point_data, geometry.point_size);
- CustomData_realloc(&geometry.curve_data, geometry.curve_size);
- BKE_curves_update_customdata_pointers(curves);
+ MutableSpan<int> offsets = geometry.offsets();
+ MutableSpan<float3> positions = geometry.positions();
- MutableSpan<int> offsets{geometry.offsets, geometry.curve_size + 1};
- MutableSpan<float3> positions{(float3 *)geometry.position, geometry.point_size};
- MutableSpan<float> radii{geometry.radius, geometry.point_size};
+ float *radius_data = (float *)CustomData_add_layer_named(
+ &geometry.point_data, CD_PROP_FLOAT, CD_DEFAULT, nullptr, geometry.point_size, "radius");
+ MutableSpan<float> radii{radius_data, geometry.points_size()};
for (const int i : offsets.index_range()) {
- geometry.offsets[i] = numpoints * i;
+ offsets[i] = numpoints * i;
}
RandomNumberGenerator rng;
for (int i = 0; i < geometry.curve_size; i++) {
- const IndexRange curve_range(offsets[i], offsets[i + 1] - offsets[i]);
+ const IndexRange curve_range = geometry.range_for_curve(i);
MutableSpan<float3> curve_positions = positions.slice(curve_range);
MutableSpan<float> curve_radii = radii.slice(curve_range);
@@ -304,18 +293,13 @@ BoundBox *BKE_curves_boundbox_get(Object *ob)
if (ob->runtime.bb == nullptr) {
ob->runtime.bb = MEM_cnew<BoundBox>(__func__);
- float min[3], max[3];
- INIT_MINMAX(min, max);
-
- float(*curves_co)[3] = curves->geometry.position;
- float *curves_radius = curves->geometry.radius;
- for (int a = 0; a < curves->geometry.point_size; a++) {
- float *co = curves_co[a];
- float radius = (curves_radius) ? curves_radius[a] : 0.0f;
- const float co_min[3] = {co[0] - radius, co[1] - radius, co[2] - radius};
- const float co_max[3] = {co[0] + radius, co[1] + radius, co[2] + radius};
- DO_MIN(co_min, min);
- DO_MAX(co_max, max);
+ blender::bke::CurvesGeometry &geometry = blender::bke::CurvesGeometry::wrap(curves->geometry);
+
+ float3 min(FLT_MAX);
+ float3 max(-FLT_MAX);
+ if (!geometry.bounds_min_max(min, max)) {
+ min = float3(-1);
+ max = float3(1);
}
BKE_boundbox_init_from_minmax(ob->runtime.bb, min, max);
@@ -324,46 +308,11 @@ BoundBox *BKE_curves_boundbox_get(Object *ob)
return ob->runtime.bb;
}
-void BKE_curves_update_customdata_pointers(Curves *curves)
-{
- curves->geometry.position = (float(*)[3])CustomData_get_layer_named(
- &curves->geometry.point_data, CD_PROP_FLOAT3, ATTR_POSITION);
- curves->geometry.radius = (float *)CustomData_get_layer_named(
- &curves->geometry.point_data, CD_PROP_FLOAT, ATTR_RADIUS);
-}
-
bool BKE_curves_customdata_required(Curves *UNUSED(curves), CustomDataLayer *layer)
{
return layer->type == CD_PROP_FLOAT3 && STREQ(layer->name, ATTR_POSITION);
}
-/* Dependency Graph */
-
-Curves *BKE_curves_new_for_eval(const Curves *curves_src, int totpoint, int totcurve)
-{
- Curves *curves_dst = static_cast<Curves *>(BKE_id_new_nomain(ID_CV, nullptr));
-
- STRNCPY(curves_dst->id.name, curves_src->id.name);
- curves_dst->mat = static_cast<Material **>(MEM_dupallocN(curves_src->mat));
- curves_dst->totcol = curves_src->totcol;
-
- curves_dst->geometry.point_size = totpoint;
- curves_dst->geometry.curve_size = totcurve;
- CustomData_copy(&curves_src->geometry.point_data,
- &curves_dst->geometry.point_data,
- CD_MASK_ALL,
- CD_CALLOC,
- totpoint);
- CustomData_copy(&curves_src->geometry.curve_data,
- &curves_dst->geometry.curve_data,
- CD_MASK_ALL,
- CD_CALLOC,
- totcurve);
- BKE_curves_update_customdata_pointers(curves_dst);
-
- return curves_dst;
-}
-
Curves *BKE_curves_copy_for_eval(Curves *curves_src, bool reference)
{
int flags = LIB_ID_COPY_LOCALIZE;
@@ -414,7 +363,7 @@ static Curves *curves_evaluate_modifiers(struct Depsgraph *depsgraph,
CD_PROP_FLOAT3,
ATTR_POSITION,
curves->geometry.point_size);
- BKE_curves_update_customdata_pointers(curves);
+ update_custom_data_pointers(*curves);
/* Created deformed coordinates array on demand. */
mti->deformVerts(
@@ -457,3 +406,15 @@ void BKE_curves_batch_cache_free(Curves *curves)
BKE_curves_batch_cache_free_cb(curves);
}
}
+
+namespace blender::bke {
+
+Curves *curves_new_nomain(const int point_size, const int curves_size)
+{
+ Curves *curves = static_cast<Curves *>(BKE_id_new_nomain(ID_CV, nullptr));
+ CurvesGeometry &geometry = CurvesGeometry::wrap(curves->geometry);
+ geometry.resize(point_size, curves_size);
+ return curves;
+}
+
+} // namespace blender::bke