Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc
| Show First 20 Lines • Show All 119 Lines • ▼ Show 20 Lines | static void randomize_attribute(MutableSpan<T> span, | ||||
| const T max, | const T max, | ||||
| Span<uint32_t> ids, | Span<uint32_t> ids, | ||||
| const uint32_t seed, | const uint32_t seed, | ||||
| const GeometryNodeAttributeRandomizeMode operation) | const GeometryNodeAttributeRandomizeMode operation) | ||||
| { | { | ||||
| /* The operations could be templated too, but it doesn't make the code much shorter. */ | /* The operations could be templated too, but it doesn't make the code much shorter. */ | ||||
| switch (operation) { | switch (operation) { | ||||
| case GEO_NODE_ATTRIBUTE_RANDOMIZE_REPLACE_CREATE: | case GEO_NODE_ATTRIBUTE_RANDOMIZE_REPLACE_CREATE: | ||||
| for (const int i : span.index_range()) { | for (const int i : iter_indices(span)) { | ||||
| const T random_value = random_value_in_range<T>(ids[i], seed, min, max); | const T random_value = random_value_in_range<T>(ids[i], seed, min, max); | ||||
| span[i] = random_value; | span[i] = random_value; | ||||
| } | } | ||||
| break; | break; | ||||
| case GEO_NODE_ATTRIBUTE_RANDOMIZE_ADD: | case GEO_NODE_ATTRIBUTE_RANDOMIZE_ADD: | ||||
| for (const int i : span.index_range()) { | for (const int i : iter_indices(span)) { | ||||
| const T random_value = random_value_in_range<T>(ids[i], seed, min, max); | const T random_value = random_value_in_range<T>(ids[i], seed, min, max); | ||||
| span[i] = span[i] + random_value; | span[i] = span[i] + random_value; | ||||
| } | } | ||||
| break; | break; | ||||
| case GEO_NODE_ATTRIBUTE_RANDOMIZE_SUBTRACT: | case GEO_NODE_ATTRIBUTE_RANDOMIZE_SUBTRACT: | ||||
| for (const int i : span.index_range()) { | for (const int i : iter_indices(span)) { | ||||
| const T random_value = random_value_in_range<T>(ids[i], seed, min, max); | const T random_value = random_value_in_range<T>(ids[i], seed, min, max); | ||||
| span[i] = span[i] - random_value; | span[i] = span[i] - random_value; | ||||
| } | } | ||||
| break; | break; | ||||
| case GEO_NODE_ATTRIBUTE_RANDOMIZE_MULTIPLY: | case GEO_NODE_ATTRIBUTE_RANDOMIZE_MULTIPLY: | ||||
| for (const int i : span.index_range()) { | for (const int i : iter_indices(span)) { | ||||
| const T random_value = random_value_in_range<T>(ids[i], seed, min, max); | const T random_value = random_value_in_range<T>(ids[i], seed, min, max); | ||||
| span[i] = span[i] * random_value; | span[i] = span[i] * random_value; | ||||
| } | } | ||||
| break; | break; | ||||
| default: | default: | ||||
| BLI_assert(false); | BLI_assert(false); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| static void randomize_attribute_bool(MutableSpan<bool> span, | static void randomize_attribute_bool(MutableSpan<bool> span, | ||||
| Span<uint32_t> ids, | Span<uint32_t> ids, | ||||
| const uint32_t seed, | const uint32_t seed, | ||||
| const GeometryNodeAttributeRandomizeMode operation) | const GeometryNodeAttributeRandomizeMode operation) | ||||
| { | { | ||||
| BLI_assert(operation == GEO_NODE_ATTRIBUTE_RANDOMIZE_REPLACE_CREATE); | BLI_assert(operation == GEO_NODE_ATTRIBUTE_RANDOMIZE_REPLACE_CREATE); | ||||
| UNUSED_VARS_NDEBUG(operation); | UNUSED_VARS_NDEBUG(operation); | ||||
| for (const int i : span.index_range()) { | for (const int i : iter_indices(span)) { | ||||
| const bool random_value = BLI_hash_int_2d_to_float(ids[i], seed) > 0.5f; | const bool random_value = BLI_hash_int_2d_to_float(ids[i], seed) > 0.5f; | ||||
| span[i] = random_value; | span[i] = random_value; | ||||
| } | } | ||||
| } | } | ||||
| Array<uint32_t> get_geometry_element_ids_as_uints(const GeometryComponent &component, | Array<uint32_t> get_geometry_element_ids_as_uints(const GeometryComponent &component, | ||||
| const AttributeDomain domain) | const AttributeDomain domain) | ||||
| { | { | ||||
| const int domain_size = component.attribute_domain_size(domain); | const int domain_size = component.attribute_domain_size(domain); | ||||
| /* Hash the reserved name attribute "id" as a (hopefully) stable seed for each point. */ | /* Hash the reserved name attribute "id" as a (hopefully) stable seed for each point. */ | ||||
| GVArrayPtr hash_attribute = component.attribute_try_get_for_read("id", domain); | GVArrayPtr hash_attribute = component.attribute_try_get_for_read("id", domain); | ||||
| Array<uint32_t> hashes(domain_size); | Array<uint32_t> hashes(domain_size); | ||||
| if (hash_attribute) { | if (hash_attribute) { | ||||
| BLI_assert(hashes.size() == hash_attribute->size()); | BLI_assert(hashes.size() == hash_attribute->size()); | ||||
| const CPPType &cpp_type = hash_attribute->type(); | const CPPType &cpp_type = hash_attribute->type(); | ||||
| GVArray_GSpan items{*hash_attribute}; | GVArray_GSpan items{*hash_attribute}; | ||||
| for (const int i : hashes.index_range()) { | for (const int i : iter_indices(hashes)) { | ||||
| hashes[i] = cpp_type.hash(items[i]); | hashes[i] = cpp_type.hash(items[i]); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* If there is no "id" attribute for per-point variation, just create it here. */ | /* If there is no "id" attribute for per-point variation, just create it here. */ | ||||
| RandomNumberGenerator rng(0); | RandomNumberGenerator rng(0); | ||||
| for (const int i : hashes.index_range()) { | for (const int i : iter_indices(hashes)) { | ||||
| hashes[i] = rng.get_uint32(); | hashes[i] = rng.get_uint32(); | ||||
| } | } | ||||
| } | } | ||||
| return hashes; | return hashes; | ||||
| } | } | ||||
| static AttributeDomain get_result_domain(const GeometryComponent &component, | static AttributeDomain get_result_domain(const GeometryComponent &component, | ||||
| ▲ Show 20 Lines • Show All 129 Lines • Show Last 20 Lines | |||||