Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2021-02-18 13:03:38 +0300
committerJacques Lucke <jacques@blender.org>2021-02-18 13:03:38 +0300
commit72e2b5060dcc164b05a6d204824e6f94834ca100 (patch)
tree7962b24933246d936822b75004aa2d508d4c2e3d /source/blender/blenkernel/intern/attribute_access.cc
parente3f0b6d5cbe5d34ac43568090c52a84dc51e579e (diff)
Geometry Nodes: support adapting point to corner domain
This allows accessing per-point attributes on the corner domain, which can be useful e.g. when adding per-point displacement to per-corner uv coordinates. Also it is required to make an upcoming patch work well, that makes the Point Distribute node use density weights per corner instead of per point, giving the user more precise control over the distribution.
Diffstat (limited to 'source/blender/blenkernel/intern/attribute_access.cc')
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc46
1 files changed, 43 insertions, 3 deletions
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index 87f7df84eab..dcf5f6434cf 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -2009,9 +2009,9 @@ int MeshComponent::attribute_domain_size(const AttributeDomain domain) const
namespace blender::bke {
template<typename T>
-void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh,
- const TypedReadAttribute<T> &attribute,
- MutableSpan<T> r_values)
+static void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh,
+ const TypedReadAttribute<T> &attribute,
+ MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totvert);
attribute_math::DefaultMixer<T> mixer(r_values);
@@ -2044,6 +2044,38 @@ static ReadAttributePtr adapt_mesh_domain_corner_to_point(const Mesh &mesh,
return new_attribute;
}
+template<typename T>
+static void adapt_mesh_domain_point_to_corner_impl(const Mesh &mesh,
+ const TypedReadAttribute<T> &attribute,
+ MutableSpan<T> r_values)
+{
+ BLI_assert(r_values.size() == mesh.totloop);
+
+ for (const int loop_index : IndexRange(mesh.totloop)) {
+ const int vertex_index = mesh.mloop[loop_index].v;
+ r_values[loop_index] = attribute[vertex_index];
+ }
+}
+
+static ReadAttributePtr adapt_mesh_domain_point_to_corner(const Mesh &mesh,
+ ReadAttributePtr attribute)
+{
+ ReadAttributePtr new_attribute;
+ const CustomDataType data_type = attribute->custom_data_type();
+ attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
+ using T = decltype(dummy);
+ /* It is not strictly necessary to compute the value for all corners here. Instead one could
+ * lazily lookup the mesh topology when a specific index accessed. This can be more efficient
+ * when an algorithm only accesses very few of the corner values. However, for the algorithms
+ * we currently have, precomputing the array is fine. Also, it is easier to implement. */
+ Array<T> values(mesh.totloop);
+ adapt_mesh_domain_point_to_corner_impl<T>(mesh, *attribute, values);
+ new_attribute = std::make_unique<OwnedArrayReadAttribute<T>>(ATTR_DOMAIN_CORNER,
+ std::move(values));
+ });
+ return new_attribute;
+}
+
} // namespace blender::bke
ReadAttributePtr MeshComponent::attribute_try_adapt_domain(ReadAttributePtr attribute,
@@ -2070,6 +2102,14 @@ ReadAttributePtr MeshComponent::attribute_try_adapt_domain(ReadAttributePtr attr
}
break;
}
+ case ATTR_DOMAIN_POINT: {
+ switch (new_domain) {
+ case ATTR_DOMAIN_CORNER:
+ return blender::bke::adapt_mesh_domain_point_to_corner(*mesh_, std::move(attribute));
+ default:
+ break;
+ }
+ }
default:
break;
}