Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/geometry/nodes/node_geo_attribute_mix.cc
| Show First 20 Lines • Show All 130 Lines • ▼ Show 20 Lines | static void do_mix_operation(const CustomDataType result_type, | ||||
| } | } | ||||
| } | } | ||||
| static void attribute_mix_calc(GeometryComponent &component, const GeoNodeExecParams ¶ms) | static void attribute_mix_calc(GeometryComponent &component, const GeoNodeExecParams ¶ms) | ||||
| { | { | ||||
| const bNode &node = params.node(); | const bNode &node = params.node(); | ||||
| const NodeAttributeMix *node_storage = (const NodeAttributeMix *)node.storage; | 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 | ||||
| AttributeDomain result_domain = ATTR_DOMAIN_POINT; | * 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), | |||||
| }); | |||||
HooglyBoogly: I have an alternate version of this patch that just takes the names and the component for… | |||||
JacquesLuckeUnsubmitted Not Done Inline ActionsCould also just use CD_PROP_FLOAT here, but either way is fine for me. JacquesLucke: Could also just use `CD_PROP_FLOAT` here, but either way is fine for me. | |||||
HooglyBooglyAuthorUnsubmitted Done Inline ActionsYeah, the result would be the same since that situation is completely trivial. I think if this is to become the "canonical" way of dealing with this then bool is a bit more clear on the intent. HooglyBoogly: Yeah, the result would be the same since that situation is completely trivial. I think if this… | |||||
| /* Use type and domain from the result attribute, if it exists already. */ | /* 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; | |||||
| const std::string result_name = params.get_input<std::string>("Result"); | const std::string result_name = params.get_input<std::string>("Result"); | ||||
| const ReadAttributePtr result_attribute_read = component.attribute_try_get_for_read(result_name); | const ReadAttributePtr result_attribute_read = component.attribute_try_get_for_read(result_name); | ||||
| if (result_attribute_read) { | if (result_attribute_read) { | ||||
| result_type = result_attribute_read->custom_data_type(); | |||||
| result_domain = result_attribute_read->domain(); | result_domain = result_attribute_read->domain(); | ||||
| } | } | ||||
| WriteAttributePtr attribute_result = component.attribute_try_ensure_for_write( | WriteAttributePtr attribute_result = component.attribute_try_ensure_for_write( | ||||
| result_name, result_domain, result_type); | result_name, result_domain, result_type); | ||||
| if (!attribute_result) { | if (!attribute_result) { | ||||
| return; | return; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 67 Lines • Show Last 20 Lines | |||||
I have an alternate version of this patch that just takes the names and the component for arguments and gives a result, but I actually prefer this version because it's more explicit.
Since there are only two examples of this sort of thing I'm not sure it's time for an abstraction yet anyway.