Revert "Multires: Simplify grids normals update and grid to face map"

This reverts commit c97178fa2e.

This was committed to main by mistake, it was meant for a local branch.
This commit is contained in:
Hans Goudey
2023-08-12 16:37:02 -04:00
parent d38a0cf537
commit b04a72866d
7 changed files with 240 additions and 118 deletions
+3 -6
View File
@@ -14,7 +14,6 @@
#include "BLI_bitmap.h"
#include "BLI_compiler_compat.h"
#include "BLI_ghash.h"
#include "BLI_index_mask.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_offset_indices.hh"
#include "BLI_vector.hh"
@@ -211,7 +210,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
CCGElem **grids,
int totgrid,
CCGKey *key,
blender::Span<int> gridfaces,
void **gridfaces,
DMFlagMat *flagmats,
unsigned int **grid_hidden,
Mesh *me,
@@ -444,12 +443,10 @@ void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flags);
void BKE_pbvh_update_visibility(PBVH *pbvh);
void BKE_pbvh_update_normals(PBVH *pbvh, SubdivCCG *subdiv_ccg);
void BKE_pbvh_redraw_BB(PBVH *pbvh, float bb_min[3], float bb_max[3]);
blender::IndexMask BKE_pbvh_get_grid_updates(const PBVH *pbvh,
blender::Span<const PBVHNode *> nodes,
blender::IndexMaskMemory &memory);
void BKE_pbvh_get_grid_updates(PBVH *pbvh, bool clear, void ***r_gridfaces, int *r_totface);
void BKE_pbvh_grids_update(PBVH *pbvh,
CCGElem **grids,
blender::Span<int> gridfaces,
void **gridfaces,
DMFlagMat *flagmats,
unsigned int **grid_hidden,
CCGKey *key);
+6 -4
View File
@@ -8,7 +8,6 @@
#pragma once
#include "BLI_array.hh"
#include "BLI_bitmap.h"
#include "BLI_offset_indices.hh"
#include "BLI_sys_types.h"
@@ -160,7 +159,7 @@ struct SubdivCCG {
int num_faces;
SubdivCCGFace *faces;
/* Indexed by grid index, points to corresponding face from `faces`. */
blender::Array<int> grid_faces;
SubdivCCGFace **grid_faces;
/* Edges which are adjacent to faces.
* Used for faster grid stitching, in the cost of extra memory.
@@ -236,14 +235,17 @@ void BKE_subdiv_ccg_key_top_level(CCGKey *key, const SubdivCCG *subdiv_ccg);
void BKE_subdiv_ccg_recalc_normals(SubdivCCG *subdiv_ccg);
/* Update normals of affected faces. */
void BKE_subdiv_ccg_update_normals(SubdivCCG *subdiv_ccg, const blender::IndexMask &face_mask);
void BKE_subdiv_ccg_update_normals(SubdivCCG *subdiv_ccg,
CCGFace **effected_faces,
int num_effected_faces);
/* Average grid coordinates and normals along the grid boundaries. */
void BKE_subdiv_ccg_average_grids(SubdivCCG *subdiv_ccg);
/* Similar to above, but only updates given faces. */
void BKE_subdiv_ccg_average_stitch_faces(SubdivCCG *subdiv_ccg,
const blender::IndexMask &face_mask);
CCGFace **effected_faces,
int num_effected_faces);
/* Get geometry counters at the current subdivision level. */
void BKE_subdiv_ccg_topology_counters(const SubdivCCG *subdiv_ccg,
+6 -5
View File
@@ -1226,11 +1226,12 @@ void multires_stitch_grids(Object *ob)
/* NOTE: Currently CCG does not keep track of faces, making it impossible
* to use BKE_pbvh_get_grid_updates().
*/
blender::IndexMaskMemory memory;
blender::Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr);
const blender::IndexMask mask = BKE_pbvh_get_grid_updates(pbvh, nodes, memory);
if (!mask.is_empty()) {
BKE_subdiv_ccg_average_stitch_faces(subdiv_ccg, mask);
CCGFace **faces;
int num_faces;
BKE_pbvh_get_grid_updates(pbvh, false, (void ***)&faces, &num_faces);
if (num_faces) {
BKE_subdiv_ccg_average_stitch_faces(subdiv_ccg, faces, num_faces);
MEM_freeN(faces);
}
}
+2 -2
View File
@@ -2260,7 +2260,7 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg)
subdiv_ccg->grids,
subdiv_ccg->num_grids,
&key,
subdiv_ccg->grid_faces,
(void **)subdiv_ccg->grid_faces,
subdiv_ccg->grid_flag_mats,
subdiv_ccg->grid_hidden,
base_mesh,
@@ -2349,7 +2349,7 @@ void BKE_sculpt_bvh_update_from_ccg(PBVH *pbvh, SubdivCCG *subdiv_ccg)
BKE_pbvh_grids_update(pbvh,
subdiv_ccg->grids,
subdiv_ccg->grid_faces,
(void **)subdiv_ccg->grid_faces,
subdiv_ccg->grid_flag_mats,
subdiv_ccg->grid_hidden,
&key);
+47 -19
View File
@@ -927,7 +927,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
CCGElem **grids,
int totgrid,
CCGKey *key,
blender::Span<int> gridfaces,
void **gridfaces,
DMFlagMat *flagmats,
BLI_bitmap **grid_hidden,
Mesh *me,
@@ -1742,21 +1742,49 @@ void BKE_pbvh_redraw_BB(PBVH *pbvh, float bb_min[3], float bb_max[3])
copy_v3_v3(bb_max, bb.bmax);
}
blender::IndexMask BKE_pbvh_get_grid_updates(const PBVH *pbvh,
const Span<const PBVHNode *> nodes,
blender::IndexMaskMemory &memory)
void BKE_pbvh_get_grid_updates(PBVH *pbvh, bool clear, void ***r_gridfaces, int *r_totface)
{
using namespace blender;
Array<bool> faces_to_update(pbvh->faces_num, false);
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (const PBVHNode *node : nodes.slice(range)) {
GSet *face_set = BLI_gset_ptr_new(__func__);
PBVHNode *node;
PBVHIter iter;
pbvh_iter_begin(&iter, pbvh, nullptr, nullptr);
while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) {
if (node->flag & PBVH_UpdateNormals) {
for (const int grid : node->prim_indices) {
const int face = pbvh->gridfaces[grid];
faces_to_update[face] = true;
void *face = pbvh->gridfaces[grid];
BLI_gset_add(face_set, face);
}
if (clear) {
node->flag &= ~PBVH_UpdateNormals;
}
}
}
});
return IndexMask::from_bools(faces_to_update, memory);
pbvh_iter_end(&iter);
const int tot = BLI_gset_len(face_set);
if (tot == 0) {
*r_totface = 0;
*r_gridfaces = nullptr;
BLI_gset_free(face_set, nullptr);
return;
}
void **faces = static_cast<void **>(MEM_mallocN(sizeof(*faces) * tot, __func__));
GSetIterator gs_iter;
int i;
GSET_ITER_INDEX (gs_iter, face_set, i) {
faces[i] = BLI_gsetIterator_getKey(&gs_iter);
}
BLI_gset_free(face_set, nullptr);
*r_totface = tot;
*r_gridfaces = faces;
}
/***************************** PBVH Access ***********************************/
@@ -2817,7 +2845,6 @@ bool BKE_pbvh_node_frustum_exclude_AABB(PBVHNode *node, void *data)
void BKE_pbvh_update_normals(PBVH *pbvh, SubdivCCG *subdiv_ccg)
{
using namespace blender;
/* Update normals */
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(
pbvh, update_search_cb, POINTER_FROM_INT(PBVH_UpdateNormals));
@@ -2830,11 +2857,12 @@ void BKE_pbvh_update_normals(PBVH *pbvh, SubdivCCG *subdiv_ccg)
pbvh_faces_update_normals(pbvh, nodes);
}
else if (pbvh->header.type == PBVH_GRIDS) {
IndexMaskMemory memory;
const IndexMask faces_to_update = BKE_pbvh_get_grid_updates(pbvh, nodes, memory);
BKE_subdiv_ccg_update_normals(subdiv_ccg, faces_to_update);
for (PBVHNode *node : nodes) {
node->flag &= ~PBVH_UpdateNormals;
CCGFace **faces;
int num_faces;
BKE_pbvh_get_grid_updates(pbvh, true, (void ***)&faces, &num_faces);
if (num_faces > 0) {
BKE_subdiv_ccg_update_normals(subdiv_ccg, faces, num_faces);
MEM_freeN(faces);
}
}
}
@@ -2953,7 +2981,7 @@ void BKE_pbvh_draw_debug_cb(PBVH *pbvh,
void BKE_pbvh_grids_update(PBVH *pbvh,
CCGElem **grids,
blender::Span<int> gridfaces,
void **gridfaces,
DMFlagMat *flagmats,
BLI_bitmap **grid_hidden,
CCGKey *key)
@@ -176,7 +176,7 @@ struct PBVH {
/* Grid Data */
CCGKey gridkey;
CCGElem **grids;
blender::Span<int> gridfaces;
void **gridfaces;
const DMFlagMat *grid_flag_mats;
int totgrid;
BLI_bitmap **grid_hidden;
+175 -81
View File
@@ -13,7 +13,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_enumerable_thread_specific.hh"
#include "BLI_ghash.h"
#include "BLI_math_bits.h"
#include "BLI_math_geom.h"
@@ -41,7 +40,8 @@ static void subdiv_ccg_average_inner_face_grids(SubdivCCG *subdiv_ccg,
void subdiv_ccg_average_faces_boundaries_and_corners(SubdivCCG *subdiv_ccg,
CCGKey *key,
const blender::IndexMask &face_mask);
CCGFace **effected_faces,
int num_effected_faces);
/** \} */
@@ -152,7 +152,8 @@ static void subdiv_ccg_alloc_elements(SubdivCCG *subdiv_ccg, Subdiv *subdiv)
if (num_faces) {
subdiv_ccg->faces = static_cast<SubdivCCGFace *>(
MEM_calloc_arrayN(num_faces, sizeof(SubdivCCGFace), "Subdiv CCG faces"));
subdiv_ccg->grid_faces.reinitialize(num_grids);
subdiv_ccg->grid_faces = static_cast<SubdivCCGFace **>(
MEM_calloc_arrayN(num_grids, sizeof(SubdivCCGFace *), "Subdiv CCG grid faces"));
}
}
@@ -231,7 +232,7 @@ static void subdiv_ccg_eval_regular_grid(CCGEvalGridsData *data, const int face_
const float grid_size_1_inv = 1.0f / (grid_size - 1);
const int element_size = element_size_bytes_get(subdiv_ccg);
SubdivCCGFace *faces = subdiv_ccg->faces;
blender::MutableSpan<int> grid_faces = subdiv_ccg->grid_faces;
SubdivCCGFace **grid_faces = subdiv_ccg->grid_faces;
const SubdivCCGFace *face = &faces[face_index];
for (int corner = 0; corner < face->num_grids; corner++) {
const int grid_index = face->start_grid_index + corner;
@@ -248,7 +249,7 @@ static void subdiv_ccg_eval_regular_grid(CCGEvalGridsData *data, const int face_
}
}
/* Assign grid's face. */
grid_faces[grid_index] = face_index;
grid_faces[grid_index] = &faces[face_index];
/* Assign material flags. */
subdiv_ccg->grid_flag_mats[grid_index] = data->material_flags_evaluator->eval_material_flags(
data->material_flags_evaluator, face_index);
@@ -262,7 +263,7 @@ static void subdiv_ccg_eval_special_grid(CCGEvalGridsData *data, const int face_
const float grid_size_1_inv = 1.0f / (grid_size - 1);
const int element_size = element_size_bytes_get(subdiv_ccg);
SubdivCCGFace *faces = subdiv_ccg->faces;
blender::MutableSpan<int> grid_faces = subdiv_ccg->grid_faces;
SubdivCCGFace **grid_faces = subdiv_ccg->grid_faces;
const SubdivCCGFace *face = &faces[face_index];
for (int corner = 0; corner < face->num_grids; corner++) {
const int grid_index = face->start_grid_index + corner;
@@ -278,7 +279,7 @@ static void subdiv_ccg_eval_special_grid(CCGEvalGridsData *data, const int face_
}
}
/* Assign grid's face. */
grid_faces[grid_index] = face_index;
grid_faces[grid_index] = &faces[face_index];
/* Assign material flags. */
subdiv_ccg->grid_flag_mats[grid_index] = data->material_flags_evaluator->eval_material_flags(
data->material_flags_evaluator, face_index);
@@ -572,7 +573,7 @@ SubdivCCG *BKE_subdiv_to_ccg(Subdiv *subdiv,
SubdivCCGMaterialFlagsEvaluator *material_flags_evaluator)
{
BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_CCG);
SubdivCCG *subdiv_ccg = MEM_new<SubdivCCG>(__func__);
SubdivCCG *subdiv_ccg = MEM_cnew<SubdivCCG>(__func__);
subdiv_ccg->subdiv = subdiv;
subdiv_ccg->level = bitscan_forward_i(settings->resolution - 1);
subdiv_ccg->grid_size = BKE_subdiv_grid_size_from_level(subdiv_ccg->level);
@@ -639,6 +640,7 @@ void BKE_subdiv_ccg_destroy(SubdivCCG *subdiv_ccg)
BKE_subdiv_free(subdiv_ccg->subdiv);
}
MEM_SAFE_FREE(subdiv_ccg->faces);
MEM_SAFE_FREE(subdiv_ccg->grid_faces);
/* Free map of adjacent edges. */
for (int i = 0; i < subdiv_ccg->num_adjacent_edges; i++) {
SubdivCCGAdjacentEdge *adjacent_edge = &subdiv_ccg->adjacent_edges[i];
@@ -655,7 +657,7 @@ void BKE_subdiv_ccg_destroy(SubdivCCG *subdiv_ccg)
}
MEM_SAFE_FREE(subdiv_ccg->adjacent_vertices);
MEM_SAFE_FREE(subdiv_ccg->cache_.start_face_grid_index);
MEM_delete(subdiv_ccg);
MEM_freeN(subdiv_ccg);
}
void BKE_subdiv_ccg_key(CCGKey *key, const SubdivCCG *subdiv_ccg, int level)
@@ -684,20 +686,32 @@ void BKE_subdiv_ccg_key_top_level(CCGKey *key, const SubdivCCG *subdiv_ccg)
/** \name Normals
* \{ */
struct RecalcInnerNormalsData {
SubdivCCG *subdiv_ccg;
CCGKey *key;
};
struct RecalcInnerNormalsTLSData {
float (*face_normals)[3];
};
/* Evaluate high-res face normals, for faces which corresponds to grid elements
*
* {(x, y), {x + 1, y}, {x + 1, y + 1}, {x, y + 1}}
*
* The result is stored in normals storage from TLS. */
static void subdiv_ccg_recalc_inner_face_normals(
SubdivCCG *subdiv_ccg,
CCGKey *key,
blender::MutableSpan<blender::float3> face_normals,
const int grid_index)
static void subdiv_ccg_recalc_inner_face_normals(SubdivCCG *subdiv_ccg,
CCGKey *key,
RecalcInnerNormalsTLSData *tls,
const int grid_index)
{
const int grid_size = subdiv_ccg->grid_size;
const int grid_size_1 = grid_size - 1;
CCGElem *grid = subdiv_ccg->grids[grid_index];
if (tls->face_normals == nullptr) {
tls->face_normals = static_cast<float(*)[3]>(
MEM_malloc_arrayN(grid_size_1 * grid_size_1, sizeof(float[3]), "CCG TLS normals"));
}
for (int y = 0; y < grid_size - 1; y++) {
for (int x = 0; x < grid_size - 1; x++) {
CCGElem *grid_elements[4] = {
@@ -713,22 +727,22 @@ static void subdiv_ccg_recalc_inner_face_normals(
CCG_elem_co(key, grid_elements[3]),
};
const int face_index = y * grid_size_1 + x;
float *face_normal = face_normals[face_index];
float *face_normal = tls->face_normals[face_index];
normal_quad_v3(face_normal, co[0], co[1], co[2], co[3]);
}
}
}
/* Average normals at every grid element, using adjacent faces normals. */
static void subdiv_ccg_average_inner_face_normals(
SubdivCCG *subdiv_ccg,
CCGKey *key,
const blender::Span<blender::float3> face_normals,
const int grid_index)
static void subdiv_ccg_average_inner_face_normals(SubdivCCG *subdiv_ccg,
CCGKey *key,
RecalcInnerNormalsTLSData *tls,
const int grid_index)
{
const int grid_size = subdiv_ccg->grid_size;
const int grid_size_1 = grid_size - 1;
CCGElem *grid = subdiv_ccg->grids[grid_index];
const float(*face_normals)[3] = tls->face_normals;
for (int y = 0; y < grid_size; y++) {
for (int x = 0; x < grid_size; x++) {
float normal_acc[3] = {0.0f, 0.0f, 0.0f};
@@ -758,25 +772,42 @@ static void subdiv_ccg_average_inner_face_normals(
}
}
static void subdiv_ccg_recalc_inner_normal_task(void *__restrict userdata_v,
const int grid_index,
const TaskParallelTLS *__restrict tls_v)
{
RecalcInnerNormalsData *data = static_cast<RecalcInnerNormalsData *>(userdata_v);
RecalcInnerNormalsTLSData *tls = static_cast<RecalcInnerNormalsTLSData *>(tls_v->userdata_chunk);
subdiv_ccg_recalc_inner_face_normals(data->subdiv_ccg, data->key, tls, grid_index);
subdiv_ccg_average_inner_face_normals(data->subdiv_ccg, data->key, tls, grid_index);
}
static void subdiv_ccg_recalc_inner_normal_free(const void *__restrict /*userdata*/,
void *__restrict tls_v)
{
RecalcInnerNormalsTLSData *tls = static_cast<RecalcInnerNormalsTLSData *>(tls_v);
MEM_SAFE_FREE(tls->face_normals);
}
/* Recalculate normals which corresponds to non-boundaries elements of grids. */
static void subdiv_ccg_recalc_inner_grid_normals(SubdivCCG *subdiv_ccg)
{
using namespace blender;
const int grid_size_1 = subdiv_ccg->grid_size - 1;
threading::EnumerableThreadSpecific<Array<float3>> face_normals_tls(
[&]() { return Array<float3>(grid_size_1 * grid_size_1); });
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
threading::parallel_for(IndexRange(subdiv_ccg->num_grids), 512, [&](const IndexRange range) {
MutableSpan<float3> face_normals = face_normals_tls.local();
for (const int grid_index : range) {
subdiv_ccg_recalc_inner_face_normals(subdiv_ccg, &key, face_normals, grid_index);
subdiv_ccg_average_inner_face_normals(subdiv_ccg, &key, face_normals, grid_index);
}
});
RecalcInnerNormalsData data{};
data.subdiv_ccg = subdiv_ccg;
data.key = &key;
RecalcInnerNormalsTLSData tls_data = {nullptr};
TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
parallel_range_settings.userdata_chunk = &tls_data;
parallel_range_settings.userdata_chunk_size = sizeof(tls_data);
parallel_range_settings.func_free = subdiv_ccg_recalc_inner_normal_free;
BLI_task_parallel_range(0,
subdiv_ccg->num_grids,
&data,
subdiv_ccg_recalc_inner_normal_task,
&parallel_range_settings);
}
void BKE_subdiv_ccg_recalc_normals(SubdivCCG *subdiv_ccg)
@@ -789,48 +820,80 @@ void BKE_subdiv_ccg_recalc_normals(SubdivCCG *subdiv_ccg)
BKE_subdiv_ccg_average_grids(subdiv_ccg);
}
static void subdiv_ccg_recalc_modified_inner_grid_normals(SubdivCCG *subdiv_ccg,
const blender::IndexMask &face_mask)
struct RecalcModifiedInnerNormalsData {
SubdivCCG *subdiv_ccg;
CCGKey *key;
SubdivCCGFace **effected_ccg_faces;
};
static void subdiv_ccg_recalc_modified_inner_normal_task(void *__restrict userdata_v,
const int face_index,
const TaskParallelTLS *__restrict tls_v)
{
using namespace blender;
const int grid_size_1 = subdiv_ccg->grid_size - 1;
threading::EnumerableThreadSpecific<Array<float3>> face_normals_tls(
[&]() { return Array<float3>(grid_size_1 * grid_size_1); });
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
const SubdivCCGFace *faces = subdiv_ccg->faces;
face_mask.foreach_segment(GrainSize(512), [&](const IndexMaskSegment segment) {
MutableSpan<float3> face_normals = face_normals_tls.local();
for (const int face_index : segment) {
const SubdivCCGFace &face = faces[face_index];
const int num_face_grids = face.num_grids;
for (int i = 0; i < num_face_grids; i++) {
const int grid_index = face.start_grid_index + i;
subdiv_ccg_recalc_inner_face_normals(subdiv_ccg, &key, face_normals, grid_index);
subdiv_ccg_average_inner_face_normals(subdiv_ccg, &key, face_normals, grid_index);
}
}
});
RecalcModifiedInnerNormalsData *data = static_cast<RecalcModifiedInnerNormalsData *>(userdata_v);
SubdivCCG *subdiv_ccg = data->subdiv_ccg;
CCGKey *key = data->key;
RecalcInnerNormalsTLSData *tls = static_cast<RecalcInnerNormalsTLSData *>(tls_v->userdata_chunk);
SubdivCCGFace **faces = data->effected_ccg_faces;
SubdivCCGFace *face = faces[face_index];
const int num_face_grids = face->num_grids;
for (int i = 0; i < num_face_grids; i++) {
const int grid_index = face->start_grid_index + i;
subdiv_ccg_recalc_inner_face_normals(data->subdiv_ccg, data->key, tls, grid_index);
subdiv_ccg_average_inner_face_normals(data->subdiv_ccg, data->key, tls, grid_index);
}
subdiv_ccg_average_inner_face_grids(subdiv_ccg, key, face);
}
void BKE_subdiv_ccg_update_normals(SubdivCCG *subdiv_ccg, const blender::IndexMask &face_mask)
static void subdiv_ccg_recalc_modified_inner_normal_free(const void *__restrict /*userdata*/,
void *__restrict tls_v)
{
RecalcInnerNormalsTLSData *tls = static_cast<RecalcInnerNormalsTLSData *>(tls_v);
MEM_SAFE_FREE(tls->face_normals);
}
static void subdiv_ccg_recalc_modified_inner_grid_normals(SubdivCCG *subdiv_ccg,
CCGFace **effected_faces,
int num_effected_faces)
{
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
RecalcModifiedInnerNormalsData data{};
data.subdiv_ccg = subdiv_ccg;
data.key = &key;
data.effected_ccg_faces = (SubdivCCGFace **)effected_faces;
RecalcInnerNormalsTLSData tls_data = {nullptr};
TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
parallel_range_settings.userdata_chunk = &tls_data;
parallel_range_settings.userdata_chunk_size = sizeof(tls_data);
parallel_range_settings.func_free = subdiv_ccg_recalc_modified_inner_normal_free;
BLI_task_parallel_range(0,
num_effected_faces,
&data,
subdiv_ccg_recalc_modified_inner_normal_task,
&parallel_range_settings);
}
void BKE_subdiv_ccg_update_normals(SubdivCCG *subdiv_ccg,
CCGFace **effected_faces,
int num_effected_faces)
{
if (!subdiv_ccg->has_normal) {
/* Grids don't have normals, can do early output. */
return;
}
if (face_mask.is_empty()) {
if (num_effected_faces == 0) {
/* No faces changed, so nothing to do here. */
return;
}
subdiv_ccg_recalc_modified_inner_grid_normals(subdiv_ccg, face_mask);
subdiv_ccg_recalc_modified_inner_grid_normals(subdiv_ccg, effected_faces, num_effected_faces);
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
subdiv_ccg_average_faces_boundaries_and_corners(subdiv_ccg, &key, face_mask);
subdiv_ccg_average_faces_boundaries_and_corners(
subdiv_ccg, &key, effected_faces, num_effected_faces);
}
/** \} */
@@ -1164,7 +1227,8 @@ void BKE_subdiv_ccg_average_grids(SubdivCCG *subdiv_ccg)
}
static void subdiv_ccg_affected_face_adjacency(SubdivCCG *subdiv_ccg,
const blender::IndexMask &face_mask,
CCGFace **effected_faces,
int num_effected_faces,
GSet *r_adjacent_vertices,
GSet *r_adjacent_edges)
{
@@ -1177,8 +1241,9 @@ static void subdiv_ccg_affected_face_adjacency(SubdivCCG *subdiv_ccg,
static_or_heap_storage_init(&face_vertices_storage);
static_or_heap_storage_init(&face_edges_storage);
face_mask.foreach_index([&](const int face_index) {
SubdivCCGFace *face = &subdiv_ccg->faces[face_index];
for (int i = 0; i < num_effected_faces; i++) {
SubdivCCGFace *face = (SubdivCCGFace *)effected_faces[i];
int face_index = face - subdiv_ccg->faces;
const int num_face_grids = face->num_grids;
const int num_face_edges = num_face_grids;
int *face_vertices = static_or_heap_storage_get(&face_vertices_storage, num_face_edges);
@@ -1201,7 +1266,7 @@ static void subdiv_ccg_affected_face_adjacency(SubdivCCG *subdiv_ccg,
SubdivCCGAdjacentVertex *adjacent_vertex = &subdiv_ccg->adjacent_vertices[vertex_index];
BLI_gset_add(r_adjacent_vertices, adjacent_vertex);
}
});
}
static_or_heap_storage_free(&face_vertices_storage);
static_or_heap_storage_free(&face_edges_storage);
@@ -1209,13 +1274,15 @@ static void subdiv_ccg_affected_face_adjacency(SubdivCCG *subdiv_ccg,
void subdiv_ccg_average_faces_boundaries_and_corners(SubdivCCG *subdiv_ccg,
CCGKey *key,
const blender::IndexMask &face_mask)
CCGFace **effected_faces,
int num_effected_faces)
{
GSet *adjacent_vertices = BLI_gset_ptr_new(__func__);
GSet *adjacent_edges = BLI_gset_ptr_new(__func__);
GSetIterator gi;
subdiv_ccg_affected_face_adjacency(subdiv_ccg, face_mask, adjacent_vertices, adjacent_edges);
subdiv_ccg_affected_face_adjacency(
subdiv_ccg, effected_faces, num_effected_faces, adjacent_vertices, adjacent_edges);
int *adjacent_vertex_index_map;
int *adjacent_edge_index_map;
@@ -1253,17 +1320,42 @@ void subdiv_ccg_average_faces_boundaries_and_corners(SubdivCCG *subdiv_ccg,
static_or_heap_storage_free(&index_heap);
}
void BKE_subdiv_ccg_average_stitch_faces(SubdivCCG *subdiv_ccg,
const blender::IndexMask &face_mask)
struct StitchFacesInnerGridsData {
SubdivCCG *subdiv_ccg;
CCGKey *key;
CCGFace **effected_ccg_faces;
};
static void subdiv_ccg_stitch_face_inner_grids_task(void *__restrict userdata_v,
const int face_index,
const TaskParallelTLS *__restrict /*tls_v*/)
{
StitchFacesInnerGridsData *data = static_cast<StitchFacesInnerGridsData *>(userdata_v);
SubdivCCG *subdiv_ccg = data->subdiv_ccg;
CCGKey *key = data->key;
CCGFace **effected_ccg_faces = data->effected_ccg_faces;
CCGFace *effected_ccg_face = effected_ccg_faces[face_index];
SubdivCCGFace *face = (SubdivCCGFace *)effected_ccg_face;
subdiv_ccg_average_inner_face_grids(subdiv_ccg, key, face);
}
void BKE_subdiv_ccg_average_stitch_faces(SubdivCCG *subdiv_ccg,
CCGFace **effected_faces,
int num_effected_faces)
{
using namespace blender;
CCGKey key;
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
face_mask.foreach_index(GrainSize(512), [&](const int face_index) {
subdiv_ccg_average_inner_face_grids(subdiv_ccg, &key, &subdiv_ccg->faces[face_index]);
});
StitchFacesInnerGridsData data{};
data.subdiv_ccg = subdiv_ccg;
data.key = &key;
data.effected_ccg_faces = effected_faces;
TaskParallelSettings parallel_range_settings;
BLI_parallel_range_settings_defaults(&parallel_range_settings);
BLI_task_parallel_range(0,
num_effected_faces,
&data,
subdiv_ccg_stitch_face_inner_grids_task,
&parallel_range_settings);
/* TODO(sergey): Only average elements which are adjacent to modified
* faces. */
subdiv_ccg_average_all_boundaries_and_corners(subdiv_ccg, &key);
@@ -1421,7 +1513,7 @@ static SubdivCCGCoord coord_step_inside_from_boundary(const SubdivCCG *subdiv_cc
BLI_INLINE
int next_grid_index_from_coord(const SubdivCCG *subdiv_ccg, const SubdivCCGCoord *coord)
{
SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_faces[coord->grid_index]];
SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
const int face_grid_index = coord->grid_index;
int next_face_grid_index = face_grid_index + 1 - face->start_grid_index;
if (next_face_grid_index == face->num_grids) {
@@ -1431,7 +1523,7 @@ int next_grid_index_from_coord(const SubdivCCG *subdiv_ccg, const SubdivCCGCoord
}
BLI_INLINE int prev_grid_index_from_coord(const SubdivCCG *subdiv_ccg, const SubdivCCGCoord *coord)
{
SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_faces[coord->grid_index]];
SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
const int face_grid_index = coord->grid_index;
int prev_face_grid_index = face_grid_index - 1 - face->start_grid_index;
if (prev_face_grid_index < 0) {
@@ -1447,7 +1539,7 @@ static void neighbor_coords_corner_center_get(const SubdivCCG *subdiv_ccg,
const bool include_duplicates,
SubdivCCGNeighbors *r_neighbors)
{
const SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_faces[coord->grid_index]];
SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
const int num_adjacent_grids = face->num_grids;
subdiv_ccg_neighbors_init(
@@ -1475,7 +1567,7 @@ static int adjacent_vertex_index_from_coord(const SubdivCCG *subdiv_ccg,
Subdiv *subdiv = subdiv_ccg->subdiv;
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
const SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_faces[coord->grid_index]];
const SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
const int face_index = face - subdiv_ccg->faces;
const int face_grid_index = coord->grid_index - face->start_grid_index;
const int num_face_grids = face->num_grids;
@@ -1562,7 +1654,7 @@ static int adjacent_edge_index_from_coord(const SubdivCCG *subdiv_ccg, const Sub
{
Subdiv *subdiv = subdiv_ccg->subdiv;
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
const SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_faces[coord->grid_index]];
SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
const int face_grid_index = coord->grid_index - face->start_grid_index;
const int face_index = face - subdiv_ccg->faces;
@@ -1859,7 +1951,9 @@ void BKE_subdiv_ccg_neighbor_coords_get(const SubdivCCG *subdiv_ccg,
int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG *subdiv_ccg, const int grid_index)
{
return subdiv_ccg->grid_faces[grid_index];
const SubdivCCGFace *face = subdiv_ccg->grid_faces[grid_index];
const int face_index = face - subdiv_ccg->faces;
return face_index;
}
const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG *subdiv_ccg)