diff options
author | Hans Goudey <h.goudey@me.com> | 2022-02-03 19:49:51 +0300 |
---|---|---|
committer | Fabian Schempp <fabianschempp@googlemail.com> | 2022-04-11 01:28:52 +0300 |
commit | 33946e3548fb1a57e1870626b5af973712266661 (patch) | |
tree | efc07a7a6cab294ed50f631f11cebf263d390e22 /source/blender/blenkernel/intern | |
parent | 787021d38a08ec6e557f2091367b676cc087765a (diff) |
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
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/attribute.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/customdata.cc | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/hair.cc | 152 |
3 files changed, 114 insertions, 54 deletions
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_size = hair_src->geometry.point_size; + hair_dst->geometry.curve_size = hair_src->geometry.curve_size; + const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE; - CustomData_copy(&hair_src->pdata, &hair_dst->pdata, CD_MASK_ALL, alloc_type, hair_dst->totpoint); - CustomData_copy(&hair_src->cdata, &hair_dst->cdata, CD_MASK_ALL, alloc_type, hair_dst->totcurve); + CustomData_copy(&hair_src->geometry.point_data, + &hair_dst->geometry.point_data, + CD_MASK_ALL, + alloc_type, + hair_dst->geometry.point_size); + CustomData_copy(&hair_src->geometry.curve_data, + &hair_dst->geometry.curve_data, + CD_MASK_ALL, + alloc_type, + hair_dst->geometry.curve_size); BKE_hair_update_customdata_pointers(hair_dst); + hair_dst->geometry.offsets = static_cast<int *>(MEM_dupallocN(hair_src->geometry.offsets)); + hair_dst->batch_cache = nullptr; } @@ -104,8 +128,10 @@ static void hair_free_data(ID *id) BKE_hair_batch_cache_free(hair); - CustomData_free(&hair->pdata, hair->totpoint); - CustomData_free(&hair->cdata, hair->totcurve); + CustomData_free(&hair->geometry.point_data, hair->geometry.point_size); + CustomData_free(&hair->geometry.curve_data, hair->geometry.curve_size); + + MEM_SAFE_FREE(hair->geometry.offsets); MEM_SAFE_FREE(hair->mat); } @@ -124,16 +150,30 @@ static void hair_blend_write(BlendWriter *writer, ID *id, const void *id_address CustomDataLayer *players = nullptr, players_buff[CD_TEMP_CHUNK_SIZE]; CustomDataLayer *clayers = nullptr, clayers_buff[CD_TEMP_CHUNK_SIZE]; - CustomData_blend_write_prepare(&hair->pdata, &players, players_buff, ARRAY_SIZE(players_buff)); - CustomData_blend_write_prepare(&hair->cdata, &clayers, clayers_buff, ARRAY_SIZE(clayers_buff)); + CustomData_blend_write_prepare( + &hair->geometry.point_data, &players, players_buff, ARRAY_SIZE(players_buff)); + CustomData_blend_write_prepare( + &hair->geometry.curve_data, &clayers, clayers_buff, ARRAY_SIZE(clayers_buff)); /* Write LibData */ BLO_write_id_struct(writer, Hair, id_address, &hair->id); BKE_id_blend_write(writer, &hair->id); /* Direct data */ - CustomData_blend_write(writer, &hair->pdata, players, hair->totpoint, CD_MASK_ALL, &hair->id); - CustomData_blend_write(writer, &hair->cdata, clayers, hair->totcurve, CD_MASK_ALL, &hair->id); + CustomData_blend_write(writer, + &hair->geometry.point_data, + players, + hair->geometry.point_size, + CD_MASK_ALL, + &hair->id); + CustomData_blend_write(writer, + &hair->geometry.curve_data, + clayers, + hair->geometry.curve_size, + CD_MASK_ALL, + &hair->id); + + BLO_write_int32_array(writer, hair->geometry.curve_size + 1, hair->geometry.offsets); BLO_write_pointer_array(writer, hair->totcol, hair->mat); if (hair->adt) { @@ -156,10 +196,12 @@ static void hair_blend_read_data(BlendDataReader *reader, ID *id) BKE_animdata_blend_read_data(reader, hair->adt); /* Geometry */ - CustomData_blend_read(reader, &hair->pdata, hair->totpoint); - CustomData_blend_read(reader, &hair->cdata, hair->totcurve); + CustomData_blend_read(reader, &hair->geometry.point_data, hair->geometry.point_size); + CustomData_blend_read(reader, &hair->geometry.curve_data, hair->geometry.point_size); BKE_hair_update_customdata_pointers(hair); + BLO_read_int32_array(reader, hair->geometry.curve_size + 1, &hair->geometry.offsets); + /* Materials */ BLO_read_pointer_array(reader, (void **)&hair->mat); } @@ -212,38 +254,48 @@ IDTypeInfo IDType_ID_HA = { static void hair_random(Hair *hair) { + CurvesGeometry &geometry = hair->geometry; const int numpoints = 8; - hair->totcurve = 500; - hair->totpoint = hair->totcurve * numpoints; + geometry.curve_size = 500; + + geometry.curve_size = 500; + geometry.point_size = geometry.curve_size * numpoints; - CustomData_realloc(&hair->pdata, hair->totpoint); - CustomData_realloc(&hair->cdata, hair->totcurve); + hair->geometry.offsets = (int *)MEM_calloc_arrayN( + hair->geometry.curve_size + 1, sizeof(int), __func__); + CustomData_realloc(&geometry.point_data, geometry.point_size); + CustomData_realloc(&geometry.curve_data, geometry.curve_size); BKE_hair_update_customdata_pointers(hair); + 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}; + + for (const int i : offsets.index_range()) { + geometry.offsets[i] = numpoints * i; + } + RandomNumberGenerator rng; - for (int i = 0; i < hair->totcurve; i++) { - HairCurve *curve = &hair->curves[i]; - curve->firstpoint = i * numpoints; - curve->numpoints = numpoints; + for (int i = 0; i < geometry.curve_size; i++) { + const IndexRange curve_range(offsets[i], offsets[i + 1] - offsets[i]); + MutableSpan<float3> curve_positions = positions.slice(curve_range); + MutableSpan<float> curve_radii = radii.slice(curve_range); const float theta = 2.0f * M_PI * rng.get_float(); const float phi = saacosf(2.0f * rng.get_float() - 1.0f); float3 no = {std::sin(theta) * std::sin(phi), std::cos(theta) * std::sin(phi), std::cos(phi)}; - blender::math::normalize(no); + no = blender::math::normalize(no); - float(*curve_positions)[3] = hair->co + curve->firstpoint; - float *curve_radii = hair->radius + curve->firstpoint; float3 co = no; for (int key = 0; key < numpoints; key++) { float t = key / (float)(numpoints - 1); - copy_v3_v3(curve_positions[key], co); + curve_positions[key] = co; curve_radii[key] = 0.02f * (1.0f - t); float3 offset = float3(rng.get_float(), rng.get_float(), rng.get_float()) * 2.0f - 1.0f; - co += (offset + no) / numpoints; } } @@ -271,9 +323,9 @@ BoundBox *BKE_hair_boundbox_get(Object *ob) float min[3], max[3]; INIT_MINMAX(min, max); - float(*hair_co)[3] = hair->co; - float *hair_radius = hair->radius; - for (int a = 0; a < hair->totpoint; a++) { + float(*hair_co)[3] = hair->geometry.position; + float *hair_radius = hair->geometry.radius; + for (int a = 0; a < hair->geometry.point_size; a++) { float *co = hair_co[a]; float radius = (hair_radius) ? hair_radius[a] : 0.0f; const float co_min[3] = {co[0] - radius, co[1] - radius, co[2] - radius}; @@ -290,12 +342,10 @@ BoundBox *BKE_hair_boundbox_get(Object *ob) void BKE_hair_update_customdata_pointers(Hair *hair) { - hair->co = (float(*)[3])CustomData_get_layer_named( - &hair->pdata, CD_PROP_FLOAT3, HAIR_ATTR_POSITION); - hair->radius = (float *)CustomData_get_layer_named( - &hair->pdata, CD_PROP_FLOAT, HAIR_ATTR_RADIUS); - hair->curves = (HairCurve *)CustomData_get_layer(&hair->cdata, CD_HAIRCURVE); - hair->mapping = (HairMaping *)CustomData_get_layer(&hair->cdata, CD_HAIRMAPPING); + hair->geometry.position = (float(*)[3])CustomData_get_layer_named( + &hair->geometry.point_data, CD_PROP_FLOAT3, HAIR_ATTR_POSITION); + hair->geometry.radius = (float *)CustomData_get_layer_named( + &hair->geometry.point_data, CD_PROP_FLOAT, HAIR_ATTR_RADIUS); } bool BKE_hair_customdata_required(Hair *UNUSED(hair), CustomDataLayer *layer) @@ -313,10 +363,18 @@ Hair *BKE_hair_new_for_eval(const Hair *hair_src, int totpoint, int totcurve) hair_dst->mat = static_cast<Material **>(MEM_dupallocN(hair_src->mat)); hair_dst->totcol = hair_src->totcol; - hair_dst->totpoint = totpoint; - hair_dst->totcurve = totcurve; - CustomData_copy(&hair_src->pdata, &hair_dst->pdata, CD_MASK_ALL, CD_CALLOC, totpoint); - CustomData_copy(&hair_src->cdata, &hair_dst->cdata, CD_MASK_ALL, CD_CALLOC, totcurve); + hair_dst->geometry.point_size = totpoint; + hair_dst->geometry.curve_size = totcurve; + CustomData_copy(&hair_src->geometry.point_data, + &hair_dst->geometry.point_data, + CD_MASK_ALL, + CD_CALLOC, + totpoint); + CustomData_copy(&hair_src->geometry.curve_data, + &hair_dst->geometry.curve_data, + CD_MASK_ALL, + CD_CALLOC, + totcurve); BKE_hair_update_customdata_pointers(hair_dst); return hair_dst; @@ -368,12 +426,14 @@ static Hair *hair_evaluate_modifiers(struct Depsgraph *depsgraph, } /* Ensure we are not overwriting referenced data. */ - CustomData_duplicate_referenced_layer_named( - &hair->pdata, CD_PROP_FLOAT3, HAIR_ATTR_POSITION, hair->totpoint); + CustomData_duplicate_referenced_layer_named(&hair->geometry.point_data, + CD_PROP_FLOAT3, + HAIR_ATTR_POSITION, + hair->geometry.point_size); BKE_hair_update_customdata_pointers(hair); /* Created deformed coordinates array on demand. */ - mti->deformVerts(md, &mectx, nullptr, hair->co, hair->totpoint); + mti->deformVerts(md, &mectx, nullptr, hair->geometry.position, hair->geometry.point_size); } } |