[Bf-blender-cvs] [bf85e6a6371] functions: improve grouping of similar indices
Jacques Lucke
noreply at git.blender.org
Wed Dec 11 14:26:40 CET 2019
Commit: bf85e6a63714a15a34491439f0e07970b90f63a0
Author: Jacques Lucke
Date: Wed Dec 11 13:53:53 2019 +0100
Branches: functions
https://developer.blender.org/rBbf85e6a63714a15a34491439f0e07970b90f63a0
improve grouping of similar indices
===================================================================
M source/blender/blenlib/BLI_array_ref.h
M source/blender/functions/intern/multi_functions/mixed.cc
===================================================================
diff --git a/source/blender/blenlib/BLI_array_ref.h b/source/blender/blenlib/BLI_array_ref.h
index 56e3ade2d0c..53769d02e81 100644
--- a/source/blender/blenlib/BLI_array_ref.h
+++ b/source/blender/blenlib/BLI_array_ref.h
@@ -295,6 +295,16 @@ template<typename T> class ArrayRef {
return -1;
}
+ template<typename PredicateT> bool any(const PredicateT predicate)
+ {
+ for (uint i = 0; i < m_size; i++) {
+ if (predicate(m_start[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Utility to make it more convenient to iterate over all indices that can be used with this
* array.
diff --git a/source/blender/functions/intern/multi_functions/mixed.cc b/source/blender/functions/intern/multi_functions/mixed.cc
index 30a4261d85b..a9b228cd6b5 100644
--- a/source/blender/functions/intern/multi_functions/mixed.cc
+++ b/source/blender/functions/intern/multi_functions/mixed.cc
@@ -480,6 +480,34 @@ MF_GetImageColorOnSurface::MF_GetImageColorOnSurface()
this->set_signature(signature);
}
+template<typename T, typename FuncT, typename EqualFuncT = std::equal_to<T>>
+void group_indices_by_same_value(ArrayRef<uint> indices,
+ VirtualListRef<T> values,
+ const FuncT &func,
+ EqualFuncT equal = std::equal_to<T>())
+{
+ Vector<T> seen_values;
+
+ for (uint i : indices.index_iterator()) {
+ uint index = indices[i];
+
+ const T &value = values[index];
+ if (seen_values.as_ref().any([&](const T &seen_value) { return equal(value, seen_value); })) {
+ continue;
+ }
+ seen_values.append(value);
+
+ TemporaryVector<uint> indices_with_value;
+ for (uint j : indices.drop_front(i)) {
+ if (equal(values[j], value)) {
+ indices_with_value.append(j);
+ }
+ }
+
+ func(value, indices_with_value.as_ref());
+ }
+}
+
static void get_colors_on_surface(ArrayRef<uint> indices,
VirtualListRef<SurfaceHook> surface_hooks,
MutableArrayRef<rgba_f> r_colors,
@@ -487,51 +515,68 @@ static void get_colors_on_surface(ArrayRef<uint> indices,
const IDHandleLookup &id_handle_lookup,
const ImBuf &ibuf)
{
+ group_indices_by_same_value(
+ indices,
+ surface_hooks,
+ [&](SurfaceHook base_hook, ArrayRef<uint> indices_with_similar_hook) {
+ if (base_hook.type() != BKE::SurfaceHookType::MeshObject) {
+ r_colors.fill_indices(indices_with_similar_hook, fallback);
+ return;
+ }
- for (uint i : indices) {
- SurfaceHook hook = surface_hooks[i];
- if (hook.type() != BKE::SurfaceHookType::MeshObject) {
- r_colors[i] = fallback;
- continue;
- }
+ Object *object = id_handle_lookup.lookup(base_hook.object_handle());
+ if (object == nullptr) {
+ r_colors.fill_indices(indices_with_similar_hook, fallback);
+ return;
+ }
- Object *object = id_handle_lookup.lookup(hook.object_handle());
- if (object == nullptr) {
- r_colors[i] = fallback;
- continue;
- }
+ Mesh *mesh = (Mesh *)object->data;
+ const MLoopTri *triangles = BKE_mesh_runtime_looptri_ensure(mesh);
+ int triangle_amount = BKE_mesh_runtime_looptri_len(mesh);
- Mesh *mesh = (Mesh *)object->data;
- const MLoopTri *triangles = BKE_mesh_runtime_looptri_ensure(mesh);
- int triangle_amount = BKE_mesh_runtime_looptri_len(mesh);
+ int uv_layer_index = 0;
+ ArrayRef<MLoopUV> uv_layer = BLI::ref_c_array(
+ (MLoopUV *)CustomData_get_layer_n(&mesh->ldata, CD_MLOOPUV, uv_layer_index),
+ mesh->totloop);
- if (hook.triangle_index() >= triangle_amount) {
- r_colors[i] = fallback;
- continue;
- }
-
- int uv_layer_index = 0;
- ArrayRef<MLoopUV> uv_layer = BLI::ref_c_array(
- (MLoopUV *)CustomData_get_layer_n(&mesh->ldata, CD_MLOOPUV, uv_layer_index),
- mesh->totloop);
+ ArrayRef<rgba_b> pixel_buffer = BLI::ref_c_array((rgba_b *)ibuf.rect, ibuf.x * ibuf.y);
- ArrayRef<rgba_b> pixel_buffer = BLI::ref_c_array((rgba_b *)ibuf.rect, ibuf.x * ibuf.y);
+ for (uint i : indices_with_similar_hook) {
+ SurfaceHook hook = surface_hooks[i];
+ if (hook.triangle_index() >= triangle_amount) {
+ r_colors[i] = fallback;
+ continue;
+ }
- const MLoopTri &triangle = triangles[hook.triangle_index()];
+ const MLoopTri &triangle = triangles[hook.triangle_index()];
- float2 uv1 = uv_layer[triangle.tri[0]].uv;
- float2 uv2 = uv_layer[triangle.tri[1]].uv;
- float2 uv3 = uv_layer[triangle.tri[2]].uv;
+ float2 uv1 = uv_layer[triangle.tri[0]].uv;
+ float2 uv2 = uv_layer[triangle.tri[1]].uv;
+ float2 uv3 = uv_layer[triangle.tri[2]].uv;
- float2 uv;
- interp_v2_v2v2v2(uv, uv1, uv2, uv3, hook.bary_coords());
+ float2 uv;
+ interp_v2_v2v2v2(uv, uv1, uv2, uv3, hook.bary_coords());
- uv = uv.clamped_01();
- uint x = uv.x * (ibuf.x - 1);
- uint y = uv.y * (ibuf.y - 1);
- rgba_b color = pixel_buffer[y * ibuf.x + x];
- r_colors[i] = color;
- }
+ uv = uv.clamped_01();
+ uint x = uv.x * (ibuf.x - 1);
+ uint y = uv.y * (ibuf.y - 1);
+ rgba_b color = pixel_buffer[y * ibuf.x + x];
+ r_colors[i] = color;
+ }
+ },
+ [](const SurfaceHook &a, const SurfaceHook &b) {
+ if (a.type() != b.type()) {
+ return false;
+ }
+ switch (a.type()) {
+ case BKE::SurfaceHookType::MeshObject:
+ return a.object_handle() == b.object_handle();
+ case BKE::SurfaceHookType::None:
+ return true;
+ }
+ BLI_assert(false);
+ return false;
+ });
}
void MF_GetImageColorOnSurface::call(MFMask mask, MFParams params, MFContext context) const
@@ -554,39 +599,25 @@ void MF_GetImageColorOnSurface::call(MFMask mask, MFParams params, MFContext con
return;
}
- Vector<ImageIDHandle> seen_images;
-
- for (uint i = 0; i < mask.indices_amount(); i++) {
- uint index = mask.indices()[i];
-
- ImageIDHandle image_handle = image_handles[index];
- if (seen_images.contains(image_handle)) {
- continue;
- }
- seen_images.append(image_handle);
-
- TemporaryVector<uint> indices_with_image;
- for (uint j : mask.indices().drop_front(i)) {
- if (image_handles[j] == image_handle) {
- indices_with_image.append(j);
- }
- }
-
- Image *image = id_handle_lookup->lookup(image_handle);
- if (image == nullptr) {
- r_colors.fill_indices(indices_with_image, fallback);
- continue;
- }
+ group_indices_by_same_value<ImageIDHandle>(
+ mask.indices(),
+ image_handles,
+ [&](ImageIDHandle image_handle, ArrayRef<uint> indices_with_image) {
+ Image *image = id_handle_lookup->lookup(image_handle);
+ if (image == nullptr) {
+ r_colors.fill_indices(indices_with_image, fallback);
+ return;
+ }
- ImageUser image_user = {0};
- image_user.ok = true;
- ImBuf *ibuf = BKE_image_acquire_ibuf(image, &image_user, NULL);
+ ImageUser image_user = {0};
+ image_user.ok = true;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, &image_user, NULL);
- get_colors_on_surface(
- indices_with_image, surface_hooks, r_colors, fallback, *id_handle_lookup, *ibuf);
+ get_colors_on_surface(
+ indices_with_image, surface_hooks, r_colors, fallback, *id_handle_lookup, *ibuf);
- BKE_image_release_ibuf(image, ibuf, NULL);
- }
+ BKE_image_release_ibuf(image, ibuf, NULL);
+ });
}
MF_ObjectWorldLocation::MF_ObjectWorldLocation()
More information about the Bf-blender-cvs
mailing list