Geometry Nodes: Allow float input for point scale node

This allows easily changing the scale attribute with a uniform scale
within a single simple node.
This commit is contained in:
Hans Goudey 2021-04-02 12:03:27 -05:00
parent bd9c479475
commit 0e8fa1d44b
2 changed files with 32 additions and 5 deletions

View File

@ -453,6 +453,12 @@ static const EnumPropertyItem rna_node_geometry_attribute_input_type_items_vecto
ITEM_VECTOR,
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem rna_node_geometry_attribute_input_type_items_float_vector[] = {
ITEM_ATTRIBUTE,
ITEM_FLOAT,
ITEM_VECTOR,
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem rna_node_geometry_attribute_input_type_items_float[] = {
ITEM_ATTRIBUTE,
ITEM_FLOAT,
@ -9277,7 +9283,7 @@ static void def_geo_point_scale(StructRNA *srna)
RNA_def_struct_sdna_from(srna, "NodeGeometryPointScale", "storage");
prop = RNA_def_property(srna, "input_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_vector);
RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_float_vector);
RNA_def_property_ui_text(prop, "Input Type", "");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}

View File

@ -25,6 +25,7 @@ static bNodeSocketTemplate geo_node_point_scale_in[] = {
{SOCK_GEOMETRY, N_("Geometry")},
{SOCK_STRING, N_("Factor")},
{SOCK_VECTOR, N_("Factor"), 1.0f, 1.0f, 1.0f, 1.0f, -FLT_MAX, FLT_MAX, PROP_XYZ},
{SOCK_FLOAT, N_("Factor"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX},
{-1, ""},
};
@ -44,22 +45,42 @@ namespace blender::nodes {
static void execute_on_component(GeoNodeExecParams params, GeometryComponent &component)
{
/* Note that scale doesn't necessarily need to be created with a vector type-- it could also use
* the highest complexity of the existing attribute's type (if it exists) and the data type used
* for the factor. But for it's simpler to simply always use float3, since that is usually
* expected anyway. */
static const float3 scale_default = float3(1.0f);
OutputAttributePtr scale_attribute = component.attribute_try_get_for_output(
"scale", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, &scale_default);
if (!scale_attribute) {
return;
}
const bNode &node = params.node();
const NodeGeometryPointScale &node_storage = *(const NodeGeometryPointScale *)node.storage;
const GeometryNodeAttributeInputMode input_type = (GeometryNodeAttributeInputMode)
node_storage.input_type;
const CustomDataType data_type = (input_type == GEO_NODE_ATTRIBUTE_INPUT_FLOAT) ? CD_PROP_FLOAT :
CD_PROP_FLOAT3;
ReadAttributePtr attribute = params.get_input_attribute(
"Factor", component, ATTR_DOMAIN_POINT, CD_PROP_FLOAT3, nullptr);
"Factor", component, ATTR_DOMAIN_POINT, data_type, nullptr);
if (!attribute) {
return;
}
Span<float3> data = attribute->get_span<float3>();
MutableSpan<float3> scale_span = scale_attribute->get_span<float3>();
for (const int i : scale_span.index_range()) {
scale_span[i] = scale_span[i] * data[i];
if (data_type == CD_PROP_FLOAT) {
Span<float> factors = attribute->get_span<float>();
for (const int i : scale_span.index_range()) {
scale_span[i] = scale_span[i] * factors[i];
}
}
else if (data_type == CD_PROP_FLOAT3) {
Span<float3> factors = attribute->get_span<float3>();
for (const int i : scale_span.index_range()) {
scale_span[i] = scale_span[i] * factors[i];
}
}
scale_attribute.apply_span_and_save();