diff --git a/source/blender/blenkernel/BKE_attribute_access.hh b/source/blender/blenkernel/BKE_attribute_access.hh index 564e912551a..eafd86d176b 100644 --- a/source/blender/blenkernel/BKE_attribute_access.hh +++ b/source/blender/blenkernel/BKE_attribute_access.hh @@ -264,9 +264,11 @@ template class TypedWriteAttribute { } }; +using BooleanReadAttribute = TypedReadAttribute; using FloatReadAttribute = TypedReadAttribute; using Float3ReadAttribute = TypedReadAttribute; using Color4fReadAttribute = TypedReadAttribute; +using BooleanWriteAttribute = TypedWriteAttribute; using FloatWriteAttribute = TypedWriteAttribute; using Float3WriteAttribute = TypedWriteAttribute; using Color4fWriteAttribute = TypedWriteAttribute; diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index 282e9bc2962..623335f65a1 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -392,6 +392,8 @@ const blender::fn::CPPType *custom_data_type_to_cpp_type(const CustomDataType ty return &CPPType::get(); case CD_PROP_COLOR: return &CPPType::get(); + case CD_PROP_BOOL: + return &CPPType::get(); default: return nullptr; } @@ -415,6 +417,9 @@ CustomDataType cpp_type_to_custom_data_type(const blender::fn::CPPType &type) if (type.is()) { return CD_PROP_COLOR; } + if (type.is()) { + return CD_PROP_BOOL; + } return static_cast(-1); } @@ -449,6 +454,9 @@ static ReadAttributePtr read_attribute_from_custom_data(const CustomData &custom case CD_PROP_COLOR: return std::make_unique>( domain, Span(static_cast(layer.data), size)); + case CD_PROP_BOOL: + return std::make_unique>( + domain, Span(static_cast(layer.data), size)); } } } @@ -490,6 +498,9 @@ static WriteAttributePtr write_attribute_from_custom_data( case CD_PROP_COLOR: return std::make_unique>( domain, MutableSpan(static_cast(layer.data), size)); + case CD_PROP_BOOL: + return std::make_unique>( + domain, MutableSpan(static_cast(layer.data), size)); } } } @@ -751,6 +762,7 @@ bool PointCloudComponent::attribute_domain_with_type_supported( const AttributeDomain domain, const CustomDataType data_type) const { return domain == ATTR_DOMAIN_POINT && ELEM(data_type, + CD_PROP_BOOL, CD_PROP_FLOAT, CD_PROP_FLOAT2, CD_PROP_FLOAT3, @@ -874,8 +886,13 @@ bool MeshComponent::attribute_domain_with_type_supported(const AttributeDomain d if (!this->attribute_domain_supported(domain)) { return false; } - return ELEM( - data_type, CD_PROP_FLOAT, CD_PROP_FLOAT2, CD_PROP_FLOAT3, CD_PROP_INT32, CD_PROP_COLOR); + return ELEM(data_type, + CD_PROP_BOOL, + CD_PROP_FLOAT, + CD_PROP_FLOAT2, + CD_PROP_FLOAT3, + CD_PROP_INT32, + CD_PROP_COLOR); } int MeshComponent::attribute_domain_size(const AttributeDomain domain) const diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index fdb3e246382..1e2bc570c65 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -1837,6 +1837,21 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { layerMultiply_propfloat2, NULL, layerAdd_propfloat2}, + /* 50: CD_PROP_POOL */ + {sizeof(bool), + "bool", + 1, + N_("Boolean"), + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL}, }; static const char *LAYERTYPENAMES[CD_NUMTYPES] = { @@ -1892,6 +1907,7 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = { "CDPropCol", "CDPropFloat3", "CDPropFloat2", + "CDPropBoolean", }; const CustomData_MeshMasks CD_MASK_BAREMESH = { diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index ae0bb20e529..832d55ea151 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -75,8 +75,7 @@ typedef struct CustomData { * MUST be >= CD_NUMTYPES, but we cant use a define here. * Correct size is ensured in CustomData_update_typemap assert(). */ - int typemap[50]; - char _pad[4]; + int typemap[51]; /** Number of layers, size of layers array. */ int totlayer, maxlayer; /** In editmode, total size of all data layers. */ @@ -156,7 +155,9 @@ typedef enum CustomDataType { CD_PROP_FLOAT3 = 48, CD_PROP_FLOAT2 = 49, - CD_NUMTYPES = 50, + CD_PROP_BOOL = 50, + + CD_NUMTYPES = 51, } CustomDataType; /* Bits for CustomDataMask */ @@ -208,6 +209,7 @@ typedef enum CustomDataType { #define CD_MASK_PROP_COLOR (1ULL << CD_PROP_COLOR) #define CD_MASK_PROP_FLOAT3 (1ULL << CD_PROP_FLOAT3) #define CD_MASK_PROP_FLOAT2 (1ULL << CD_PROP_FLOAT2) +#define CD_MASK_PROP_BOOL (1ULL << CD_PROP_BOOL) /** Multires loop data. */ #define CD_MASK_MULTIRES_GRIDS (CD_MASK_MDISPS | CD_GRID_PAINT_MASK) diff --git a/source/blender/makesrna/intern/rna_attribute.c b/source/blender/makesrna/intern/rna_attribute.c index 95f6340174a..f98ca47d767 100644 --- a/source/blender/makesrna/intern/rna_attribute.c +++ b/source/blender/makesrna/intern/rna_attribute.c @@ -44,6 +44,7 @@ const EnumPropertyItem rna_enum_attribute_type_items[] = { {CD_PROP_COLOR, "FLOAT_COLOR", 0, "Float Color", "RGBA color with floating-point precisions"}, {CD_MLOOPCOL, "BYTE_COLOR", 0, "Byte Color", "RGBA color with 8-bit precision"}, {CD_PROP_STRING, "STRING", 0, "String", "Text string"}, + {CD_PROP_BOOL, "BOOLEAN", 0, "Boolean", "True or false"}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 1731a42583b..4cd5b45ce78 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1890,7 +1890,7 @@ static const EnumPropertyItem *itemf_function_check( static bool attribute_random_type_supported(const EnumPropertyItem *item) { - return ELEM(item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3); + return ELEM(item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3, CD_PROP_BOOL); } static const EnumPropertyItem *rna_GeometryNodeAttributeRandom_type_itemf( bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) @@ -1912,7 +1912,7 @@ static const EnumPropertyItem *rna_GeometryNodeAttributeRandom_domain_itemf( static bool attribute_fill_type_supported(const EnumPropertyItem *item) { - return ELEM(item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3, CD_PROP_COLOR); + return ELEM(item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3, CD_PROP_COLOR, CD_PROP_BOOL); } static const EnumPropertyItem *rna_GeometryNodeAttributeFill_type_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh index 5fe554e0478..445e1ed6af2 100644 --- a/source/blender/nodes/NOD_geometry_exec.hh +++ b/source/blender/nodes/NOD_geometry_exec.hh @@ -26,6 +26,8 @@ namespace blender::nodes { +using bke::BooleanReadAttribute; +using bke::BooleanWriteAttribute; using bke::Color4fReadAttribute; using bke::Color4fWriteAttribute; using bke::Float3ReadAttribute; diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc index d3c7e86b708..5cdbd18ecc8 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc @@ -27,6 +27,7 @@ static bNodeSocketTemplate geo_node_attribute_fill_in[] = { {SOCK_VECTOR, N_("Value"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX}, {SOCK_FLOAT, N_("Value"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX}, {SOCK_RGBA, N_("Value"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX}, + {SOCK_BOOLEAN, N_("Value"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX}, {-1, ""}, }; @@ -45,12 +46,14 @@ static void geo_node_attribute_fill_update(bNodeTree *UNUSED(ntree), bNode *node bNodeSocket *socket_value_vector = (bNodeSocket *)BLI_findlink(&node->inputs, 2); bNodeSocket *socket_value_float = socket_value_vector->next; bNodeSocket *socket_value_color4f = socket_value_float->next; + bNodeSocket *socket_value_boolean = socket_value_color4f->next; const CustomDataType data_type = static_cast(node->custom1); nodeSetSocketAvailability(socket_value_vector, data_type == CD_PROP_FLOAT3); nodeSetSocketAvailability(socket_value_float, data_type == CD_PROP_FLOAT); nodeSetSocketAvailability(socket_value_color4f, data_type == CD_PROP_COLOR); + nodeSetSocketAvailability(socket_value_boolean, data_type == CD_PROP_BOOL); } namespace blender::nodes { @@ -96,6 +99,14 @@ static void fill_attribute(GeometryComponent &component, const GeoNodeExecParams color4f_attribute.apply_span(); break; } + case CD_PROP_BOOL: { + BooleanWriteAttribute boolean_attribute = std::move(attribute); + const bool value = params.get_input("Value_003"); + MutableSpan attribute_span = boolean_attribute.get_span(); + attribute_span.fill(value); + boolean_attribute.apply_span(); + break; + } default: break; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc index bde9a2a695e..53df2e8c087 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_randomize.cc @@ -59,6 +59,16 @@ static void geo_node_attribute_randomize_update(bNodeTree *UNUSED(ntree), bNode namespace blender::nodes { +static void randomize_attribute(BooleanWriteAttribute &attribute, RandomNumberGenerator &rng) +{ + MutableSpan attribute_span = attribute.get_span(); + for (const int i : IndexRange(attribute.size())) { + const bool value = rng.get_float() > 0.5f; + attribute_span[i] = value; + } + attribute.apply_span(); +} + static void randomize_attribute(FloatWriteAttribute &attribute, float min, float max, @@ -121,6 +131,11 @@ static void randomize_attribute(GeometryComponent &component, randomize_attribute(float3_attribute, min_value, max_value, rng); break; } + case CD_PROP_BOOL: { + BooleanWriteAttribute boolean_attribute = std::move(attribute); + randomize_attribute(boolean_attribute, rng); + break; + } default: break; } diff --git a/source/blender/nodes/intern/node_tree_multi_function.cc b/source/blender/nodes/intern/node_tree_multi_function.cc index ec5527a2970..2e4196af156 100644 --- a/source/blender/nodes/intern/node_tree_multi_function.cc +++ b/source/blender/nodes/intern/node_tree_multi_function.cc @@ -208,6 +208,10 @@ static DataTypeConversions create_implicit_conversions() conversions, "float to Color4f", [](float a) { return Color4f(a, a, a, 1.0f); }); add_implicit_conversion( conversions, "Color4f to float", [](Color4f a) { return rgb_to_grayscale(a); }); + add_implicit_conversion( + conversions, "float3 to boolean", [](float3 a) { return a.length_squared() == 0.0f; }); + add_implicit_conversion( + conversions, "boolean to float3", [](bool a) { return (a) ? float3(1.0f) : float3(0.0f); }); return conversions; }