UI: Highlight Selected Enum #111074

Merged
Harley Acheson merged 12 commits from Harley/blender:SelectedEnum into main 2023-09-01 21:33:11 +02:00
11 changed files with 259 additions and 165 deletions
Showing only changes of commit f32479a0ae - Show all commits

View File

@ -217,10 +217,6 @@ bool BKE_paint_always_hide_test(Object *ob);
/* Partial visibility. */
/**
* Returns non-zero if any of the face's vertices are hidden, zero otherwise.
*/
bool paint_is_face_hidden(const int *looptri_faces, const bool *hide_poly, int tri_index);
/**
* Returns non-zero if any of the corners of the grid
* face whose inner corner is at (x, y) are hidden, zero otherwise.

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);

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,

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);
}
}

View File

@ -1293,14 +1293,6 @@ void BKE_paint_blend_read_lib(BlendLibReader *reader, Scene *sce, Paint *p)
}
}
bool paint_is_face_hidden(const int *looptri_faces, const bool *hide_poly, const int tri_index)
{
if (!hide_poly) {
return false;
}
return hide_poly[looptri_faces[tri_index]];
}
bool paint_is_grid_face_hidden(const uint *grid_hidden, int gridsize, int x, int y)
{
/* Skip face if any of its corners are hidden. */
@ -2260,7 +2252,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 +2341,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);

View File

@ -318,29 +318,20 @@ static int map_insert_vert(
/* Find vertices used by the faces in this node and update the draw buffers */
static void build_mesh_leaf_node(PBVH *pbvh, PBVHNode *node)
{
bool has_visible = false;
node->uniq_verts = node->face_verts = 0;
const int totface = node->prim_indices.size();
const Span<int> prim_indices = node->prim_indices;
/* reserve size is rough guess */
blender::Map<int, int> map;
map.reserve(totface);
map.reserve(prim_indices.size());
node->face_vert_indices.reinitialize(totface);
node->face_vert_indices.reinitialize(prim_indices.size());
for (int i = 0; i < totface; i++) {
const MLoopTri *lt = &pbvh->looptri[node->prim_indices[i]];
for (const int i : prim_indices.index_range()) {
const MLoopTri &tri = pbvh->looptri[prim_indices[i]];
for (int j = 0; j < 3; j++) {
node->face_vert_indices[i][j] = map_insert_vert(
pbvh, map, &node->face_verts, &node->uniq_verts, pbvh->corner_verts[lt->tri[j]]);
}
if (has_visible == false) {
if (!paint_is_face_hidden(
pbvh->looptri_faces.data(), pbvh->hide_poly, node->prim_indices[i])) {
has_visible = true;
}
pbvh, map, &node->face_verts, &node->uniq_verts, pbvh->corner_verts[tri.tri[j]]);
}
}
@ -356,19 +347,22 @@ static void build_mesh_leaf_node(PBVH *pbvh, PBVHNode *node)
node->vert_indices[value] = item.key;
}
for (int i = 0; i < totface; i++) {
const int sides = 3;
for (int j = 0; j < sides; j++) {
for (const int i : prim_indices.index_range()) {
for (int j = 0; j < 3; j++) {
if (node->face_vert_indices[i][j] < 0) {
node->face_vert_indices[i][j] = -node->face_vert_indices[i][j] + node->uniq_verts - 1;
}
}
}
const bool fully_hidden = pbvh->hide_poly &&
std::all_of(
prim_indices.begin(), prim_indices.end(), [&](const int tri) {
const int face = pbvh->looptri_faces[tri];
return pbvh->hide_poly[face];
});
BKE_pbvh_node_fully_hidden_set(node, fully_hidden);
BKE_pbvh_node_mark_rebuild_draw(node);
BKE_pbvh_node_fully_hidden_set(node, !has_visible);
}
static void update_vb(PBVH *pbvh, PBVHNode *node, const Span<BBC> prim_bbc, int offset, int count)
@ -927,7 +921,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 +1736,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 ***********************************/
@ -2280,7 +2302,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh,
const MLoopTri *lt = &pbvh->looptri[looptri_i];
const blender::int3 face_verts = node->face_vert_indices[i];
if (paint_is_face_hidden(pbvh->looptri_faces.data(), pbvh->hide_poly, looptri_i)) {
if (pbvh->hide_poly && pbvh->hide_poly[pbvh->looptri_faces[looptri_i]]) {
continue;
}
@ -2627,7 +2649,7 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh,
const MLoopTri *lt = &pbvh->looptri[looptri_i];
const blender::int3 face_verts = node->face_vert_indices[i];
if (paint_is_face_hidden(pbvh->looptri_faces.data(), pbvh->hide_poly, looptri_i)) {
if (pbvh->hide_poly && pbvh->hide_poly[pbvh->looptri_faces[looptri_i]]) {
continue;
}
@ -2817,7 +2839,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 +2851,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 +2975,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)

View File

@ -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;

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)

View File

@ -168,7 +168,7 @@ static bool menu_items_from_ui_create_item_from_button(MenuSearch_Data *data,
MenuSearch_Item *item = nullptr;
/* Use override if the name is empty, this can happen with popovers. */
std::string drawstr_override = nullptr;
std::string drawstr_override;
const char *drawstr_sep = (but->flag & UI_BUT_HAS_SEP_CHAR) ?
strrchr(but->drawstr, UI_SEP_CHAR) :
nullptr;

View File

@ -120,13 +120,6 @@ extern "C" eAttrDomain BKE_id_attribute_domain(const struct ID * /*id*/,
/* -------------------------------------------------------------------- */
/** \name Stubs of BKE_paint.hh
* \{ */
bool paint_is_face_hidden(const int * /*looptri_faces*/,
const bool * /*hide_poly*/,
int /*tri_index*/)
{
BLI_assert_unreachable();
return false;
}
void BKE_paint_face_set_overlay_color_get(const int /*face_set*/,
const int /*seed*/,

View File

@ -1485,13 +1485,10 @@ static std::string rna_operator_description_cb(bContext *C,
ot->rna_ext.call(C, &ptr, func, &list);
RNA_parameter_get_lookup(&list, "result", &ret);
const char *result = (const char *)ret;
std::string result = ret ? std::string(static_cast<const char *>(ret)) : "";
RNA_parameter_list_free(&list);
if (!result) {
return "";
}
return result;
}