From 719bea0d6d06be579edee2fc3d12a7828bb8e101 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 12 Jan 2021 14:03:35 -0600 Subject: Geometry Nodes: Output the most complex attribute data type In order to avoid losing information, it sometimes makes sense for the output attribute type to depend on the types of the input attributes. Such a function already exists, `attribute_data_type_highest_complexity`, it just needs to be used in a few more places. The change for the attribute compare node is just so the code there uses the same code style as in the attribute mix node. Addresses part of T83793 Differential Revision: https://developer.blender.org/D10099 --- .../nodes/geometry/nodes/node_geo_attribute_color_ramp.cc | 6 ++++-- .../nodes/geometry/nodes/node_geo_attribute_compare.cc | 10 ++++------ .../nodes/geometry/nodes/node_geo_attribute_mix.cc | 15 +++++++++++---- 3 files changed, 19 insertions(+), 12 deletions(-) (limited to 'source/blender/nodes') diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc index 8a96a6ea866..7d49253c6a3 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_color_ramp.cc @@ -37,12 +37,14 @@ static void execute_on_component(const GeoNodeExecParams ¶ms, GeometryCompon const bNode &bnode = params.node(); NodeAttributeColorRamp *node_storage = (NodeAttributeColorRamp *)bnode.storage; + /* Use the type of the input attribute, but create a color attribute if it doesn't exist yet. */ + const CustomDataType result_type = params.get_input_attribute_data_type( + "Attribute", component, CD_PROP_COLOR); + const std::string result_name = params.get_input("Result"); /* Once we support more domains at the user level, we have to decide how the result domain is * chosen. */ const AttributeDomain result_domain = ATTR_DOMAIN_POINT; - const CustomDataType result_type = CD_PROP_COLOR; - WriteAttributePtr attribute_result = component.attribute_try_ensure_for_write( result_name, result_domain, result_type); if (!attribute_result) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc index f1a71e7a642..5d6e2412a3d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_compare.cc @@ -216,14 +216,12 @@ static CustomDataType get_data_type(GeometryComponent &component, const NodeAttributeCompare &node_storage) { if (operation_tests_equality(node_storage)) { - CustomDataType data_type_a = params.get_input_attribute_data_type( - "A", component, CD_PROP_FLOAT); - CustomDataType data_type_b = params.get_input_attribute_data_type( - "B", component, CD_PROP_FLOAT); - /* Convert the input attributes to the same data type for the equality tests. Use the higher * complexity attribute type, otherwise information necessary to the comparison may be lost. */ - return attribute_data_type_highest_complexity({data_type_a, data_type_b}); + return attribute_data_type_highest_complexity({ + params.get_input_attribute_data_type("A", component, CD_PROP_FLOAT), + params.get_input_attribute_data_type("B", component, CD_PROP_FLOAT), + }); } /* Use float compare for every operation besides equality. */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc index 3d3a72dd910..9a780e1212b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc @@ -136,14 +136,21 @@ static void attribute_mix_calc(GeometryComponent &component, const GeoNodeExecPa const bNode &node = params.node(); const NodeAttributeMix *node_storage = (const NodeAttributeMix *)node.storage; - CustomDataType result_type = CD_PROP_COLOR; + /* Use the highest complexity data type among the inputs and outputs, that way the node will + * never "remove information". Use CD_PROP_BOOL as the lowest complexity data type, but in any + * real situation it won't be returned. */ + const CustomDataType result_type = attribute_data_type_highest_complexity({ + params.get_input_attribute_data_type("A", component, CD_PROP_BOOL), + params.get_input_attribute_data_type("B", component, CD_PROP_BOOL), + params.get_input_attribute_data_type("Result", component, CD_PROP_BOOL), + }); + + /* Once we support more domains at the user level, we have to decide how the result domain is + * chosen. */ AttributeDomain result_domain = ATTR_DOMAIN_POINT; - - /* Use type and domain from the result attribute, if it exists already. */ const std::string result_name = params.get_input("Result"); const ReadAttributePtr result_attribute_read = component.attribute_try_get_for_read(result_name); if (result_attribute_read) { - result_type = result_attribute_read->custom_data_type(); result_domain = result_attribute_read->domain(); } -- cgit v1.2.3