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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/geometry_component_mesh.cc167
1 files changed, 167 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc
index 31809b1ffec..53defc89b7e 100644
--- a/source/blender/blenkernel/intern/geometry_component_mesh.cc
+++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc
@@ -256,6 +256,157 @@ static ReadAttributePtr adapt_mesh_domain_point_to_corner(const Mesh &mesh,
return new_attribute;
}
+/**
+ * \note Theoretically this interpolation does not need to compute all values at once.
+ * However, doing that makes the implementation simpler, and this can be optimized in the future if
+ * only some values are required.
+ */
+template<typename T>
+static void adapt_mesh_domain_corner_to_polygon_impl(const Mesh &mesh,
+ Span<T> old_values,
+ MutableSpan<T> r_values)
+{
+ BLI_assert(r_values.size() == mesh.totpoly);
+ attribute_math::DefaultMixer<T> mixer(r_values);
+
+ for (const int poly_index : IndexRange(mesh.totpoly)) {
+ const MPoly &poly = mesh.mpoly[poly_index];
+ for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
+ const T value = old_values[loop_index];
+ mixer.mix_in(poly_index, value);
+ }
+ }
+
+ mixer.finalize();
+}
+
+static ReadAttributePtr adapt_mesh_domain_corner_to_polygon(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);
+ if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
+ Array<T> values(mesh.totpoly);
+ adapt_mesh_domain_corner_to_polygon_impl<T>(mesh, attribute->get_span<T>(), values);
+ new_attribute = std::make_unique<OwnedArrayReadAttribute<T>>(ATTR_DOMAIN_POINT,
+ std::move(values));
+ }
+ });
+ return new_attribute;
+}
+
+template<typename T>
+void adapt_mesh_domain_polygon_to_point_impl(const Mesh &mesh,
+ Span<T> old_values,
+ MutableSpan<T> r_values)
+{
+ BLI_assert(r_values.size() == mesh.totvert);
+ attribute_math::DefaultMixer<T> mixer(r_values);
+
+ for (const int poly_index : IndexRange(mesh.totpoly)) {
+ const MPoly &poly = mesh.mpoly[poly_index];
+ const T value = old_values[poly_index];
+ for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
+ const MLoop &loop = mesh.mloop[loop_index];
+ const int point_index = loop.v;
+ mixer.mix_in(point_index, value);
+ }
+ }
+
+ mixer.finalize();
+}
+
+static ReadAttributePtr adapt_mesh_domain_polygon_to_point(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);
+ if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
+ Array<T> values(mesh.totvert);
+ adapt_mesh_domain_polygon_to_point_impl<T>(mesh, attribute->get_span<T>(), values);
+ new_attribute = std::make_unique<OwnedArrayReadAttribute<T>>(ATTR_DOMAIN_POINT,
+ std::move(values));
+ }
+ });
+ return new_attribute;
+}
+
+template<typename T>
+void adapt_mesh_domain_polygon_to_corner_impl(const Mesh &mesh,
+ const Span<T> old_values,
+ MutableSpan<T> r_values)
+{
+ BLI_assert(r_values.size() == mesh.totloop);
+
+ for (const int poly_index : IndexRange(mesh.totpoly)) {
+ const MPoly &poly = mesh.mpoly[poly_index];
+ MutableSpan<T> poly_corner_values = r_values.slice(poly.loopstart, poly.totloop);
+ poly_corner_values.fill(old_values[poly_index]);
+ }
+}
+
+static ReadAttributePtr adapt_mesh_domain_polygon_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);
+ if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
+ Array<T> values(mesh.totloop);
+ adapt_mesh_domain_polygon_to_corner_impl<T>(mesh, attribute->get_span<T>(), values);
+ new_attribute = std::make_unique<OwnedArrayReadAttribute<T>>(ATTR_DOMAIN_POINT,
+ std::move(values));
+ }
+ });
+ return new_attribute;
+}
+
+/**
+ * \note Theoretically this interpolation does not need to compute all values at once.
+ * However, doing that makes the implementation simpler, and this can be optimized in the future if
+ * only some values are required.
+ */
+template<typename T>
+static void adapt_mesh_domain_point_to_polygon_impl(const Mesh &mesh,
+ const Span<T> old_values,
+ MutableSpan<T> r_values)
+{
+ BLI_assert(r_values.size() == mesh.totpoly);
+ attribute_math::DefaultMixer<T> mixer(r_values);
+
+ for (const int poly_index : IndexRange(mesh.totpoly)) {
+ const MPoly &poly = mesh.mpoly[poly_index];
+ for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
+ MLoop &loop = mesh.mloop[loop_index];
+ const int point_index = loop.v;
+ mixer.mix_in(poly_index, old_values[point_index]);
+ }
+ }
+ mixer.finalize();
+}
+
+static ReadAttributePtr adapt_mesh_domain_point_to_polygon(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);
+ if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
+ Array<T> values(mesh.totpoly);
+ adapt_mesh_domain_point_to_polygon_impl<T>(mesh, attribute->get_span<T>(), values);
+ new_attribute = std::make_unique<OwnedArrayReadAttribute<T>>(ATTR_DOMAIN_POINT,
+ std::move(values));
+ }
+ });
+ return new_attribute;
+}
+
} // namespace blender::bke
ReadAttributePtr MeshComponent::attribute_try_adapt_domain(ReadAttributePtr attribute,
@@ -277,6 +428,8 @@ ReadAttributePtr MeshComponent::attribute_try_adapt_domain(ReadAttributePtr attr
switch (new_domain) {
case ATTR_DOMAIN_POINT:
return blender::bke::adapt_mesh_domain_corner_to_point(*mesh_, std::move(attribute));
+ case ATTR_DOMAIN_POLYGON:
+ return blender::bke::adapt_mesh_domain_corner_to_polygon(*mesh_, std::move(attribute));
default:
break;
}
@@ -286,9 +439,23 @@ ReadAttributePtr MeshComponent::attribute_try_adapt_domain(ReadAttributePtr attr
switch (new_domain) {
case ATTR_DOMAIN_CORNER:
return blender::bke::adapt_mesh_domain_point_to_corner(*mesh_, std::move(attribute));
+ case ATTR_DOMAIN_POLYGON:
+ return blender::bke::adapt_mesh_domain_point_to_polygon(*mesh_, std::move(attribute));
+ default:
+ break;
+ }
+ break;
+ }
+ case ATTR_DOMAIN_POLYGON: {
+ switch (new_domain) {
+ case ATTR_DOMAIN_POINT:
+ return blender::bke::adapt_mesh_domain_polygon_to_point(*mesh_, std::move(attribute));
+ case ATTR_DOMAIN_CORNER:
+ return blender::bke::adapt_mesh_domain_polygon_to_corner(*mesh_, std::move(attribute));
default:
break;
}
+ break;
}
default:
break;