Geometry Nodes: Boolean attribute type
This adds a boolean attribute and custom data type, to be used in the point separate node. It also adds it as supported data types in the random attribute and attribute fill nodes. There are more clever ways of storing a boolean attribute that make more sense in certain situations-- sets, bitfields, and others, this commit keeps it simple, saving those changes for when there is a proper use case for them. In any case, we will still probably always want the idea of a boolean attribute. Differential Revision: https://developer.blender.org/D9818
This commit is contained in:
parent
c06c5d617a
commit
c484b54453
Notes:
blender-bot
2023-02-14 05:43:04 +01:00
Referenced by commitcd29d76ab6
, Cleanup: typo inc484b54453
|
@ -264,9 +264,11 @@ template<typename T> class TypedWriteAttribute {
|
|||
}
|
||||
};
|
||||
|
||||
using BooleanReadAttribute = TypedReadAttribute<bool>;
|
||||
using FloatReadAttribute = TypedReadAttribute<float>;
|
||||
using Float3ReadAttribute = TypedReadAttribute<float3>;
|
||||
using Color4fReadAttribute = TypedReadAttribute<Color4f>;
|
||||
using BooleanWriteAttribute = TypedWriteAttribute<bool>;
|
||||
using FloatWriteAttribute = TypedWriteAttribute<float>;
|
||||
using Float3WriteAttribute = TypedWriteAttribute<float3>;
|
||||
using Color4fWriteAttribute = TypedWriteAttribute<Color4f>;
|
||||
|
|
|
@ -392,6 +392,8 @@ const blender::fn::CPPType *custom_data_type_to_cpp_type(const CustomDataType ty
|
|||
return &CPPType::get<int>();
|
||||
case CD_PROP_COLOR:
|
||||
return &CPPType::get<Color4f>();
|
||||
case CD_PROP_BOOL:
|
||||
return &CPPType::get<bool>();
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -415,6 +417,9 @@ CustomDataType cpp_type_to_custom_data_type(const blender::fn::CPPType &type)
|
|||
if (type.is<Color4f>()) {
|
||||
return CD_PROP_COLOR;
|
||||
}
|
||||
if (type.is<bool>()) {
|
||||
return CD_PROP_BOOL;
|
||||
}
|
||||
return static_cast<CustomDataType>(-1);
|
||||
}
|
||||
|
||||
|
@ -449,6 +454,9 @@ static ReadAttributePtr read_attribute_from_custom_data(const CustomData &custom
|
|||
case CD_PROP_COLOR:
|
||||
return std::make_unique<ArrayReadAttribute<Color4f>>(
|
||||
domain, Span(static_cast<Color4f *>(layer.data), size));
|
||||
case CD_PROP_BOOL:
|
||||
return std::make_unique<ArrayReadAttribute<bool>>(
|
||||
domain, Span(static_cast<bool *>(layer.data), size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -490,6 +498,9 @@ static WriteAttributePtr write_attribute_from_custom_data(
|
|||
case CD_PROP_COLOR:
|
||||
return std::make_unique<ArrayWriteAttribute<Color4f>>(
|
||||
domain, MutableSpan(static_cast<Color4f *>(layer.data), size));
|
||||
case CD_PROP_BOOL:
|
||||
return std::make_unique<ArrayWriteAttribute<bool>>(
|
||||
domain, MutableSpan(static_cast<bool *>(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
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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},
|
||||
};
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
namespace blender::nodes {
|
||||
|
||||
using bke::BooleanReadAttribute;
|
||||
using bke::BooleanWriteAttribute;
|
||||
using bke::Color4fReadAttribute;
|
||||
using bke::Color4fWriteAttribute;
|
||||
using bke::Float3ReadAttribute;
|
||||
|
|
|
@ -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<CustomDataType>(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<bool>("Value_003");
|
||||
MutableSpan<bool> attribute_span = boolean_attribute.get_span();
|
||||
attribute_span.fill(value);
|
||||
boolean_attribute.apply_span();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -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<bool> 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;
|
||||
}
|
||||
|
|
|
@ -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<Color4f, float>(
|
||||
conversions, "Color4f to float", [](Color4f a) { return rgb_to_grayscale(a); });
|
||||
add_implicit_conversion<float3, bool>(
|
||||
conversions, "float3 to boolean", [](float3 a) { return a.length_squared() == 0.0f; });
|
||||
add_implicit_conversion<bool, float3>(
|
||||
conversions, "boolean to float3", [](bool a) { return (a) ? float3(1.0f) : float3(0.0f); });
|
||||
return conversions;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue