Parallelize remesh reprojects

Differential Revision: https://developer.blender.org/D15638
This commit is contained in:
Erik Abrahamsson 2022-08-06 09:30:33 +02:00
parent e441e21d74
commit 34009dfb23
Notes: blender-bot 2023-02-14 08:06:33 +01:00
Referenced by commit 341e9f7a7c, Revert "Parallelize remesh reprojects"
1 changed files with 83 additions and 69 deletions

View File

@ -19,6 +19,7 @@
#include "BLI_math_vec_types.hh"
#include "BLI_math_vector.h"
#include "BLI_span.hh"
#include "BLI_task.hh"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@ -299,17 +300,20 @@ void BKE_mesh_remesh_reproject_paint_mask(Mesh *target, Mesh *source)
&source->vdata, CD_PAINT_MASK, CD_CALLOC, nullptr, source->totvert);
}
for (int i = 0; i < target->totvert; i++) {
float from_co[3];
BVHTreeNearest nearest;
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
copy_v3_v3(from_co, target_verts[i].co);
BLI_bvhtree_find_nearest(bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree);
if (nearest.index != -1) {
target_mask[i] = source_mask[nearest.index];
blender::threading::parallel_for(IndexRange(target->totvert), 4096, [&](const IndexRange range) {
for (const int i : range) {
float from_co[3];
BVHTreeNearest nearest;
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
copy_v3_v3(from_co, target_verts[i].co);
BLI_bvhtree_find_nearest(
bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree);
if (nearest.index != -1) {
target_mask[i] = source_mask[nearest.index];
}
}
}
});
free_bvhtree_from_mesh(&bvhtree);
}
@ -342,21 +346,24 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, Mesh *source)
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(source);
BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_LOOPTRI, 2);
for (int i = 0; i < target->totpoly; i++) {
float from_co[3];
BVHTreeNearest nearest;
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
const MPoly *mpoly = &target_polys[i];
BKE_mesh_calc_poly_center(mpoly, &target_loops[mpoly->loopstart], target_verts, from_co);
BLI_bvhtree_find_nearest(bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree);
if (nearest.index != -1) {
target_face_sets[i] = source_face_sets[looptri[nearest.index].poly];
blender::threading::parallel_for(IndexRange(target->totpoly), 2048, [&](const IndexRange range) {
for (const int i : range) {
float from_co[3];
BVHTreeNearest nearest;
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
const MPoly *mpoly = &target_polys[i];
BKE_mesh_calc_poly_center(mpoly, &target_loops[mpoly->loopstart], target_verts, from_co);
BLI_bvhtree_find_nearest(
bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree);
if (nearest.index != -1) {
target_face_sets[i] = source_face_sets[looptri[nearest.index].poly];
}
else {
target_face_sets[i] = 1;
}
}
else {
target_face_sets[i] = 1;
}
}
});
free_bvhtree_from_mesh(&bvhtree);
}
@ -396,19 +403,22 @@ void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source)
MVert *target_verts = (MVert *)CustomData_get_layer(&target->vdata, CD_MVERT);
if (domain == ATTR_DOMAIN_POINT) {
for (int i = 0; i < target->totvert; i++) {
BVHTreeNearest nearest;
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
BLI_bvhtree_find_nearest(
bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree);
blender::threading::parallel_for(
IndexRange(target->totvert), 4096, [&](const IndexRange range) {
for (const int i : range) {
BVHTreeNearest nearest;
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
BLI_bvhtree_find_nearest(
bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree);
if (nearest.index != -1) {
memcpy(POINTER_OFFSET(target_data, (size_t)i * data_size),
POINTER_OFFSET(source_data, (size_t)nearest.index * data_size),
data_size);
}
}
if (nearest.index != -1) {
memcpy(POINTER_OFFSET(target_data, (size_t)i * data_size),
POINTER_OFFSET(source_data, (size_t)nearest.index * data_size),
data_size);
}
}
});
}
else {
/* Lazily init vertex -> loop maps. */
@ -435,46 +445,50 @@ void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source)
target->totloop);
}
for (int i = 0; i < target->totvert; i++) {
BVHTreeNearest nearest;
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
BLI_bvhtree_find_nearest(
bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree);
blender::threading::parallel_for(
IndexRange(target->totvert), 2048, [&](const IndexRange range) {
for (const int i : range) {
BVHTreeNearest nearest;
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
BLI_bvhtree_find_nearest(
bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree);
if (nearest.index == -1) {
continue;
}
if (nearest.index == -1) {
continue;
}
MeshElemMap *source_loops = source_lmap + nearest.index;
MeshElemMap *target_loops = target_lmap + i;
MeshElemMap *source_loops = source_lmap + nearest.index;
MeshElemMap *target_loops = target_lmap + i;
if (target_loops->count == 0 || source_loops->count == 0) {
continue;
}
if (target_loops->count == 0 || source_loops->count == 0) {
continue;
}
/*
* Average color data for loops around the source vertex into
* the first target loop around the target vertex
*/
/*
* Average color data for loops around the source vertex into
* the first target loop around the target vertex
*/
CustomData_interp(source_cdata,
target_cdata,
source_loops->indices,
nullptr,
nullptr,
source_loops->count,
target_loops->indices[0]);
CustomData_interp(source_cdata,
target_cdata,
source_loops->indices,
nullptr,
nullptr,
source_loops->count,
target_loops->indices[0]);
void *elem = POINTER_OFFSET(target_data, (size_t)target_loops->indices[0] * data_size);
void *elem = POINTER_OFFSET(target_data,
(size_t)target_loops->indices[0] * data_size);
/* Copy to rest of target loops. */
for (int j = 1; j < target_loops->count; j++) {
memcpy(POINTER_OFFSET(target_data, (size_t)target_loops->indices[j] * data_size),
elem,
data_size);
}
}
/* Copy to rest of target loops. */
for (int j = 1; j < target_loops->count; j++) {
memcpy(POINTER_OFFSET(target_data, (size_t)target_loops->indices[j] * data_size),
elem,
data_size);
}
}
});
}
}