Geometry Nodes: Add Offset Option to Set Postion
Add a boolean field to the Set Position Node. This value allows for each point to either have its position set to the input position value or have the input value added to the current position. Differential Revision: https://developer.blender.org/D12773
This commit is contained in:
@@ -23,14 +23,16 @@ namespace blender::nodes {
|
|||||||
static void geo_node_set_position_declare(NodeDeclarationBuilder &b)
|
static void geo_node_set_position_declare(NodeDeclarationBuilder &b)
|
||||||
{
|
{
|
||||||
b.add_input<decl::Geometry>("Geometry");
|
b.add_input<decl::Geometry>("Geometry");
|
||||||
b.add_input<decl::Vector>("Position").implicit_field();
|
|
||||||
b.add_input<decl::Bool>("Selection").default_value(true).hide_value().supports_field();
|
b.add_input<decl::Bool>("Selection").default_value(true).hide_value().supports_field();
|
||||||
|
b.add_input<decl::Vector>("Position").implicit_field();
|
||||||
|
b.add_input<decl::Bool>("Offset").default_value(false).supports_field();
|
||||||
b.add_output<decl::Geometry>("Geometry");
|
b.add_output<decl::Geometry>("Geometry");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_position_in_component(GeometryComponent &component,
|
static void set_position_in_component(GeometryComponent &component,
|
||||||
const Field<bool> &selection_field,
|
const Field<bool> &selection_field,
|
||||||
const Field<float3> &position_field)
|
const Field<float3> &position_field,
|
||||||
|
const Field<bool> &offset_field)
|
||||||
{
|
{
|
||||||
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
|
GeometryComponentFieldContext field_context{component, ATTR_DOMAIN_POINT};
|
||||||
const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
|
const int domain_size = component.attribute_domain_size(ATTR_DOMAIN_POINT);
|
||||||
@@ -45,9 +47,23 @@ static void set_position_in_component(GeometryComponent &component,
|
|||||||
|
|
||||||
OutputAttribute_Typed<float3> positions = component.attribute_try_get_for_output<float3>(
|
OutputAttribute_Typed<float3> positions = component.attribute_try_get_for_output<float3>(
|
||||||
"position", ATTR_DOMAIN_POINT, {0, 0, 0});
|
"position", ATTR_DOMAIN_POINT, {0, 0, 0});
|
||||||
|
MutableSpan<float3> position_mutable = positions.as_span();
|
||||||
|
|
||||||
fn::FieldEvaluator position_evaluator{field_context, &selection};
|
fn::FieldEvaluator position_evaluator{field_context, &selection};
|
||||||
position_evaluator.add_with_destination(position_field, positions.varray());
|
position_evaluator.add(position_field);
|
||||||
|
position_evaluator.add(offset_field);
|
||||||
position_evaluator.evaluate();
|
position_evaluator.evaluate();
|
||||||
|
|
||||||
|
/* TODO: We could have different code paths depending on whether the offset input is a single
|
||||||
|
* value or not */
|
||||||
|
|
||||||
|
const VArray<float3> &positions_input = position_evaluator.get_evaluated<float3>(0);
|
||||||
|
const VArray<bool> &offsets_input = position_evaluator.get_evaluated<bool>(1);
|
||||||
|
|
||||||
|
for (int i : selection) {
|
||||||
|
position_mutable[i] = offsets_input[i] ? position_mutable[i] + positions_input[i] :
|
||||||
|
positions_input[i];
|
||||||
|
}
|
||||||
positions.save();
|
positions.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,6 +71,7 @@ static void geo_node_set_position_exec(GeoNodeExecParams params)
|
|||||||
{
|
{
|
||||||
GeometrySet geometry = params.extract_input<GeometrySet>("Geometry");
|
GeometrySet geometry = params.extract_input<GeometrySet>("Geometry");
|
||||||
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
|
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
|
||||||
|
Field<bool> offset_field = params.extract_input<Field<bool>>("Offset");
|
||||||
Field<float3> position_field = params.extract_input<Field<float3>>("Position");
|
Field<float3> position_field = params.extract_input<Field<float3>>("Position");
|
||||||
|
|
||||||
for (const GeometryComponentType type : {GEO_COMPONENT_TYPE_MESH,
|
for (const GeometryComponentType type : {GEO_COMPONENT_TYPE_MESH,
|
||||||
@@ -63,7 +80,7 @@ static void geo_node_set_position_exec(GeoNodeExecParams params)
|
|||||||
GEO_COMPONENT_TYPE_INSTANCES}) {
|
GEO_COMPONENT_TYPE_INSTANCES}) {
|
||||||
if (geometry.has(type)) {
|
if (geometry.has(type)) {
|
||||||
set_position_in_component(
|
set_position_in_component(
|
||||||
geometry.get_component_for_write(type), selection_field, position_field);
|
geometry.get_component_for_write(type), selection_field, position_field, offset_field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user