Cleanup: Use Vector for passing lists of PBVHNodes around
Cleaned up sculpt code to store lists of `PBVHNodes` with
`blender::Vector` instead of simple pointer arrays. This is much
simpler and eliminates memory leaks caused by forgetting to free
the result of `BKE_pbvh_search_gather`.
Notes:
* `BKE_pbvh_search_gather` is now `blender::pbvh::search_gather`.
* `FilterCache` and `ExpandCache` have ownership over their .nodes
members; as a result they're no longer pure C structs and
are allocated with `MEM_new`/`MEM_delete`.
* The word 'totnode' no longer occurs anywhere in
`source/blender/editors/sculpt_paint`
Todo (not for this PR): create a new properly C++ task API for sculpt
(with lambdas) and use it for brushes.
Pull Request: https://projects.blender.org/blender/blender/pulls/106884
This commit is contained in:
committed by
Joseph Eagar
parent
15683d81be
commit
b86fc55d30
@@ -12,6 +12,7 @@
|
||||
#include "BLI_ghash.h"
|
||||
#ifdef __cplusplus
|
||||
# include "BLI_offset_indices.hh"
|
||||
# include "BLI_vector.hh"
|
||||
#endif
|
||||
|
||||
#include "bmesh.h"
|
||||
@@ -320,7 +321,8 @@ void BKE_pbvh_free(PBVH *pbvh);
|
||||
|
||||
/* Hierarchical Search in the BVH, two methods:
|
||||
* - For each hit calling a callback.
|
||||
* - Gather nodes in an array (easy to multi-thread). */
|
||||
* - Gather nodes in an array (easy to multi-thread) see blender::bke::pbvh::search_gather.
|
||||
*/
|
||||
|
||||
void BKE_pbvh_search_callback(PBVH *pbvh,
|
||||
BKE_pbvh_SearchCallback scb,
|
||||
@@ -328,14 +330,6 @@ void BKE_pbvh_search_callback(PBVH *pbvh,
|
||||
BKE_pbvh_HitCallback hcb,
|
||||
void *hit_data);
|
||||
|
||||
void BKE_pbvh_search_gather(
|
||||
PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***array, int *tot);
|
||||
void BKE_pbvh_search_gather_ex(PBVH *pbvh,
|
||||
BKE_pbvh_SearchCallback scb,
|
||||
void *search_data,
|
||||
PBVHNode ***r_array,
|
||||
int *r_tot,
|
||||
PBVHNodeFlags leaf_flag);
|
||||
/* Ray-cast
|
||||
* the hit callback is called for all leaf nodes intersecting the ray;
|
||||
* it's up to the callback to find the primitive within the leaves that is
|
||||
@@ -748,7 +742,6 @@ void BKE_pbvh_face_iter_finish(PBVHFaceIter *fd);
|
||||
void BKE_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *proxy_count);
|
||||
void BKE_pbvh_node_free_proxies(PBVHNode *node);
|
||||
PBVHProxyNode *BKE_pbvh_node_add_proxy(PBVH *pbvh, PBVHNode *node);
|
||||
void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot);
|
||||
void BKE_pbvh_node_get_bm_orco_data(PBVHNode *node,
|
||||
int (**r_orco_tris)[3],
|
||||
int *r_orco_tris_num,
|
||||
@@ -826,4 +819,13 @@ int BKE_pbvh_debug_draw_gen_get(PBVHNode *node);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
namespace blender::bke::pbvh {
|
||||
Vector<PBVHNode *> search_gather(PBVH *pbvh,
|
||||
BKE_pbvh_SearchCallback scb,
|
||||
void *search_data,
|
||||
PBVHNodeFlags leaf_flag = PBVH_Leaf);
|
||||
Vector<PBVHNode *> gather_proxies(PBVH *pbvh);
|
||||
|
||||
} // namespace blender::bke::pbvh
|
||||
#endif
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_string_utf8.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
@@ -70,6 +71,7 @@
|
||||
using blender::float3;
|
||||
using blender::MutableSpan;
|
||||
using blender::Span;
|
||||
using blender::Vector;
|
||||
|
||||
static void sculpt_attribute_update_refs(Object *ob);
|
||||
static SculptAttribute *sculpt_attribute_ensure_ex(Object *ob,
|
||||
@@ -1891,16 +1893,11 @@ void BKE_sculpt_update_object_before_eval(Object *ob_eval)
|
||||
BKE_sculptsession_free_vwpaint_data(ob_eval->sculpt);
|
||||
}
|
||||
else {
|
||||
PBVHNode **nodes;
|
||||
int n, totnode;
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
|
||||
for (n = 0; n < totnode; n++) {
|
||||
BKE_pbvh_node_mark_update(nodes[n]);
|
||||
for (PBVHNode *node : nodes) {
|
||||
BKE_pbvh_node_mark_update(node);
|
||||
}
|
||||
|
||||
MEM_freeN(nodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "BLI_rand.h"
|
||||
#include "BLI_task.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
@@ -39,6 +40,7 @@
|
||||
using blender::float3;
|
||||
using blender::MutableSpan;
|
||||
using blender::Span;
|
||||
using blender::Vector;
|
||||
|
||||
#define LEAF_LIMIT 10000
|
||||
|
||||
@@ -1225,70 +1227,6 @@ static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BKE_pbvh_search_gather_ex(PBVH *pbvh,
|
||||
BKE_pbvh_SearchCallback scb,
|
||||
void *search_data,
|
||||
PBVHNode ***r_array,
|
||||
int *r_tot,
|
||||
PBVHNodeFlags leaf_flag)
|
||||
{
|
||||
PBVHIter iter;
|
||||
PBVHNode **array = nullptr, *node;
|
||||
int tot = 0, space = 0;
|
||||
|
||||
pbvh_iter_begin(&iter, pbvh, scb, search_data);
|
||||
|
||||
while ((node = pbvh_iter_next(&iter, leaf_flag))) {
|
||||
if (node->flag & leaf_flag) {
|
||||
if (UNLIKELY(tot == space)) {
|
||||
/* resize array if needed */
|
||||
space = (tot == 0) ? 32 : space * 2;
|
||||
array = static_cast<PBVHNode **>(
|
||||
MEM_recallocN_id(array, sizeof(PBVHNode *) * space, __func__));
|
||||
}
|
||||
|
||||
array[tot] = node;
|
||||
tot++;
|
||||
}
|
||||
}
|
||||
|
||||
pbvh_iter_end(&iter);
|
||||
|
||||
if (tot == 0 && array) {
|
||||
MEM_freeN(array);
|
||||
array = nullptr;
|
||||
}
|
||||
|
||||
*r_array = array;
|
||||
*r_tot = tot;
|
||||
}
|
||||
|
||||
void BKE_pbvh_search_gather(
|
||||
PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***r_array, int *r_tot)
|
||||
{
|
||||
BKE_pbvh_search_gather_ex(pbvh, scb, search_data, r_array, r_tot, PBVH_Leaf);
|
||||
}
|
||||
|
||||
void BKE_pbvh_search_callback(PBVH *pbvh,
|
||||
BKE_pbvh_SearchCallback scb,
|
||||
void *search_data,
|
||||
BKE_pbvh_HitCallback hcb,
|
||||
void *hit_data)
|
||||
{
|
||||
PBVHIter iter;
|
||||
PBVHNode *node;
|
||||
|
||||
pbvh_iter_begin(&iter, pbvh, scb, search_data);
|
||||
|
||||
while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) {
|
||||
if (node->flag & PBVH_Leaf) {
|
||||
hcb(node, hit_data);
|
||||
}
|
||||
}
|
||||
|
||||
pbvh_iter_end(&iter);
|
||||
}
|
||||
|
||||
struct node_tree {
|
||||
PBVHNode *data;
|
||||
|
||||
@@ -1352,6 +1290,26 @@ float BKE_pbvh_node_get_tmin(PBVHNode *node)
|
||||
return node->tmin;
|
||||
}
|
||||
|
||||
void BKE_pbvh_search_callback(PBVH *pbvh,
|
||||
BKE_pbvh_SearchCallback scb,
|
||||
void *search_data,
|
||||
BKE_pbvh_HitCallback hcb,
|
||||
void *hit_data)
|
||||
{
|
||||
PBVHIter iter;
|
||||
PBVHNode *node;
|
||||
|
||||
pbvh_iter_begin(&iter, pbvh, scb, search_data);
|
||||
|
||||
while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) {
|
||||
if (node->flag & PBVH_Leaf) {
|
||||
hcb(node, hit_data);
|
||||
}
|
||||
}
|
||||
|
||||
pbvh_iter_end(&iter);
|
||||
}
|
||||
|
||||
static void BKE_pbvh_search_callback_occluded(PBVH *pbvh,
|
||||
BKE_pbvh_SearchCallback scb,
|
||||
void *search_data,
|
||||
@@ -1404,14 +1362,15 @@ static bool update_search_cb(PBVHNode *node, void *data_v)
|
||||
|
||||
struct PBVHUpdateData {
|
||||
PBVH *pbvh;
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
Span<PBVHNode *> nodes;
|
||||
|
||||
float (*vert_normals)[3];
|
||||
int flag;
|
||||
bool show_sculpt_face_sets;
|
||||
PBVHAttrReq *attrs;
|
||||
int attrs_num;
|
||||
float (*vert_normals)[3] = nullptr;
|
||||
int flag = 0;
|
||||
bool show_sculpt_face_sets = false;
|
||||
PBVHAttrReq *attrs = nullptr;
|
||||
int attrs_num = 0;
|
||||
|
||||
PBVHUpdateData(PBVH *pbvh_, Span<PBVHNode *> nodes_) : pbvh(pbvh_), nodes(nodes_) {}
|
||||
};
|
||||
|
||||
static void pbvh_update_normals_clear_task_cb(void *__restrict userdata,
|
||||
@@ -1515,7 +1474,7 @@ static void pbvh_update_normals_store_task_cb(void *__restrict userdata,
|
||||
}
|
||||
}
|
||||
|
||||
static void pbvh_faces_update_normals(PBVH *pbvh, PBVHNode **nodes, int totnode)
|
||||
static void pbvh_faces_update_normals(PBVH *pbvh, Span<PBVHNode *> nodes)
|
||||
{
|
||||
/* subtle assumptions:
|
||||
* - We know that for all edited vertices, the nodes with faces
|
||||
@@ -1527,18 +1486,18 @@ static void pbvh_faces_update_normals(PBVH *pbvh, PBVHNode **nodes, int totnode)
|
||||
* can only update vertices marked in the `vert_bitmap`.
|
||||
*/
|
||||
|
||||
PBVHUpdateData data{};
|
||||
PBVHUpdateData data(pbvh, nodes);
|
||||
data.pbvh = pbvh;
|
||||
data.nodes = nodes;
|
||||
data.vert_normals = pbvh->vert_normals;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
|
||||
/* Zero normals before accumulation. */
|
||||
BLI_task_parallel_range(0, totnode, &data, pbvh_update_normals_clear_task_cb, &settings);
|
||||
BLI_task_parallel_range(0, totnode, &data, pbvh_update_normals_accum_task_cb, &settings);
|
||||
BLI_task_parallel_range(0, totnode, &data, pbvh_update_normals_store_task_cb, &settings);
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, pbvh_update_normals_clear_task_cb, &settings);
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, pbvh_update_normals_accum_task_cb, &settings);
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, pbvh_update_normals_store_task_cb, &settings);
|
||||
}
|
||||
|
||||
static void pbvh_update_mask_redraw_task_cb(void *__restrict userdata,
|
||||
@@ -1577,16 +1536,16 @@ static void pbvh_update_mask_redraw_task_cb(void *__restrict userdata,
|
||||
}
|
||||
}
|
||||
|
||||
static void pbvh_update_mask_redraw(PBVH *pbvh, PBVHNode **nodes, int totnode, int flag)
|
||||
static void pbvh_update_mask_redraw(PBVH *pbvh, Span<PBVHNode *> nodes, int flag)
|
||||
{
|
||||
PBVHUpdateData data{};
|
||||
PBVHUpdateData data(pbvh, nodes);
|
||||
data.pbvh = pbvh;
|
||||
data.nodes = nodes;
|
||||
data.flag = flag;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, pbvh_update_mask_redraw_task_cb, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, pbvh_update_mask_redraw_task_cb, &settings);
|
||||
}
|
||||
|
||||
static void pbvh_update_visibility_redraw_task_cb(void *__restrict userdata,
|
||||
@@ -1613,16 +1572,17 @@ static void pbvh_update_visibility_redraw_task_cb(void *__restrict userdata,
|
||||
}
|
||||
}
|
||||
|
||||
static void pbvh_update_visibility_redraw(PBVH *pbvh, PBVHNode **nodes, int totnode, int flag)
|
||||
static void pbvh_update_visibility_redraw(PBVH *pbvh, Span<PBVHNode *> nodes, int flag)
|
||||
{
|
||||
PBVHUpdateData data{};
|
||||
PBVHUpdateData data(pbvh, nodes);
|
||||
data.pbvh = pbvh;
|
||||
data.nodes = nodes;
|
||||
data.flag = flag;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, pbvh_update_visibility_redraw_task_cb, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(
|
||||
0, nodes.size(), &data, pbvh_update_visibility_redraw_task_cb, &settings);
|
||||
}
|
||||
|
||||
static void pbvh_update_BB_redraw_task_cb(void *__restrict userdata,
|
||||
@@ -1649,17 +1609,15 @@ static void pbvh_update_BB_redraw_task_cb(void *__restrict userdata,
|
||||
}
|
||||
}
|
||||
|
||||
void pbvh_update_BB_redraw(PBVH *pbvh, PBVHNode **nodes, int totnode, int flag)
|
||||
static void pbvh_update_BB_redraw(PBVH *pbvh, Span<PBVHNode *> nodes, int flag)
|
||||
{
|
||||
/* update BB, redraw flag */
|
||||
PBVHUpdateData data{};
|
||||
data.pbvh = pbvh;
|
||||
data.nodes = nodes;
|
||||
PBVHUpdateData data(pbvh, nodes);
|
||||
data.flag = flag;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, pbvh_update_BB_redraw_task_cb, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, pbvh_update_BB_redraw_task_cb, &settings);
|
||||
}
|
||||
|
||||
bool BKE_pbvh_get_color_layer(const Mesh *me, CustomDataLayer **r_layer, eAttrDomain *r_attr)
|
||||
@@ -1724,7 +1682,7 @@ void pbvh_free_draw_buffers(PBVH * /*pbvh*/, PBVHNode *node)
|
||||
}
|
||||
}
|
||||
|
||||
static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode, int update_flag)
|
||||
static void pbvh_update_draw_buffers(PBVH *pbvh, Span<PBVHNode *> nodes, int update_flag)
|
||||
{
|
||||
const CustomData *vdata;
|
||||
|
||||
@@ -1748,8 +1706,7 @@ static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode,
|
||||
|
||||
if ((update_flag & PBVH_RebuildDrawBuffers) || ELEM(pbvh->header.type, PBVH_GRIDS, PBVH_BMESH)) {
|
||||
/* Free buffers uses OpenGL, so not in parallel. */
|
||||
for (int n = 0; n < totnode; n++) {
|
||||
PBVHNode *node = nodes[n];
|
||||
for (PBVHNode *node : nodes) {
|
||||
if (node->flag & PBVH_RebuildDrawBuffers) {
|
||||
pbvh_free_draw_buffers(pbvh, node);
|
||||
}
|
||||
@@ -1763,17 +1720,13 @@ static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode,
|
||||
}
|
||||
|
||||
/* Parallel creation and update of draw buffers. */
|
||||
PBVHUpdateData data{};
|
||||
data.pbvh = pbvh;
|
||||
data.nodes = nodes;
|
||||
PBVHUpdateData data(pbvh, nodes);
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, pbvh_update_draw_buffer_cb, &settings);
|
||||
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
PBVHNode *node = nodes[i];
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, pbvh_update_draw_buffer_cb, &settings);
|
||||
|
||||
for (PBVHNode *node : nodes) {
|
||||
if (node->flag & PBVH_UpdateDrawBuffers) {
|
||||
/* Flush buffers uses OpenGL, so not in parallel. */
|
||||
|
||||
@@ -1824,20 +1777,16 @@ void BKE_pbvh_update_bounds(PBVH *pbvh, int flag)
|
||||
return;
|
||||
}
|
||||
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
|
||||
BKE_pbvh_search_gather(pbvh, update_search_cb, POINTER_FROM_INT(flag), &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(
|
||||
pbvh, update_search_cb, POINTER_FROM_INT(flag));
|
||||
|
||||
if (flag & (PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw)) {
|
||||
pbvh_update_BB_redraw(pbvh, nodes, totnode, flag);
|
||||
pbvh_update_BB_redraw(pbvh, nodes, flag);
|
||||
}
|
||||
|
||||
if (flag & (PBVH_UpdateBB | PBVH_UpdateOriginalBB)) {
|
||||
pbvh_flush_bb(pbvh, pbvh->nodes, flag);
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
}
|
||||
|
||||
void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flag)
|
||||
@@ -1846,27 +1795,21 @@ void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flag)
|
||||
return;
|
||||
}
|
||||
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
|
||||
BKE_pbvh_search_gather(pbvh, update_search_cb, POINTER_FROM_INT(flag), &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(
|
||||
pbvh, update_search_cb, POINTER_FROM_INT(flag));
|
||||
|
||||
if (flag & (PBVH_UpdateMask)) {
|
||||
pbvh_update_mask_redraw(pbvh, nodes, totnode, flag);
|
||||
pbvh_update_mask_redraw(pbvh, nodes, flag);
|
||||
}
|
||||
|
||||
if (flag & (PBVH_UpdateColor)) {
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
nodes[i]->flag |= PBVH_UpdateRedraw | PBVH_UpdateDrawBuffers | PBVH_UpdateColor;
|
||||
for (PBVHNode *node : nodes) {
|
||||
node->flag |= PBVH_UpdateRedraw | PBVH_UpdateDrawBuffers | PBVH_UpdateColor;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag & (PBVH_UpdateVisibility)) {
|
||||
pbvh_update_visibility_redraw(pbvh, nodes, totnode, flag);
|
||||
}
|
||||
|
||||
if (nodes) {
|
||||
MEM_freeN(nodes);
|
||||
pbvh_update_visibility_redraw(pbvh, nodes, flag);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1973,15 +1916,14 @@ static void pbvh_update_visibility_task_cb(void *__restrict userdata,
|
||||
}
|
||||
}
|
||||
|
||||
static void pbvh_update_visibility(PBVH *pbvh, PBVHNode **nodes, int totnode)
|
||||
static void pbvh_update_visibility(PBVH *pbvh, Span<PBVHNode *> nodes)
|
||||
{
|
||||
PBVHUpdateData data{};
|
||||
PBVHUpdateData data(pbvh, nodes);
|
||||
data.pbvh = pbvh;
|
||||
data.nodes = nodes;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, pbvh_update_visibility_task_cb, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, pbvh_update_visibility_task_cb, &settings);
|
||||
}
|
||||
|
||||
void BKE_pbvh_update_visibility(PBVH *pbvh)
|
||||
@@ -1990,16 +1932,10 @@ void BKE_pbvh_update_visibility(PBVH *pbvh)
|
||||
return;
|
||||
}
|
||||
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(
|
||||
pbvh, update_search_cb, POINTER_FROM_INT(PBVH_UpdateVisibility));
|
||||
|
||||
BKE_pbvh_search_gather(
|
||||
pbvh, update_search_cb, POINTER_FROM_INT(PBVH_UpdateVisibility), &nodes, &totnode);
|
||||
pbvh_update_visibility(pbvh, nodes, totnode);
|
||||
|
||||
if (nodes) {
|
||||
MEM_freeN(nodes);
|
||||
}
|
||||
pbvh_update_visibility(pbvh, nodes);
|
||||
}
|
||||
|
||||
void BKE_pbvh_redraw_BB(PBVH *pbvh, float bb_min[3], float bb_max[3])
|
||||
@@ -3095,18 +3031,15 @@ bool BKE_pbvh_node_frustum_exclude_AABB(PBVHNode *node, void *data)
|
||||
void BKE_pbvh_update_normals(PBVH *pbvh, SubdivCCG *subdiv_ccg)
|
||||
{
|
||||
/* Update normals */
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(
|
||||
pbvh, update_search_cb, POINTER_FROM_INT(PBVH_UpdateNormals));
|
||||
|
||||
BKE_pbvh_search_gather(
|
||||
pbvh, update_search_cb, POINTER_FROM_INT(PBVH_UpdateNormals), &nodes, &totnode);
|
||||
|
||||
if (totnode > 0) {
|
||||
if (!nodes.is_empty()) {
|
||||
if (pbvh->header.type == PBVH_BMESH) {
|
||||
pbvh_bmesh_normals_update(nodes, totnode);
|
||||
pbvh_bmesh_normals_update(nodes);
|
||||
}
|
||||
else if (pbvh->header.type == PBVH_FACES) {
|
||||
pbvh_faces_update_normals(pbvh, nodes, totnode);
|
||||
pbvh_faces_update_normals(pbvh, nodes);
|
||||
}
|
||||
else if (pbvh->header.type == PBVH_GRIDS) {
|
||||
CCGFace **faces;
|
||||
@@ -3118,8 +3051,6 @@ void BKE_pbvh_update_normals(PBVH *pbvh, SubdivCCG *subdiv_ccg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
}
|
||||
|
||||
void BKE_pbvh_face_sets_color_set(PBVH *pbvh, int seed, int color_default)
|
||||
@@ -3160,8 +3091,7 @@ void BKE_pbvh_draw_cb(PBVH *pbvh,
|
||||
PBVHAttrReq *attrs,
|
||||
int attrs_num)
|
||||
{
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
Vector<PBVHNode *> nodes;
|
||||
int update_flag = 0;
|
||||
|
||||
pbvh->draw_cache_invalid = false;
|
||||
@@ -3174,41 +3104,37 @@ void BKE_pbvh_draw_cb(PBVH *pbvh,
|
||||
data.accum_update_flag = 0;
|
||||
data.attrs = attrs;
|
||||
data.attrs_num = attrs_num;
|
||||
BKE_pbvh_search_gather(pbvh, pbvh_draw_search_cb, &data, &nodes, &totnode);
|
||||
nodes = blender::bke::pbvh::search_gather(pbvh, pbvh_draw_search_cb, &data);
|
||||
update_flag = data.accum_update_flag;
|
||||
}
|
||||
else {
|
||||
/* Get all nodes with draw updates, also those outside the view. */
|
||||
const int search_flag = PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers;
|
||||
BKE_pbvh_search_gather(
|
||||
pbvh, update_search_cb, POINTER_FROM_INT(search_flag), &nodes, &totnode);
|
||||
nodes = blender::bke::pbvh::search_gather(
|
||||
pbvh, update_search_cb, POINTER_FROM_INT(search_flag));
|
||||
update_flag = PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers;
|
||||
}
|
||||
|
||||
/* Update draw buffers. */
|
||||
if (totnode != 0 && (update_flag & (PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers))) {
|
||||
pbvh_update_draw_buffers(pbvh, nodes, totnode, update_flag);
|
||||
if (!nodes.is_empty() && (update_flag & (PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers))) {
|
||||
pbvh_update_draw_buffers(pbvh, nodes, update_flag);
|
||||
}
|
||||
MEM_SAFE_FREE(nodes);
|
||||
|
||||
/* Draw visible nodes. */
|
||||
PBVHDrawSearchData draw_data{};
|
||||
draw_data.frustum = draw_frustum;
|
||||
draw_data.accum_update_flag = 0;
|
||||
BKE_pbvh_search_gather(pbvh, pbvh_draw_search_cb, &draw_data, &nodes, &totnode);
|
||||
nodes = blender::bke::pbvh::search_gather(pbvh, pbvh_draw_search_cb, &draw_data);
|
||||
|
||||
PBVH_GPU_Args args;
|
||||
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
PBVHNode *node = nodes[i];
|
||||
for (PBVHNode *node : nodes) {
|
||||
if (!(node->flag & PBVH_FullyHidden)) {
|
||||
pbvh_draw_args_init(pbvh, &args, node);
|
||||
|
||||
draw_fn(user_data, node->draw_batches, &args);
|
||||
}
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
}
|
||||
|
||||
void BKE_pbvh_draw_debug_cb(PBVH *pbvh,
|
||||
@@ -3357,36 +3283,6 @@ void BKE_pbvh_node_free_proxies(PBVHNode *node)
|
||||
node->proxy_count = 0;
|
||||
}
|
||||
|
||||
void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot)
|
||||
{
|
||||
PBVHNode **array = nullptr;
|
||||
int tot = 0, space = 0;
|
||||
|
||||
for (int n = 0; n < pbvh->totnode; n++) {
|
||||
PBVHNode *node = pbvh->nodes + n;
|
||||
|
||||
if (node->proxy_count > 0) {
|
||||
if (tot == space) {
|
||||
/* resize array if needed */
|
||||
space = (tot == 0) ? 32 : space * 2;
|
||||
array = static_cast<PBVHNode **>(
|
||||
MEM_recallocN_id(array, sizeof(PBVHNode *) * space, __func__));
|
||||
}
|
||||
|
||||
array[tot] = node;
|
||||
tot++;
|
||||
}
|
||||
}
|
||||
|
||||
if (tot == 0 && array) {
|
||||
MEM_freeN(array);
|
||||
array = nullptr;
|
||||
}
|
||||
|
||||
*r_array = array;
|
||||
*r_tot = tot;
|
||||
}
|
||||
|
||||
PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node)
|
||||
{
|
||||
|
||||
@@ -3399,13 +3295,11 @@ PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node)
|
||||
|
||||
void BKE_pbvh_node_color_buffer_free(PBVH *pbvh)
|
||||
{
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
MEM_SAFE_FREE(nodes[i]->color_buffer.color);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr);
|
||||
|
||||
for (PBVHNode *node : nodes) {
|
||||
MEM_SAFE_FREE(node->color_buffer.color);
|
||||
}
|
||||
MEM_SAFE_FREE(nodes);
|
||||
}
|
||||
|
||||
void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int mode)
|
||||
@@ -3934,3 +3828,41 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH *pbvh, Mesh *mesh)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace blender::bke::pbvh {
|
||||
Vector<PBVHNode *> search_gather(PBVH *pbvh,
|
||||
BKE_pbvh_SearchCallback scb,
|
||||
void *search_data,
|
||||
PBVHNodeFlags leaf_flag)
|
||||
{
|
||||
PBVHIter iter;
|
||||
Vector<PBVHNode *> nodes;
|
||||
|
||||
pbvh_iter_begin(&iter, pbvh, scb, search_data);
|
||||
|
||||
PBVHNode *node;
|
||||
while ((node = pbvh_iter_next(&iter, leaf_flag))) {
|
||||
if (node->flag & leaf_flag) {
|
||||
nodes.append(node);
|
||||
}
|
||||
}
|
||||
|
||||
pbvh_iter_end(&iter);
|
||||
return nodes;
|
||||
}
|
||||
|
||||
Vector<PBVHNode *> gather_proxies(PBVH *pbvh)
|
||||
{
|
||||
Vector<PBVHNode *> array;
|
||||
|
||||
for (int n = 0; n < pbvh->totnode; n++) {
|
||||
PBVHNode *node = pbvh->nodes + n;
|
||||
|
||||
if (node->proxy_count > 0) {
|
||||
array.append(node);
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
} // namespace blender::bke::pbvh
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "BLI_heap_simple.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_memarena.h"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_DerivedMesh.h"
|
||||
@@ -22,6 +23,8 @@
|
||||
#include "bmesh.h"
|
||||
#include "pbvh_intern.hh"
|
||||
|
||||
using blender::Span;
|
||||
|
||||
/* Avoid skinny faces */
|
||||
#define USE_EDGEQUEUE_EVEN_SUBDIV
|
||||
#ifdef USE_EDGEQUEUE_EVEN_SUBDIV
|
||||
@@ -1659,11 +1662,9 @@ bool pbvh_bmesh_node_nearest_to_ray(PBVHNode *node,
|
||||
return hit;
|
||||
}
|
||||
|
||||
void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode)
|
||||
void pbvh_bmesh_normals_update(Span<PBVHNode *> nodes)
|
||||
{
|
||||
for (int n = 0; n < totnode; n++) {
|
||||
PBVHNode *node = nodes[n];
|
||||
|
||||
for (PBVHNode *node : nodes) {
|
||||
if (node->flag & PBVH_UpdateNormals) {
|
||||
GSetIterator gs_iter;
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
/** \file
|
||||
* \ingroup bke
|
||||
*/
|
||||
@@ -281,7 +283,7 @@ bool pbvh_bmesh_node_nearest_to_ray(PBVHNode *node,
|
||||
float *dist_sq,
|
||||
bool use_original);
|
||||
|
||||
void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode);
|
||||
void pbvh_bmesh_normals_update(blender::Span<PBVHNode *> nodes);
|
||||
|
||||
/* pbvh_pixels.hh */
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "BLI_bitmap.h"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
@@ -43,6 +44,8 @@
|
||||
/* For undo push. */
|
||||
#include "sculpt_intern.hh"
|
||||
|
||||
using blender::Vector;
|
||||
|
||||
/* Return true if the element should be hidden/shown. */
|
||||
static bool is_effected(PartialVisArea area,
|
||||
float planes[4][4],
|
||||
@@ -296,8 +299,7 @@ static void clip_planes_from_rect(bContext *C,
|
||||
* inside the clip_planes volume. If mode is outside, get all nodes
|
||||
* that lie at least partially outside the volume. If showing all, get
|
||||
* all nodes. */
|
||||
static void get_pbvh_nodes(
|
||||
PBVH *pbvh, PBVHNode ***nodes, int *totnode, float clip_planes[4][4], PartialVisArea mode)
|
||||
static Vector<PBVHNode *> get_pbvh_nodes(PBVH *pbvh, float clip_planes[4][4], PartialVisArea mode)
|
||||
{
|
||||
BKE_pbvh_SearchCallback cb = nullptr;
|
||||
|
||||
@@ -317,7 +319,7 @@ static void get_pbvh_nodes(
|
||||
PBVHFrustumPlanes frustum{};
|
||||
frustum.planes = clip_planes;
|
||||
frustum.num_planes = 4;
|
||||
BKE_pbvh_search_gather(pbvh, cb, &frustum, nodes, totnode);
|
||||
return blender::bke::pbvh::search_gather(pbvh, cb, &frustum);
|
||||
}
|
||||
|
||||
static int hide_show_exec(bContext *C, wmOperator *op)
|
||||
@@ -329,11 +331,9 @@ static int hide_show_exec(bContext *C, wmOperator *op)
|
||||
PartialVisAction action;
|
||||
PartialVisArea area;
|
||||
PBVH *pbvh;
|
||||
PBVHNode **nodes;
|
||||
PBVHType pbvh_type;
|
||||
float clip_planes[4][4];
|
||||
rcti rect;
|
||||
int totnode;
|
||||
|
||||
/* Read operator properties. */
|
||||
action = PartialVisAction(RNA_enum_get(op->ptr, "action"));
|
||||
@@ -345,7 +345,7 @@ static int hide_show_exec(bContext *C, wmOperator *op)
|
||||
pbvh = BKE_sculpt_object_pbvh_ensure(depsgraph, ob);
|
||||
BLI_assert(BKE_object_sculpt_pbvh_get(ob) == pbvh);
|
||||
|
||||
get_pbvh_nodes(pbvh, &nodes, &totnode, clip_planes, area);
|
||||
Vector<PBVHNode *> nodes = get_pbvh_nodes(pbvh, clip_planes, area);
|
||||
pbvh_type = BKE_pbvh_type(pbvh);
|
||||
|
||||
negate_m4(clip_planes);
|
||||
@@ -360,24 +360,20 @@ static int hide_show_exec(bContext *C, wmOperator *op)
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
for (PBVHNode *node : nodes) {
|
||||
switch (pbvh_type) {
|
||||
case PBVH_FACES:
|
||||
partialvis_update_mesh(ob, pbvh, nodes[i], action, area, clip_planes);
|
||||
partialvis_update_mesh(ob, pbvh, node, action, area, clip_planes);
|
||||
break;
|
||||
case PBVH_GRIDS:
|
||||
partialvis_update_grids(depsgraph, ob, pbvh, nodes[i], action, area, clip_planes);
|
||||
partialvis_update_grids(depsgraph, ob, pbvh, node, action, area, clip_planes);
|
||||
break;
|
||||
case PBVH_BMESH:
|
||||
partialvis_update_bmesh(ob, pbvh, nodes[i], action, area, clip_planes);
|
||||
partialvis_update_bmesh(ob, pbvh, node, action, area, clip_planes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nodes) {
|
||||
MEM_freeN(nodes);
|
||||
}
|
||||
|
||||
/* End undo. */
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
|
||||
@@ -21,8 +21,10 @@
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_polyfill_2d.h"
|
||||
#include "BLI_rect.h"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_task.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "BKE_brush.h"
|
||||
#include "BKE_ccg.h"
|
||||
@@ -54,6 +56,9 @@
|
||||
/* For undo push. */
|
||||
#include "sculpt_intern.hh"
|
||||
|
||||
using blender::Span;
|
||||
using blender::Vector;
|
||||
|
||||
static const EnumPropertyItem mode_items[] = {
|
||||
{PAINT_MASK_FLOOD_VALUE,
|
||||
"VALUE",
|
||||
@@ -86,7 +91,7 @@ static void mask_flood_fill_set_elem(float *elem, PaintMaskFloodMode mode, float
|
||||
struct MaskTaskData {
|
||||
Object *ob;
|
||||
PBVH *pbvh;
|
||||
PBVHNode **nodes;
|
||||
Span<PBVHNode *> nodes;
|
||||
bool multires;
|
||||
|
||||
PaintMaskFloodMode mode;
|
||||
@@ -136,8 +141,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||
PBVH *pbvh;
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
Vector<PBVHNode *> nodes;
|
||||
bool multires;
|
||||
|
||||
PaintMaskFloodMode mode = PaintMaskFloodMode(RNA_enum_get(op->ptr, "mode"));
|
||||
@@ -150,7 +154,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
|
||||
pbvh = ob->sculpt->pbvh;
|
||||
multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS);
|
||||
|
||||
BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr);
|
||||
|
||||
SCULPT_undo_push_begin(ob, op);
|
||||
|
||||
@@ -163,8 +167,8 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
|
||||
data.value = value;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, mask_flood_fill_task_cb, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, mask_flood_fill_task_cb, &settings);
|
||||
|
||||
if (multires) {
|
||||
multires_mark_as_modified(depsgraph, ob, MULTIRES_COORDS_MODIFIED);
|
||||
@@ -174,10 +178,6 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
|
||||
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
if (nodes) {
|
||||
MEM_freeN(nodes);
|
||||
}
|
||||
|
||||
SCULPT_tag_update_overlays(C);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -288,8 +288,7 @@ struct SculptGestureContext {
|
||||
LineGestureData line;
|
||||
|
||||
/* Task Callback Data. */
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
Vector<PBVHNode *> nodes;
|
||||
};
|
||||
|
||||
struct SculptGestureOperation {
|
||||
@@ -366,7 +365,7 @@ static void sculpt_gesture_lasso_px_cb(int x, int x_end, int y, void *user_data)
|
||||
|
||||
static SculptGestureContext *sculpt_gesture_init_from_lasso(bContext *C, wmOperator *op)
|
||||
{
|
||||
SculptGestureContext *sgcontext = MEM_cnew<SculptGestureContext>(__func__);
|
||||
SculptGestureContext *sgcontext = MEM_new<SculptGestureContext>(__func__);
|
||||
sgcontext->shape_type = SCULPT_GESTURE_SHAPE_LASSO;
|
||||
|
||||
sculpt_gesture_context_init_common(C, op, sgcontext);
|
||||
@@ -417,7 +416,7 @@ static SculptGestureContext *sculpt_gesture_init_from_lasso(bContext *C, wmOpera
|
||||
|
||||
static SculptGestureContext *sculpt_gesture_init_from_box(bContext *C, wmOperator *op)
|
||||
{
|
||||
SculptGestureContext *sgcontext = MEM_cnew<SculptGestureContext>(__func__);
|
||||
SculptGestureContext *sgcontext = MEM_new<SculptGestureContext>(__func__);
|
||||
sgcontext->shape_type = SCULPT_GESTURE_SHAPE_BOX;
|
||||
|
||||
sculpt_gesture_context_init_common(C, op, sgcontext);
|
||||
@@ -493,7 +492,7 @@ static void sculpt_gesture_line_calculate_plane_points(SculptGestureContext *sgc
|
||||
|
||||
static SculptGestureContext *sculpt_gesture_init_from_line(bContext *C, wmOperator *op)
|
||||
{
|
||||
SculptGestureContext *sgcontext = MEM_cnew<SculptGestureContext>(__func__);
|
||||
SculptGestureContext *sgcontext = MEM_new<SculptGestureContext>(__func__);
|
||||
sgcontext->shape_type = SCULPT_GESTURE_SHAPE_LINE;
|
||||
|
||||
sculpt_gesture_context_init_common(C, op, sgcontext);
|
||||
@@ -542,8 +541,7 @@ static void sculpt_gesture_context_free(SculptGestureContext *sgcontext)
|
||||
MEM_SAFE_FREE(sgcontext->lasso.mask_px);
|
||||
MEM_SAFE_FREE(sgcontext->gesture_points);
|
||||
MEM_SAFE_FREE(sgcontext->operation);
|
||||
MEM_SAFE_FREE(sgcontext->nodes);
|
||||
MEM_SAFE_FREE(sgcontext);
|
||||
MEM_delete(sgcontext);
|
||||
}
|
||||
|
||||
static void flip_plane(float out[4], const float in[4], const char symm)
|
||||
@@ -587,7 +585,8 @@ static void sculpt_gesture_flip_for_symmetry_pass(SculptGestureContext *sgcontex
|
||||
flip_plane(sgcontext->line.side_plane[1], sgcontext->line.true_side_plane[1], symmpass);
|
||||
}
|
||||
|
||||
static void sculpt_gesture_update_effected_nodes_by_line_plane(SculptGestureContext *sgcontext)
|
||||
static Vector<PBVHNode *> sculpt_gesture_update_effected_nodes_by_line_plane(
|
||||
SculptGestureContext *sgcontext)
|
||||
{
|
||||
SculptSession *ss = sgcontext->ss;
|
||||
float clip_planes[3][4];
|
||||
@@ -599,11 +598,8 @@ static void sculpt_gesture_update_effected_nodes_by_line_plane(SculptGestureCont
|
||||
frustum.planes = clip_planes;
|
||||
frustum.num_planes = sgcontext->line.use_side_planes ? 3 : 1;
|
||||
|
||||
BKE_pbvh_search_gather(ss->pbvh,
|
||||
BKE_pbvh_node_frustum_contain_AABB,
|
||||
&frustum,
|
||||
&sgcontext->nodes,
|
||||
&sgcontext->totnode);
|
||||
return sgcontext->nodes = blender::bke::pbvh::search_gather(
|
||||
ss->pbvh, BKE_pbvh_node_frustum_contain_AABB, &frustum);
|
||||
}
|
||||
|
||||
static void sculpt_gesture_update_effected_nodes_by_clip_planes(SculptGestureContext *sgcontext)
|
||||
@@ -617,11 +613,8 @@ static void sculpt_gesture_update_effected_nodes_by_clip_planes(SculptGestureCon
|
||||
frustum.planes = clip_planes;
|
||||
frustum.num_planes = 4;
|
||||
|
||||
BKE_pbvh_search_gather(ss->pbvh,
|
||||
BKE_pbvh_node_frustum_contain_AABB,
|
||||
&frustum,
|
||||
&sgcontext->nodes,
|
||||
&sgcontext->totnode);
|
||||
sgcontext->nodes = blender::bke::pbvh::search_gather(
|
||||
ss->pbvh, BKE_pbvh_node_frustum_contain_AABB, &frustum);
|
||||
}
|
||||
|
||||
static void sculpt_gesture_update_effected_nodes(SculptGestureContext *sgcontext)
|
||||
@@ -716,8 +709,6 @@ static void sculpt_gesture_apply(bContext *C, SculptGestureContext *sgcontext, w
|
||||
sculpt_gesture_update_effected_nodes(sgcontext);
|
||||
|
||||
operation->sculpt_gesture_apply_for_symmetry_pass(C, sgcontext);
|
||||
|
||||
MEM_SAFE_FREE(sgcontext->nodes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -773,9 +764,9 @@ static void sculpt_gesture_face_set_apply_for_symmetry_pass(bContext * /*C*/,
|
||||
SculptGestureContext *sgcontext)
|
||||
{
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->nodes.size());
|
||||
BLI_task_parallel_range(
|
||||
0, sgcontext->totnode, sgcontext, face_set_gesture_apply_task_cb, &settings);
|
||||
0, sgcontext->nodes.size(), sgcontext, face_set_gesture_apply_task_cb, &settings);
|
||||
}
|
||||
|
||||
static void sculpt_gesture_face_set_end(bContext * /*C*/, SculptGestureContext *sgcontext)
|
||||
@@ -862,8 +853,9 @@ static void sculpt_gesture_mask_apply_for_symmetry_pass(bContext * /*C*/,
|
||||
SculptGestureContext *sgcontext)
|
||||
{
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->totnode);
|
||||
BLI_task_parallel_range(0, sgcontext->totnode, sgcontext, mask_gesture_apply_task_cb, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->nodes.size());
|
||||
BLI_task_parallel_range(
|
||||
0, sgcontext->nodes.size(), sgcontext, mask_gesture_apply_task_cb, &settings);
|
||||
}
|
||||
|
||||
static void sculpt_gesture_mask_end(bContext *C, SculptGestureContext *sgcontext)
|
||||
@@ -1563,12 +1555,12 @@ static void sculpt_gesture_project_apply_for_symmetry_pass(bContext * /*C*/,
|
||||
SculptGestureContext *sgcontext)
|
||||
{
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->nodes.size());
|
||||
|
||||
switch (sgcontext->shape_type) {
|
||||
case SCULPT_GESTURE_SHAPE_LINE:
|
||||
BLI_task_parallel_range(
|
||||
0, sgcontext->totnode, sgcontext, project_line_gesture_apply_task_cb, &settings);
|
||||
0, sgcontext->nodes.size(), sgcontext, project_line_gesture_apply_task_cb, &settings);
|
||||
break;
|
||||
case SCULPT_GESTURE_SHAPE_LASSO:
|
||||
case SCULPT_GESTURE_SHAPE_BOX:
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_task.h"
|
||||
#include "BLI_task.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
@@ -2254,21 +2255,20 @@ static void do_wpaint_brush_calc_average_weight_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
static void calculate_average_weight(SculptThreadedTaskData *data,
|
||||
PBVHNode ** /*nodes*/,
|
||||
int totnode)
|
||||
static void calculate_average_weight(SculptThreadedTaskData *data, Span<PBVHNode *> nodes)
|
||||
{
|
||||
WPaintAverageAccum *accum = (WPaintAverageAccum *)MEM_mallocN(sizeof(*accum) * totnode,
|
||||
WPaintAverageAccum *accum = (WPaintAverageAccum *)MEM_mallocN(sizeof(*accum) * nodes.size(),
|
||||
__func__);
|
||||
data->custom_data = accum;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, data, do_wpaint_brush_calc_average_weight_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(
|
||||
0, nodes.size(), data, do_wpaint_brush_calc_average_weight_cb_ex, &settings);
|
||||
|
||||
uint accum_len = 0;
|
||||
double accum_weight = 0.0;
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
accum_len += accum[i].len;
|
||||
accum_weight += accum[i].value;
|
||||
}
|
||||
@@ -2287,8 +2287,7 @@ static void wpaint_paint_leaves(bContext *C,
|
||||
WPaintData *wpd,
|
||||
WeightPaintInfo *wpi,
|
||||
Mesh *me,
|
||||
PBVHNode **nodes,
|
||||
int totnode)
|
||||
Span<PBVHNode *> nodes)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
const Brush *brush = ob->sculpt->cache->brush;
|
||||
@@ -2311,31 +2310,33 @@ static void wpaint_paint_leaves(bContext *C,
|
||||
/* NOTE: current mirroring code cannot be run in parallel */
|
||||
TaskParallelSettings settings;
|
||||
const bool use_threading = !ME_USING_MIRROR_X_VERTEX_GROUPS(me);
|
||||
BKE_pbvh_parallel_range_settings(&settings, use_threading, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, use_threading, nodes.size());
|
||||
|
||||
switch ((eBrushWeightPaintTool)brush->weightpaint_tool) {
|
||||
case WPAINT_TOOL_AVERAGE:
|
||||
calculate_average_weight(&data, nodes, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_wpaint_brush_draw_task_cb_ex, &settings);
|
||||
calculate_average_weight(&data, nodes);
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_wpaint_brush_draw_task_cb_ex, &settings);
|
||||
break;
|
||||
case WPAINT_TOOL_SMEAR:
|
||||
BLI_task_parallel_range(0, totnode, &data, do_wpaint_brush_smear_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_wpaint_brush_smear_task_cb_ex, &settings);
|
||||
break;
|
||||
case WPAINT_TOOL_BLUR:
|
||||
BLI_task_parallel_range(0, totnode, &data, do_wpaint_brush_blur_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_wpaint_brush_blur_task_cb_ex, &settings);
|
||||
break;
|
||||
case WPAINT_TOOL_DRAW:
|
||||
BLI_task_parallel_range(0, totnode, &data, do_wpaint_brush_draw_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_wpaint_brush_draw_task_cb_ex, &settings);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static PBVHNode **vwpaint_pbvh_gather_generic(
|
||||
Object *ob, VPaint *wp, Sculpt *sd, Brush *brush, int *r_totnode)
|
||||
static Vector<PBVHNode *> vwpaint_pbvh_gather_generic(Object *ob,
|
||||
VPaint *wp,
|
||||
Sculpt *sd,
|
||||
Brush *brush)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
const bool use_normal = vwpaint_use_normal(wp);
|
||||
PBVHNode **nodes = nullptr;
|
||||
Vector<PBVHNode *> nodes;
|
||||
|
||||
/* Build a list of all nodes that are potentially within the brush's area of influence */
|
||||
if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) {
|
||||
@@ -2345,10 +2346,10 @@ static PBVHNode **vwpaint_pbvh_gather_generic(
|
||||
data.radius_squared = ss->cache->radius_squared;
|
||||
data.original = true;
|
||||
|
||||
BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode);
|
||||
nodes = blender::bke::pbvh::search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data);
|
||||
|
||||
if (use_normal) {
|
||||
SCULPT_pbvh_calc_area_normal(
|
||||
brush, ob, nodes, *r_totnode, true, ss->cache->sculpt_normal_symm);
|
||||
SCULPT_pbvh_calc_area_normal(brush, ob, nodes, true, ss->cache->sculpt_normal_symm);
|
||||
}
|
||||
else {
|
||||
zero_v3(ss->cache->sculpt_normal_symm);
|
||||
@@ -2365,7 +2366,8 @@ static PBVHNode **vwpaint_pbvh_gather_generic(
|
||||
data.original = true;
|
||||
data.dist_ray_to_aabb_precalc = &dist_ray_to_aabb_precalc;
|
||||
|
||||
BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_circle_cb, &data, &nodes, r_totnode);
|
||||
nodes = blender::bke::pbvh::search_gather(ss->pbvh, SCULPT_search_circle_cb, &data);
|
||||
|
||||
if (use_normal) {
|
||||
copy_v3_v3(ss->cache->sculpt_normal_symm, ss->cache->view_normal);
|
||||
}
|
||||
@@ -2393,14 +2395,9 @@ static void wpaint_do_paint(bContext *C,
|
||||
ss->cache->radial_symmetry_pass = i;
|
||||
SCULPT_cache_calc_brushdata_symm(ss->cache, symm, axis, angle);
|
||||
|
||||
int totnode;
|
||||
PBVHNode **nodes = vwpaint_pbvh_gather_generic(ob, wp, sd, brush, &totnode);
|
||||
Vector<PBVHNode *> nodes = vwpaint_pbvh_gather_generic(ob, wp, sd, brush);
|
||||
|
||||
wpaint_paint_leaves(C, ob, sd, wp, wpd, wpi, me, nodes, totnode);
|
||||
|
||||
if (nodes) {
|
||||
MEM_freeN(nodes);
|
||||
}
|
||||
wpaint_paint_leaves(C, ob, sd, wp, wpd, wpi, me, nodes);
|
||||
}
|
||||
|
||||
static void wpaint_do_radial_symmetry(bContext *C,
|
||||
@@ -2948,8 +2945,7 @@ static void do_vpaint_brush_blur_loops(bContext *C,
|
||||
VPaintData<Color, Traits, ATTR_DOMAIN_CORNER> *vpd,
|
||||
Object *ob,
|
||||
Mesh *me,
|
||||
PBVHNode **nodes,
|
||||
int totnode,
|
||||
Span<PBVHNode *> nodes,
|
||||
Color *lcol)
|
||||
{
|
||||
using Blend = typename Traits::BlendType;
|
||||
@@ -2966,7 +2962,7 @@ static void do_vpaint_brush_blur_loops(bContext *C,
|
||||
const blender::VArray<bool> select_poly = me->attributes().lookup_or_default<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) {
|
||||
blender::threading::parallel_for(nodes.index_range(), 1LL, [&](IndexRange range) {
|
||||
for (int n : range) {
|
||||
const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh);
|
||||
const bool has_grids = (pbvh_type == PBVH_GRIDS);
|
||||
@@ -3092,8 +3088,7 @@ static void do_vpaint_brush_blur_verts(bContext *C,
|
||||
VPaintData<Color, Traits, ATTR_DOMAIN_POINT> *vpd,
|
||||
Object *ob,
|
||||
Mesh *me,
|
||||
PBVHNode **nodes,
|
||||
int totnode,
|
||||
Span<PBVHNode *> nodes,
|
||||
Color *lcol)
|
||||
{
|
||||
using Blend = typename Traits::BlendType;
|
||||
@@ -3110,7 +3105,7 @@ static void do_vpaint_brush_blur_verts(bContext *C,
|
||||
const blender::VArray<bool> select_poly = me->attributes().lookup_or_default<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) {
|
||||
blender::threading::parallel_for(nodes.index_range(), 1LL, [&](IndexRange range) {
|
||||
for (int n : range) {
|
||||
const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh);
|
||||
const bool has_grids = (pbvh_type == PBVH_GRIDS);
|
||||
@@ -3237,8 +3232,7 @@ static void do_vpaint_brush_smear(bContext *C,
|
||||
VPaintData<Color, Traits, domain> *vpd,
|
||||
Object *ob,
|
||||
Mesh *me,
|
||||
PBVHNode **nodes,
|
||||
int totnode,
|
||||
Span<PBVHNode *> nodes,
|
||||
Color *lcol)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
@@ -3259,7 +3253,7 @@ static void do_vpaint_brush_smear(bContext *C,
|
||||
const blender::VArray<bool> select_poly = me->attributes().lookup_or_default<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) {
|
||||
blender::threading::parallel_for(nodes.index_range(), 1LL, [&](IndexRange range) {
|
||||
for (int n : range) {
|
||||
float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
|
||||
|
||||
@@ -3417,8 +3411,7 @@ static void calculate_average_color(VPaintData<Color, Traits, domain> *vpd,
|
||||
Mesh *me,
|
||||
const Brush *brush,
|
||||
Color *lcol,
|
||||
PBVHNode **nodes,
|
||||
int totnode)
|
||||
Span<PBVHNode *> nodes)
|
||||
{
|
||||
using Blend = typename Traits::BlendType;
|
||||
|
||||
@@ -3426,8 +3419,8 @@ static void calculate_average_color(VPaintData<Color, Traits, domain> *vpd,
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
|
||||
VPaintAverageAccum<Blend> *accum = (VPaintAverageAccum<Blend> *)MEM_mallocN(
|
||||
sizeof(*accum) * totnode, __func__);
|
||||
blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) {
|
||||
sizeof(*accum) * nodes.size(), __func__);
|
||||
blender::threading::parallel_for(nodes.index_range(), 1LL, [&](IndexRange range) {
|
||||
for (int n : range) {
|
||||
SculptSession *ss = ob->sculpt;
|
||||
const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh);
|
||||
@@ -3487,7 +3480,7 @@ static void calculate_average_color(VPaintData<Color, Traits, domain> *vpd,
|
||||
Blend accum_value[3] = {0};
|
||||
Color blend(0, 0, 0, 0);
|
||||
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
accum_len += accum[i].len;
|
||||
accum_value[0] += accum[i].value[0];
|
||||
accum_value[1] += accum[i].value[1];
|
||||
@@ -3528,8 +3521,7 @@ static void vpaint_do_draw(bContext *C,
|
||||
VPaintData<Color, Traits, domain> *vpd,
|
||||
Object *ob,
|
||||
Mesh *me,
|
||||
PBVHNode **nodes,
|
||||
int totnode,
|
||||
Span<PBVHNode *> nodes,
|
||||
Color *lcol)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
@@ -3545,7 +3537,7 @@ static void vpaint_do_draw(bContext *C,
|
||||
const blender::VArray<bool> select_poly = me->attributes().lookup_or_default<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) {
|
||||
blender::threading::parallel_for(nodes.index_range(), 1LL, [&](IndexRange range) {
|
||||
for (int n : range) {
|
||||
const bool has_grids = (pbvh_type == PBVH_GRIDS);
|
||||
const SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap;
|
||||
@@ -3671,15 +3663,14 @@ static void vpaint_do_blur(bContext *C,
|
||||
VPaintData<Color, Traits, domain> *vpd,
|
||||
Object *ob,
|
||||
Mesh *me,
|
||||
PBVHNode **nodes,
|
||||
int totnode,
|
||||
Span<PBVHNode *> nodes,
|
||||
Color *lcol)
|
||||
{
|
||||
if constexpr (domain == ATTR_DOMAIN_POINT) {
|
||||
do_vpaint_brush_blur_verts<Color, Traits>(C, sd, vp, vpd, ob, me, nodes, totnode, lcol);
|
||||
do_vpaint_brush_blur_verts<Color, Traits>(C, sd, vp, vpd, ob, me, nodes, lcol);
|
||||
}
|
||||
else {
|
||||
do_vpaint_brush_blur_loops<Color, Traits>(C, sd, vp, vpd, ob, me, nodes, totnode, lcol);
|
||||
do_vpaint_brush_blur_loops<Color, Traits>(C, sd, vp, vpd, ob, me, nodes, lcol);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3691,28 +3682,27 @@ static void vpaint_paint_leaves(bContext *C,
|
||||
Object *ob,
|
||||
Mesh *me,
|
||||
Color *lcol,
|
||||
PBVHNode **nodes,
|
||||
int totnode)
|
||||
Span<PBVHNode *> nodes)
|
||||
{
|
||||
|
||||
for (int i : IndexRange(totnode)) {
|
||||
SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_COLOR);
|
||||
for (PBVHNode *node : nodes) {
|
||||
SCULPT_undo_push_node(ob, node, SCULPT_UNDO_COLOR);
|
||||
}
|
||||
|
||||
const Brush *brush = ob->sculpt->cache->brush;
|
||||
|
||||
switch ((eBrushVertexPaintTool)brush->vertexpaint_tool) {
|
||||
case VPAINT_TOOL_AVERAGE:
|
||||
calculate_average_color<Color, Traits, domain>(vpd, ob, me, brush, lcol, nodes, totnode);
|
||||
calculate_average_color<Color, Traits, domain>(vpd, ob, me, brush, lcol, nodes);
|
||||
break;
|
||||
case VPAINT_TOOL_DRAW:
|
||||
vpaint_do_draw<Color, Traits, domain>(C, sd, vp, vpd, ob, me, nodes, totnode, lcol);
|
||||
vpaint_do_draw<Color, Traits, domain>(C, sd, vp, vpd, ob, me, nodes, lcol);
|
||||
break;
|
||||
case VPAINT_TOOL_BLUR:
|
||||
vpaint_do_blur<Color, Traits, domain>(C, sd, vp, vpd, ob, me, nodes, totnode, lcol);
|
||||
vpaint_do_blur<Color, Traits, domain>(C, sd, vp, vpd, ob, me, nodes, lcol);
|
||||
break;
|
||||
case VPAINT_TOOL_SMEAR:
|
||||
do_vpaint_brush_smear<Color, Traits, domain>(C, sd, vp, vpd, ob, me, nodes, totnode, lcol);
|
||||
do_vpaint_brush_smear<Color, Traits, domain>(C, sd, vp, vpd, ob, me, nodes, lcol);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -3736,8 +3726,7 @@ static void vpaint_do_paint(bContext *C,
|
||||
ss->cache->radial_symmetry_pass = i;
|
||||
SCULPT_cache_calc_brushdata_symm(ss->cache, symm, axis, angle);
|
||||
|
||||
int totnode;
|
||||
PBVHNode **nodes = vwpaint_pbvh_gather_generic(ob, vp, sd, brush, &totnode);
|
||||
Vector<PBVHNode *> nodes = vwpaint_pbvh_gather_generic(ob, vp, sd, brush);
|
||||
|
||||
bke::GSpanAttributeWriter attribute = me->attributes_for_write().lookup_for_write_span(
|
||||
me->active_color_attribute);
|
||||
@@ -3746,12 +3735,9 @@ static void vpaint_do_paint(bContext *C,
|
||||
Color *color_data = static_cast<Color *>(attribute.span.data());
|
||||
|
||||
/* Paint those leaves. */
|
||||
vpaint_paint_leaves<Color, Traits, domain>(C, sd, vp, vpd, ob, me, color_data, nodes, totnode);
|
||||
vpaint_paint_leaves<Color, Traits, domain>(C, sd, vp, vpd, ob, me, color_data, nodes);
|
||||
|
||||
attribute.finish();
|
||||
if (nodes) {
|
||||
MEM_freeN(nodes);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Color, typename Traits, eAttrDomain domain>
|
||||
|
||||
@@ -300,18 +300,17 @@ static void transform_active_color(bContext *C, wmOperator *op, const TransformF
|
||||
CTX_data_ensure_evaluated_depsgraph(C), obact, true, false, true);
|
||||
|
||||
SCULPT_undo_push_begin(obact, op);
|
||||
PBVHNode **nodes;
|
||||
int nodes_num;
|
||||
|
||||
BKE_pbvh_search_gather(obact->sculpt->pbvh, nullptr, nullptr, &nodes, &nodes_num);
|
||||
for (int i : IndexRange(nodes_num)) {
|
||||
SCULPT_undo_push_node(obact, nodes[i], SCULPT_UNDO_COLOR);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(
|
||||
obact->sculpt->pbvh, nullptr, nullptr);
|
||||
for (PBVHNode *node : nodes) {
|
||||
SCULPT_undo_push_node(obact, node, SCULPT_UNDO_COLOR);
|
||||
}
|
||||
|
||||
transform_active_color_data(*BKE_mesh_from_object(obact), transform_fn);
|
||||
|
||||
for (int i : IndexRange(nodes_num)) {
|
||||
BKE_pbvh_node_mark_update_color(nodes[i]);
|
||||
for (PBVHNode *node : nodes) {
|
||||
BKE_pbvh_node_mark_update_color(node);
|
||||
}
|
||||
|
||||
SCULPT_undo_push_end(obact);
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
using blender::float3;
|
||||
using blender::MutableSpan;
|
||||
using blender::Set;
|
||||
using blender::Span;
|
||||
using blender::Vector;
|
||||
|
||||
static float sculpt_calc_radius(ViewContext *vc,
|
||||
@@ -1101,16 +1102,16 @@ PBVHVertRef SCULPT_nearest_vertex_get(
|
||||
Sculpt *sd, Object *ob, const float co[3], float max_distance, bool use_original)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
PBVHNode **nodes = nullptr;
|
||||
int totnode;
|
||||
Vector<PBVHNode *> nodes;
|
||||
|
||||
SculptSearchSphereData data{};
|
||||
data.sd = sd;
|
||||
data.radius_squared = max_distance * max_distance;
|
||||
data.original = use_original;
|
||||
data.center = co;
|
||||
|
||||
BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode);
|
||||
if (totnode == 0) {
|
||||
nodes = blender::bke::pbvh::search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data);
|
||||
if (nodes.is_empty()) {
|
||||
return BKE_pbvh_make_vref(PBVH_REF_NONE);
|
||||
}
|
||||
|
||||
@@ -1126,13 +1127,11 @@ PBVHVertRef SCULPT_nearest_vertex_get(
|
||||
nvtd.nearest_vertex_distance_squared = FLT_MAX;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
settings.func_reduce = nearest_vertex_get_reduce;
|
||||
settings.userdata_chunk = &nvtd;
|
||||
settings.userdata_chunk_size = sizeof(NearestVertexTLSData);
|
||||
BLI_task_parallel_range(0, totnode, &task_data, do_nearest_vertex_get_task_cb, &settings);
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
BLI_task_parallel_range(0, nodes.size(), &task_data, do_nearest_vertex_get_task_cb, &settings);
|
||||
|
||||
return nvtd.nearest_vertex;
|
||||
}
|
||||
@@ -1619,10 +1618,7 @@ static void paint_mesh_restore_co(Sculpt *sd, Object *ob)
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
|
||||
/**
|
||||
* Disable multi-threading when dynamic-topology is enabled. Otherwise,
|
||||
@@ -1636,12 +1632,10 @@ static void paint_mesh_restore_co(Sculpt *sd, Object *ob)
|
||||
data.nodes = nodes;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true && !ss->bm, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, paint_mesh_restore_co_task_cb, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true && !ss->bm, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, paint_mesh_restore_co_task_cb, &settings);
|
||||
|
||||
BKE_pbvh_node_color_buffer_free(ss->pbvh);
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
}
|
||||
|
||||
/*** BVH Tree ***/
|
||||
@@ -2249,8 +2243,7 @@ static void calc_area_normal_and_center_reduce(const void *__restrict /*userdata
|
||||
add_v2_v2_int(join->count_co, anctd->count_co);
|
||||
}
|
||||
|
||||
void SCULPT_calc_area_center(
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_co[3])
|
||||
void SCULPT_calc_area_center(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float r_area_co[3])
|
||||
{
|
||||
const Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
@@ -2263,18 +2256,17 @@ void SCULPT_calc_area_center(
|
||||
data.ob = ob;
|
||||
data.brush = brush;
|
||||
data.nodes = nodes;
|
||||
data.totnode = totnode;
|
||||
data.has_bm_orco = has_bm_orco;
|
||||
data.use_area_cos = true;
|
||||
|
||||
AreaNormalCenterTLSData anctd = {{{0}}};
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
settings.func_reduce = calc_area_normal_and_center_reduce;
|
||||
settings.userdata_chunk = &anctd;
|
||||
settings.userdata_chunk_size = sizeof(AreaNormalCenterTLSData);
|
||||
BLI_task_parallel_range(0, totnode, &data, calc_area_normal_and_center_task_cb, &settings);
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, calc_area_normal_and_center_task_cb, &settings);
|
||||
|
||||
/* For flatten center. */
|
||||
for (n = 0; n < ARRAY_SIZE(anctd.area_cos); n++) {
|
||||
@@ -2297,19 +2289,14 @@ void SCULPT_calc_area_center(
|
||||
}
|
||||
}
|
||||
|
||||
void SCULPT_calc_area_normal(
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3])
|
||||
void SCULPT_calc_area_normal(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float r_area_no[3])
|
||||
{
|
||||
const Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
SCULPT_pbvh_calc_area_normal(brush, ob, nodes, totnode, true, r_area_no);
|
||||
SCULPT_pbvh_calc_area_normal(brush, ob, nodes, true, r_area_no);
|
||||
}
|
||||
|
||||
bool SCULPT_pbvh_calc_area_normal(const Brush *brush,
|
||||
Object *ob,
|
||||
PBVHNode **nodes,
|
||||
int totnode,
|
||||
bool use_threading,
|
||||
float r_area_no[3])
|
||||
bool SCULPT_pbvh_calc_area_normal(
|
||||
const Brush *brush, Object *ob, Span<PBVHNode *> nodes, bool use_threading, float r_area_no[3])
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
const bool has_bm_orco = ss->bm && SCULPT_stroke_is_dynamic_topology(ss, brush);
|
||||
@@ -2320,7 +2307,6 @@ bool SCULPT_pbvh_calc_area_normal(const Brush *brush,
|
||||
data.ob = ob;
|
||||
data.brush = brush;
|
||||
data.nodes = nodes;
|
||||
data.totnode = totnode;
|
||||
data.has_bm_orco = has_bm_orco;
|
||||
data.use_area_nos = true;
|
||||
data.any_vertex_sampled = false;
|
||||
@@ -2328,11 +2314,11 @@ bool SCULPT_pbvh_calc_area_normal(const Brush *brush,
|
||||
AreaNormalCenterTLSData anctd = {{{0}}};
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, use_threading, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, use_threading, nodes.size());
|
||||
settings.func_reduce = calc_area_normal_and_center_reduce;
|
||||
settings.userdata_chunk = &anctd;
|
||||
settings.userdata_chunk_size = sizeof(AreaNormalCenterTLSData);
|
||||
BLI_task_parallel_range(0, totnode, &data, calc_area_normal_and_center_task_cb, &settings);
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, calc_area_normal_and_center_task_cb, &settings);
|
||||
|
||||
/* For area normal. */
|
||||
for (int i = 0; i < ARRAY_SIZE(anctd.area_nos); i++) {
|
||||
@@ -2345,7 +2331,7 @@ bool SCULPT_pbvh_calc_area_normal(const Brush *brush,
|
||||
}
|
||||
|
||||
void SCULPT_calc_area_normal_and_center(
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3])
|
||||
Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float r_area_no[3], float r_area_co[3])
|
||||
{
|
||||
const Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
@@ -2358,7 +2344,6 @@ void SCULPT_calc_area_normal_and_center(
|
||||
data.ob = ob;
|
||||
data.brush = brush;
|
||||
data.nodes = nodes;
|
||||
data.totnode = totnode;
|
||||
data.has_bm_orco = has_bm_orco;
|
||||
data.use_area_cos = true;
|
||||
data.use_area_nos = true;
|
||||
@@ -2366,11 +2351,11 @@ void SCULPT_calc_area_normal_and_center(
|
||||
AreaNormalCenterTLSData anctd = {{{0}}};
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
settings.func_reduce = calc_area_normal_and_center_reduce;
|
||||
settings.userdata_chunk = &anctd;
|
||||
settings.userdata_chunk_size = sizeof(AreaNormalCenterTLSData);
|
||||
BLI_task_parallel_range(0, totnode, &data, calc_area_normal_and_center_task_cb, &settings);
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, calc_area_normal_and_center_task_cb, &settings);
|
||||
|
||||
/* For flatten center. */
|
||||
for (n = 0; n < ARRAY_SIZE(anctd.area_cos); n++) {
|
||||
@@ -2850,13 +2835,11 @@ void SCULPT_clip(Sculpt *sd, SculptSession *ss, float co[3], const float val[3])
|
||||
}
|
||||
}
|
||||
|
||||
static PBVHNode **sculpt_pbvh_gather_cursor_update(Object *ob,
|
||||
Sculpt *sd,
|
||||
bool use_original,
|
||||
int *r_totnode)
|
||||
static Vector<PBVHNode *> sculpt_pbvh_gather_cursor_update(Object *ob,
|
||||
Sculpt *sd,
|
||||
bool use_original)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
PBVHNode **nodes = nullptr;
|
||||
SculptSearchSphereData data{};
|
||||
data.ss = ss;
|
||||
data.sd = sd;
|
||||
@@ -2864,20 +2847,19 @@ static PBVHNode **sculpt_pbvh_gather_cursor_update(Object *ob,
|
||||
data.original = use_original;
|
||||
data.ignore_fully_ineffective = false;
|
||||
data.center = nullptr;
|
||||
BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode);
|
||||
return nodes;
|
||||
|
||||
return blender::bke::pbvh::search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data);
|
||||
}
|
||||
|
||||
static PBVHNode **sculpt_pbvh_gather_generic_intern(Object *ob,
|
||||
Sculpt *sd,
|
||||
const Brush *brush,
|
||||
bool use_original,
|
||||
float radius_scale,
|
||||
int *r_totnode,
|
||||
PBVHNodeFlags flag)
|
||||
static Vector<PBVHNode *> sculpt_pbvh_gather_generic_intern(Object *ob,
|
||||
Sculpt *sd,
|
||||
const Brush *brush,
|
||||
bool use_original,
|
||||
float radius_scale,
|
||||
PBVHNodeFlags flag)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
PBVHNode **nodes = nullptr;
|
||||
Vector<PBVHNode *> nodes;
|
||||
PBVHNodeFlags leaf_flag = PBVH_Leaf;
|
||||
|
||||
if (flag & PBVH_TexLeaf) {
|
||||
@@ -2894,8 +2876,7 @@ static PBVHNode **sculpt_pbvh_gather_generic_intern(Object *ob,
|
||||
data.original = use_original;
|
||||
data.ignore_fully_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK;
|
||||
data.center = nullptr;
|
||||
BKE_pbvh_search_gather_ex(
|
||||
ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode, leaf_flag);
|
||||
nodes = blender::bke::pbvh::search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, leaf_flag);
|
||||
}
|
||||
else {
|
||||
DistRayAABB_Precalc dist_ray_to_aabb_precalc;
|
||||
@@ -2909,37 +2890,27 @@ static PBVHNode **sculpt_pbvh_gather_generic_intern(Object *ob,
|
||||
data.original = use_original;
|
||||
data.dist_ray_to_aabb_precalc = &dist_ray_to_aabb_precalc;
|
||||
data.ignore_fully_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK;
|
||||
BKE_pbvh_search_gather_ex(
|
||||
ss->pbvh, SCULPT_search_circle_cb, &data, &nodes, r_totnode, leaf_flag);
|
||||
nodes = blender::bke::pbvh::search_gather(ss->pbvh, SCULPT_search_circle_cb, &data, leaf_flag);
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
static PBVHNode **sculpt_pbvh_gather_generic(Object *ob,
|
||||
Sculpt *sd,
|
||||
const Brush *brush,
|
||||
bool use_original,
|
||||
float radius_scale,
|
||||
int *r_totnode)
|
||||
static Vector<PBVHNode *> sculpt_pbvh_gather_generic(
|
||||
Object *ob, Sculpt *sd, const Brush *brush, bool use_original, float radius_scale)
|
||||
{
|
||||
return sculpt_pbvh_gather_generic_intern(
|
||||
ob, sd, brush, use_original, radius_scale, r_totnode, PBVH_Leaf);
|
||||
return sculpt_pbvh_gather_generic_intern(ob, sd, brush, use_original, radius_scale, PBVH_Leaf);
|
||||
}
|
||||
|
||||
static PBVHNode **sculpt_pbvh_gather_texpaint(Object *ob,
|
||||
Sculpt *sd,
|
||||
const Brush *brush,
|
||||
bool use_original,
|
||||
float radius_scale,
|
||||
int *r_totnode)
|
||||
static Vector<PBVHNode *> sculpt_pbvh_gather_texpaint(
|
||||
Object *ob, Sculpt *sd, const Brush *brush, bool use_original, float radius_scale)
|
||||
{
|
||||
return sculpt_pbvh_gather_generic_intern(
|
||||
ob, sd, brush, use_original, radius_scale, r_totnode, PBVH_TexLeaf);
|
||||
ob, sd, brush, use_original, radius_scale, PBVH_TexLeaf);
|
||||
}
|
||||
|
||||
/* Calculate primary direction of movement for many brushes. */
|
||||
static void calc_sculpt_normal(
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3])
|
||||
static void calc_sculpt_normal(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float r_area_no[3])
|
||||
{
|
||||
const Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
const SculptSession *ss = ob->sculpt;
|
||||
@@ -2962,7 +2933,7 @@ static void calc_sculpt_normal(
|
||||
break;
|
||||
|
||||
case SCULPT_DISP_DIR_AREA:
|
||||
SCULPT_calc_area_normal(sd, ob, nodes, totnode, r_area_no);
|
||||
SCULPT_calc_area_normal(sd, ob, nodes, r_area_no);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -2970,7 +2941,7 @@ static void calc_sculpt_normal(
|
||||
}
|
||||
}
|
||||
|
||||
static void update_sculpt_normal(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
static void update_sculpt_normal(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
const Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
StrokeCache *cache = ob->sculpt->cache;
|
||||
@@ -2983,7 +2954,7 @@ static void update_sculpt_normal(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
|
||||
|
||||
if (cache->mirror_symmetry_pass == 0 && cache->radial_symmetry_pass == 0 &&
|
||||
(SCULPT_stroke_is_first_brush_step_of_symmetry_pass(cache) || update_normal)) {
|
||||
calc_sculpt_normal(sd, ob, nodes, totnode, cache->sculpt_normal);
|
||||
calc_sculpt_normal(sd, ob, nodes, cache->sculpt_normal);
|
||||
if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
|
||||
project_plane_v3_v3v3(cache->sculpt_normal, cache->sculpt_normal, cache->view_normal);
|
||||
normalize_v3(cache->sculpt_normal);
|
||||
@@ -3222,7 +3193,7 @@ void SCULPT_flip_quat_by_symm_area(float quat[4],
|
||||
}
|
||||
|
||||
void SCULPT_calc_brush_plane(
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3])
|
||||
Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float r_area_no[3], float r_area_co[3])
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -3251,7 +3222,7 @@ void SCULPT_calc_brush_plane(
|
||||
break;
|
||||
|
||||
case SCULPT_DISP_DIR_AREA:
|
||||
SCULPT_calc_area_normal_and_center(sd, ob, nodes, totnode, r_area_no, r_area_co);
|
||||
SCULPT_calc_area_normal_and_center(sd, ob, nodes, r_area_no, r_area_co);
|
||||
if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
|
||||
project_plane_v3_v3v3(r_area_no, r_area_no, ss->cache->view_normal);
|
||||
normalize_v3(r_area_no);
|
||||
@@ -3265,7 +3236,7 @@ void SCULPT_calc_brush_plane(
|
||||
/* For flatten center. */
|
||||
/* Flatten center has not been calculated yet if we are not using the area normal. */
|
||||
if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA) {
|
||||
SCULPT_calc_area_center(sd, ob, nodes, totnode, r_area_co);
|
||||
SCULPT_calc_area_center(sd, ob, nodes, r_area_co);
|
||||
}
|
||||
|
||||
/* For area normal. */
|
||||
@@ -3384,7 +3355,7 @@ static void do_gravity_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
static void do_gravity(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float bstrength)
|
||||
static void do_gravity(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float bstrength)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -3407,8 +3378,8 @@ static void do_gravity(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, fl
|
||||
data.offset = offset;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_gravity_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_gravity_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -3463,16 +3434,14 @@ static void sculpt_topology_update(Sculpt *sd,
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
|
||||
int n, totnode;
|
||||
/* Build a list of all nodes that are potentially within the brush's area of influence. */
|
||||
const bool use_original = sculpt_tool_needs_original(brush->sculpt_tool) ? true :
|
||||
ss->cache->original;
|
||||
const float radius_scale = 1.25f;
|
||||
PBVHNode **nodes = sculpt_pbvh_gather_generic(
|
||||
ob, sd, brush, use_original, radius_scale, &totnode);
|
||||
Vector<PBVHNode *> nodes = sculpt_pbvh_gather_generic(ob, sd, brush, use_original, radius_scale);
|
||||
|
||||
/* Only act if some verts are inside the brush area. */
|
||||
if (totnode == 0) {
|
||||
if (nodes.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3493,16 +3462,14 @@ static void sculpt_topology_update(Sculpt *sd,
|
||||
}
|
||||
}
|
||||
|
||||
for (n = 0; n < totnode; n++) {
|
||||
SCULPT_undo_push_node(ob,
|
||||
nodes[n],
|
||||
brush->sculpt_tool == SCULPT_TOOL_MASK ? SCULPT_UNDO_MASK :
|
||||
SCULPT_UNDO_COORDS);
|
||||
BKE_pbvh_node_mark_update(nodes[n]);
|
||||
for (PBVHNode *node : nodes) {
|
||||
SCULPT_undo_push_node(
|
||||
ob, node, brush->sculpt_tool == SCULPT_TOOL_MASK ? SCULPT_UNDO_MASK : SCULPT_UNDO_COORDS);
|
||||
BKE_pbvh_node_mark_update(node);
|
||||
|
||||
if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
|
||||
BKE_pbvh_node_mark_topology_update(nodes[n]);
|
||||
BKE_pbvh_bmesh_node_save_orig(ss->bm, ss->bm_log, nodes[n], false);
|
||||
BKE_pbvh_node_mark_topology_update(node);
|
||||
BKE_pbvh_bmesh_node_save_orig(ss->bm, ss->bm_log, node, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3516,8 +3483,6 @@ static void sculpt_topology_update(Sculpt *sd,
|
||||
(brush->falloff_shape != PAINT_FALLOFF_SHAPE_SPHERE));
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
|
||||
/* Update average stroke position. */
|
||||
copy_v3_v3(location, ss->cache->true_location);
|
||||
mul_m4_v3(ob->object_to_world, location);
|
||||
@@ -3568,8 +3533,7 @@ static void do_brush_action(Sculpt *sd,
|
||||
PaintModeSettings *paint_mode_settings)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
int totnode, texnodes_num = 0;
|
||||
PBVHNode **nodes, **texnodes = nullptr;
|
||||
Vector<PBVHNode *> nodes, texnodes;
|
||||
|
||||
/* Check for unsupported features. */
|
||||
PBVHType type = BKE_pbvh_type(ss->pbvh);
|
||||
@@ -3589,9 +3553,9 @@ static void do_brush_action(Sculpt *sd,
|
||||
if (sculpt_needs_pbvh_pixels(paint_mode_settings, brush, ob)) {
|
||||
sculpt_pbvh_update_pixels(paint_mode_settings, ss, ob);
|
||||
|
||||
texnodes = sculpt_pbvh_gather_texpaint(ob, sd, brush, use_original, 1.0f, &texnodes_num);
|
||||
texnodes = sculpt_pbvh_gather_texpaint(ob, sd, brush, use_original, 1.0f);
|
||||
|
||||
if (!texnodes_num) {
|
||||
if (texnodes.is_empty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -3600,10 +3564,10 @@ static void do_brush_action(Sculpt *sd,
|
||||
|
||||
if (SCULPT_tool_needs_all_pbvh_nodes(brush)) {
|
||||
/* These brushes need to update all nodes as they are not constrained by the brush radius */
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
}
|
||||
else if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
|
||||
nodes = SCULPT_cloth_brush_affected_nodes_gather(ss, brush, &totnode);
|
||||
nodes = SCULPT_cloth_brush_affected_nodes_gather(ss, brush);
|
||||
}
|
||||
else {
|
||||
float radius_scale = 1.0f;
|
||||
@@ -3618,7 +3582,7 @@ static void do_brush_action(Sculpt *sd,
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_DRAW && brush->flag & BRUSH_ORIGINAL_NORMAL) {
|
||||
radius_scale = 2.0f;
|
||||
}
|
||||
nodes = sculpt_pbvh_gather_generic(ob, sd, brush, use_original, radius_scale, &totnode);
|
||||
nodes = sculpt_pbvh_gather_generic(ob, sd, brush, use_original, radius_scale);
|
||||
}
|
||||
|
||||
/* Draw Face Sets in draw mode makes a single undo push, in alt-smooth mode deforms the
|
||||
@@ -3639,7 +3603,7 @@ static void do_brush_action(Sculpt *sd,
|
||||
|
||||
/* For anchored brushes with spherical falloff, we start off with zero radius, thus we have no
|
||||
* PBVH nodes on the first brush step. */
|
||||
if (totnode ||
|
||||
if (!nodes.is_empty() ||
|
||||
((brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) && (brush->flag & BRUSH_ANCHORED))) {
|
||||
if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
|
||||
/* Initialize auto-masking cache. */
|
||||
@@ -3659,8 +3623,7 @@ static void do_brush_action(Sculpt *sd,
|
||||
}
|
||||
|
||||
/* Only act if some verts are inside the brush area. */
|
||||
if (totnode == 0) {
|
||||
MEM_SAFE_FREE(texnodes);
|
||||
if (nodes.is_empty()) {
|
||||
return;
|
||||
}
|
||||
float location[3];
|
||||
@@ -3673,12 +3636,12 @@ static void do_brush_action(Sculpt *sd,
|
||||
task_data.nodes = nodes;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &task_data, do_brush_action_task_cb, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &task_data, do_brush_action_task_cb, &settings);
|
||||
}
|
||||
|
||||
if (sculpt_brush_needs_normal(ss, sd, brush)) {
|
||||
update_sculpt_normal(sd, ob, nodes, totnode);
|
||||
update_sculpt_normal(sd, ob, nodes);
|
||||
}
|
||||
|
||||
update_brush_local_mat(sd, ob);
|
||||
@@ -3695,7 +3658,7 @@ static void do_brush_action(Sculpt *sd,
|
||||
}
|
||||
SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim);
|
||||
SCULPT_cloth_brush_ensure_nodes_constraints(
|
||||
sd, ob, nodes, totnode, ss->cache->cloth_sim, ss->cache->location, FLT_MAX);
|
||||
sd, ob, nodes, ss->cache->cloth_sim, ss->cache->location, FLT_MAX);
|
||||
}
|
||||
|
||||
bool invert = ss->cache->pen_flip || ss->cache->invert || brush->flag & BRUSH_DIR_IN;
|
||||
@@ -3703,128 +3666,127 @@ static void do_brush_action(Sculpt *sd,
|
||||
/* Apply one type of brush action. */
|
||||
switch (brush->sculpt_tool) {
|
||||
case SCULPT_TOOL_DRAW:
|
||||
SCULPT_do_draw_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_draw_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_SMOOTH:
|
||||
if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_LAPLACIAN) {
|
||||
SCULPT_do_smooth_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_smooth_brush(sd, ob, nodes);
|
||||
}
|
||||
else if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_SURFACE) {
|
||||
SCULPT_do_surface_smooth_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_surface_smooth_brush(sd, ob, nodes);
|
||||
}
|
||||
break;
|
||||
case SCULPT_TOOL_CREASE:
|
||||
SCULPT_do_crease_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_crease_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_BLOB:
|
||||
SCULPT_do_crease_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_crease_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_PINCH:
|
||||
SCULPT_do_pinch_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_pinch_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_INFLATE:
|
||||
SCULPT_do_inflate_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_inflate_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_GRAB:
|
||||
SCULPT_do_grab_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_grab_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_ROTATE:
|
||||
SCULPT_do_rotate_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_rotate_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_SNAKE_HOOK:
|
||||
SCULPT_do_snake_hook_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_snake_hook_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_NUDGE:
|
||||
SCULPT_do_nudge_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_nudge_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_THUMB:
|
||||
SCULPT_do_thumb_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_thumb_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_LAYER:
|
||||
SCULPT_do_layer_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_layer_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_FLATTEN:
|
||||
SCULPT_do_flatten_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_flatten_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_CLAY:
|
||||
SCULPT_do_clay_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_clay_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_CLAY_STRIPS:
|
||||
SCULPT_do_clay_strips_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_clay_strips_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_MULTIPLANE_SCRAPE:
|
||||
SCULPT_do_multiplane_scrape_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_multiplane_scrape_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_CLAY_THUMB:
|
||||
SCULPT_do_clay_thumb_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_clay_thumb_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_FILL:
|
||||
if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
|
||||
SCULPT_do_scrape_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_scrape_brush(sd, ob, nodes);
|
||||
}
|
||||
else {
|
||||
SCULPT_do_fill_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_fill_brush(sd, ob, nodes);
|
||||
}
|
||||
break;
|
||||
case SCULPT_TOOL_SCRAPE:
|
||||
if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
|
||||
SCULPT_do_fill_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_fill_brush(sd, ob, nodes);
|
||||
}
|
||||
else {
|
||||
SCULPT_do_scrape_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_scrape_brush(sd, ob, nodes);
|
||||
}
|
||||
break;
|
||||
case SCULPT_TOOL_MASK:
|
||||
SCULPT_do_mask_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_mask_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_POSE:
|
||||
SCULPT_do_pose_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_pose_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_DRAW_SHARP:
|
||||
SCULPT_do_draw_sharp_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_draw_sharp_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_ELASTIC_DEFORM:
|
||||
SCULPT_do_elastic_deform_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_elastic_deform_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_SLIDE_RELAX:
|
||||
SCULPT_do_slide_relax_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_slide_relax_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_BOUNDARY:
|
||||
SCULPT_do_boundary_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_boundary_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_CLOTH:
|
||||
SCULPT_do_cloth_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_cloth_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_DRAW_FACE_SETS:
|
||||
SCULPT_do_draw_face_sets_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_draw_face_sets_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_DISPLACEMENT_ERASER:
|
||||
SCULPT_do_displacement_eraser_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_displacement_eraser_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_DISPLACEMENT_SMEAR:
|
||||
SCULPT_do_displacement_smear_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_displacement_smear_brush(sd, ob, nodes);
|
||||
break;
|
||||
case SCULPT_TOOL_PAINT:
|
||||
SCULPT_do_paint_brush(paint_mode_settings, sd, ob, nodes, totnode, texnodes, texnodes_num);
|
||||
SCULPT_do_paint_brush(paint_mode_settings, sd, ob, nodes, texnodes);
|
||||
break;
|
||||
case SCULPT_TOOL_SMEAR:
|
||||
SCULPT_do_smear_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_do_smear_brush(sd, ob, nodes);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_MASK) &&
|
||||
brush->autosmooth_factor > 0) {
|
||||
if (brush->flag & BRUSH_INVERSE_SMOOTH_PRESSURE) {
|
||||
SCULPT_smooth(
|
||||
sd, ob, nodes, totnode, brush->autosmooth_factor * (1.0f - ss->cache->pressure), false);
|
||||
SCULPT_smooth(sd, ob, nodes, brush->autosmooth_factor * (1.0f - ss->cache->pressure), false);
|
||||
}
|
||||
else {
|
||||
SCULPT_smooth(sd, ob, nodes, totnode, brush->autosmooth_factor, false);
|
||||
SCULPT_smooth(sd, ob, nodes, brush->autosmooth_factor, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (sculpt_brush_use_topology_rake(ss, brush)) {
|
||||
SCULPT_bmesh_topology_rake(sd, ob, nodes, totnode, brush->topology_rake_factor);
|
||||
SCULPT_bmesh_topology_rake(sd, ob, nodes, brush->topology_rake_factor);
|
||||
}
|
||||
|
||||
if (!SCULPT_tool_can_reuse_automask(brush->sculpt_tool) ||
|
||||
@@ -3838,19 +3800,16 @@ static void do_brush_action(Sculpt *sd,
|
||||
SCULPT_TOOL_CLOTH,
|
||||
SCULPT_TOOL_DRAW_FACE_SETS,
|
||||
SCULPT_TOOL_BOUNDARY)) {
|
||||
do_gravity(sd, ob, nodes, totnode, sd->gravity_factor);
|
||||
do_gravity(sd, ob, nodes, sd->gravity_factor);
|
||||
}
|
||||
|
||||
if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
|
||||
if (SCULPT_stroke_is_main_symmetry_pass(ss->cache)) {
|
||||
SCULPT_cloth_sim_activate_nodes(ss->cache->cloth_sim, nodes, totnode);
|
||||
SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode);
|
||||
SCULPT_cloth_sim_activate_nodes(ss->cache->cloth_sim, nodes);
|
||||
SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes);
|
||||
}
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
MEM_SAFE_FREE(texnodes);
|
||||
|
||||
/* Update average stroke position. */
|
||||
copy_v3_v3(location, ss->cache->true_location);
|
||||
mul_m4_v3(ob->object_to_world, location);
|
||||
@@ -3951,17 +3910,13 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
|
||||
SCULPT_TOOL_BOUNDARY,
|
||||
SCULPT_TOOL_POSE);
|
||||
|
||||
int totnode;
|
||||
PBVHNode **nodes;
|
||||
BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::gather_proxies(ss->pbvh);
|
||||
|
||||
threading::parallel_for(IndexRange(totnode), 1, [&](IndexRange range) {
|
||||
threading::parallel_for(nodes.index_range(), 1, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
sculpt_combine_proxies_node(*ob, *sd, use_orco, *nodes[i]);
|
||||
}
|
||||
});
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
}
|
||||
|
||||
void SCULPT_combine_transform_proxies(Sculpt *sd, Object *ob)
|
||||
@@ -3969,17 +3924,13 @@ void SCULPT_combine_transform_proxies(Sculpt *sd, Object *ob)
|
||||
using namespace blender;
|
||||
SculptSession *ss = ob->sculpt;
|
||||
|
||||
int totnode;
|
||||
PBVHNode **nodes;
|
||||
BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::gather_proxies(ss->pbvh);
|
||||
|
||||
threading::parallel_for(IndexRange(totnode), 1, [&](IndexRange range) {
|
||||
threading::parallel_for(nodes.index_range(), 1, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
sculpt_combine_proxies_node(*ob, *sd, false, *nodes[i]);
|
||||
}
|
||||
});
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4019,9 +3970,8 @@ void SCULPT_flush_stroke_deform(Sculpt * /*sd*/, Object *ob, bool is_proxy_used)
|
||||
/* This brushes aren't using proxies, so sculpt_combine_proxies() wouldn't propagate needed
|
||||
* deformation to original base. */
|
||||
|
||||
int totnode;
|
||||
Mesh *me = (Mesh *)ob->data;
|
||||
PBVHNode **nodes;
|
||||
Vector<PBVHNode *> nodes;
|
||||
float(*vertCos)[3] = nullptr;
|
||||
|
||||
if (ss->shapekey_active) {
|
||||
@@ -4033,11 +3983,11 @@ void SCULPT_flush_stroke_deform(Sculpt * /*sd*/, Object *ob, bool is_proxy_used)
|
||||
memcpy(vertCos, ss->orig_cos, sizeof(*vertCos) * me->totvert);
|
||||
}
|
||||
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
|
||||
MutableSpan<float3> positions = me->vert_positions_for_write();
|
||||
|
||||
threading::parallel_for(IndexRange(totnode), 1, [&](IndexRange range) {
|
||||
threading::parallel_for(nodes.index_range(), 1, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
PBVHVertexIter vd;
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[i], vd, PBVH_ITER_UNIQUE) {
|
||||
@@ -4058,8 +4008,6 @@ void SCULPT_flush_stroke_deform(Sculpt * /*sd*/, Object *ob, bool is_proxy_used)
|
||||
SCULPT_vertcos_to_key(ob, ss->shapekey_active, vertCos);
|
||||
MEM_freeN(vertCos);
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
}
|
||||
else if (ss->shapekey_active) {
|
||||
sculpt_update_keyblock(ob);
|
||||
@@ -5162,7 +5110,6 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
|
||||
float ray_start[3], ray_end[3], ray_normal[3], depth, face_normal[3], sampled_normal[3],
|
||||
mat[3][3];
|
||||
float viewDir[3] = {0.0f, 0.0f, 1.0f};
|
||||
int totnode;
|
||||
bool original = false;
|
||||
|
||||
ED_view3d_viewcontext_init(C, &vc, depsgraph);
|
||||
@@ -5254,17 +5201,16 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
|
||||
}
|
||||
ss->cursor_radius = radius;
|
||||
|
||||
PBVHNode **nodes = sculpt_pbvh_gather_cursor_update(ob, sd, original, &totnode);
|
||||
Vector<PBVHNode *> nodes = sculpt_pbvh_gather_cursor_update(ob, sd, original);
|
||||
|
||||
/* In case there are no nodes under the cursor, return the face normal. */
|
||||
if (!totnode) {
|
||||
MEM_SAFE_FREE(nodes);
|
||||
if (nodes.is_empty()) {
|
||||
copy_v3_v3(out->normal, srd.face_normal);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Calculate the sampled normal. */
|
||||
if (SCULPT_pbvh_calc_area_normal(brush, ob, nodes, totnode, true, sampled_normal)) {
|
||||
if (SCULPT_pbvh_calc_area_normal(brush, ob, nodes, true, sampled_normal)) {
|
||||
copy_v3_v3(out->normal, sampled_normal);
|
||||
copy_v3_v3(ss->cursor_sampled_normal, sampled_normal);
|
||||
}
|
||||
@@ -5272,7 +5218,6 @@ bool SCULPT_cursor_geometry_info_update(bContext *C,
|
||||
/* Use face normal when there are no vertices to sample inside the cursor radius. */
|
||||
copy_v3_v3(out->normal, srd.face_normal);
|
||||
}
|
||||
MEM_SAFE_FREE(nodes);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -6138,8 +6083,8 @@ static PBVHVertRef SCULPT_fake_neighbor_search(Sculpt *sd,
|
||||
float max_distance)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
PBVHNode **nodes = nullptr;
|
||||
int totnode;
|
||||
Vector<PBVHNode *> nodes;
|
||||
|
||||
SculptSearchSphereData data{};
|
||||
data.ss = ss;
|
||||
data.sd = sd;
|
||||
@@ -6147,9 +6092,9 @@ static PBVHVertRef SCULPT_fake_neighbor_search(Sculpt *sd,
|
||||
data.original = false;
|
||||
data.center = SCULPT_vertex_co_get(ss, vertex);
|
||||
|
||||
BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode);
|
||||
nodes = blender::bke::pbvh::search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data);
|
||||
|
||||
if (totnode == 0) {
|
||||
if (nodes.is_empty()) {
|
||||
return BKE_pbvh_make_vref(PBVH_REF_NONE);
|
||||
}
|
||||
|
||||
@@ -6167,13 +6112,11 @@ static PBVHVertRef SCULPT_fake_neighbor_search(Sculpt *sd,
|
||||
nvtd.current_topology_id = SCULPT_vertex_island_get(ss, vertex);
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
settings.func_reduce = fake_neighbor_search_reduce;
|
||||
settings.userdata_chunk = &nvtd;
|
||||
settings.userdata_chunk_size = sizeof(NearestVertexFakeNeighborTLSData);
|
||||
BLI_task_parallel_range(0, totnode, &task_data, do_fake_neighbor_search_task_cb, &settings);
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
BLI_task_parallel_range(0, nodes.size(), &task_data, do_fake_neighbor_search_task_cb, &settings);
|
||||
|
||||
return nvtd.nearest_vertex;
|
||||
}
|
||||
|
||||
@@ -973,7 +973,7 @@ static void do_boundary_brush_smooth_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -1031,26 +1031,32 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn
|
||||
data.nodes = nodes;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
|
||||
switch (brush->boundary_deform_type) {
|
||||
case BRUSH_BOUNDARY_DEFORM_BEND:
|
||||
BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_bend_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(
|
||||
0, nodes.size(), &data, do_boundary_brush_bend_task_cb_ex, &settings);
|
||||
break;
|
||||
case BRUSH_BOUNDARY_DEFORM_EXPAND:
|
||||
BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_slide_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(
|
||||
0, nodes.size(), &data, do_boundary_brush_slide_task_cb_ex, &settings);
|
||||
break;
|
||||
case BRUSH_BOUNDARY_DEFORM_INFLATE:
|
||||
BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_inflate_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(
|
||||
0, nodes.size(), &data, do_boundary_brush_inflate_task_cb_ex, &settings);
|
||||
break;
|
||||
case BRUSH_BOUNDARY_DEFORM_GRAB:
|
||||
BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_grab_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(
|
||||
0, nodes.size(), &data, do_boundary_brush_grab_task_cb_ex, &settings);
|
||||
break;
|
||||
case BRUSH_BOUNDARY_DEFORM_TWIST:
|
||||
BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_twist_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(
|
||||
0, nodes.size(), &data, do_boundary_brush_twist_task_cb_ex, &settings);
|
||||
break;
|
||||
case BRUSH_BOUNDARY_DEFORM_SMOOTH:
|
||||
BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_smooth_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(
|
||||
0, nodes.size(), &data, do_boundary_brush_smooth_task_cb_ex, &settings);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_task.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_span.hh"
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_customdata_types.h"
|
||||
@@ -39,6 +40,8 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
using blender::Span;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name SculptProjectVector
|
||||
*
|
||||
@@ -86,7 +89,7 @@ static void sculpt_project_v3(const SculptProjectVector *spvc, const float vec[3
|
||||
}
|
||||
|
||||
static void calc_sculpt_plane(
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3])
|
||||
Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float r_area_no[3], float r_area_co[3])
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -112,7 +115,7 @@ static void calc_sculpt_plane(
|
||||
break;
|
||||
|
||||
case SCULPT_DISP_DIR_AREA:
|
||||
SCULPT_calc_area_normal_and_center(sd, ob, nodes, totnode, r_area_no, r_area_co);
|
||||
SCULPT_calc_area_normal_and_center(sd, ob, nodes, r_area_no, r_area_co);
|
||||
if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
|
||||
project_plane_v3_v3v3(r_area_no, r_area_no, ss->cache->view_normal);
|
||||
normalize_v3(r_area_no);
|
||||
@@ -126,7 +129,7 @@ static void calc_sculpt_plane(
|
||||
/* For flatten center. */
|
||||
/* Flatten center has not been calculated yet if we are not using the area normal. */
|
||||
if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA) {
|
||||
SCULPT_calc_area_center(sd, ob, nodes, totnode, r_area_co);
|
||||
SCULPT_calc_area_center(sd, ob, nodes, r_area_co);
|
||||
}
|
||||
|
||||
/* For area normal. */
|
||||
@@ -302,7 +305,7 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_draw_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -329,8 +332,8 @@ void SCULPT_do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
data.offset = offset;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_draw_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_draw_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -406,7 +409,7 @@ static void do_fill_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_fill_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -421,7 +424,7 @@ void SCULPT_do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
|
||||
float temp[3];
|
||||
|
||||
SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co);
|
||||
SCULPT_calc_brush_plane(sd, ob, nodes, area_no, area_co);
|
||||
|
||||
SCULPT_tilt_apply_to_normal(area_no, ss->cache, brush->tilt_strength_factor);
|
||||
|
||||
@@ -440,8 +443,8 @@ void SCULPT_do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
data.area_co = area_co;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_fill_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_fill_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
static void do_scrape_brush_task_cb_ex(void *__restrict userdata,
|
||||
@@ -510,7 +513,7 @@ static void do_scrape_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_scrape_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -525,7 +528,7 @@ void SCULPT_do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
|
||||
|
||||
float temp[3];
|
||||
|
||||
SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co);
|
||||
SCULPT_calc_brush_plane(sd, ob, nodes, area_no, area_co);
|
||||
|
||||
SCULPT_tilt_apply_to_normal(area_no, ss->cache, brush->tilt_strength_factor);
|
||||
|
||||
@@ -544,8 +547,8 @@ void SCULPT_do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
|
||||
data.area_co = area_co;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_scrape_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_scrape_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -643,7 +646,7 @@ float SCULPT_clay_thumb_get_stabilized_pressure(StrokeCache *cache)
|
||||
return final_pressure / SCULPT_CLAY_STABILIZER_LEN;
|
||||
}
|
||||
|
||||
void SCULPT_do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_clay_thumb_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -662,10 +665,10 @@ void SCULPT_do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
|
||||
float scale[4][4];
|
||||
float tmat[4][4];
|
||||
|
||||
SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no_sp, area_co);
|
||||
SCULPT_calc_brush_plane(sd, ob, nodes, area_no_sp, area_co);
|
||||
|
||||
if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA || (brush->flag & BRUSH_ORIGINAL_NORMAL)) {
|
||||
SCULPT_calc_area_normal(sd, ob, nodes, totnode, area_no);
|
||||
SCULPT_calc_area_normal(sd, ob, nodes, area_no);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(area_no, area_no_sp);
|
||||
@@ -724,8 +727,8 @@ void SCULPT_do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
|
||||
data.clay_strength = clay_strength;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_clay_thumb_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_clay_thumb_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -796,7 +799,7 @@ static void do_flatten_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -810,7 +813,7 @@ void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
|
||||
float displace;
|
||||
float temp[3];
|
||||
|
||||
SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co);
|
||||
SCULPT_calc_brush_plane(sd, ob, nodes, area_no, area_co);
|
||||
|
||||
SCULPT_tilt_apply_to_normal(area_no, ss->cache, brush->tilt_strength_factor);
|
||||
|
||||
@@ -829,8 +832,8 @@ void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
|
||||
data.area_co = area_co;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_flatten_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_flatten_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -958,7 +961,7 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -974,26 +977,26 @@ void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
float area_co[3];
|
||||
float temp[3];
|
||||
|
||||
SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co);
|
||||
SCULPT_calc_brush_plane(sd, ob, nodes, area_no, area_co);
|
||||
|
||||
SculptThreadedTaskData sample_data{};
|
||||
sample_data.sd = nullptr;
|
||||
sample_data.ob = ob;
|
||||
sample_data.brush = brush;
|
||||
sample_data.nodes = nodes;
|
||||
sample_data.totnode = totnode;
|
||||
sample_data.area_no = area_no;
|
||||
sample_data.area_co = ss->cache->location;
|
||||
|
||||
ClaySampleData csd = {{0}};
|
||||
|
||||
TaskParallelSettings sample_settings;
|
||||
BKE_pbvh_parallel_range_settings(&sample_settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&sample_settings, true, nodes.size());
|
||||
sample_settings.func_reduce = calc_clay_surface_reduce;
|
||||
sample_settings.userdata_chunk = &csd;
|
||||
sample_settings.userdata_chunk_size = sizeof(ClaySampleData);
|
||||
|
||||
BLI_task_parallel_range(0, totnode, &sample_data, calc_clay_surface_task_cb, &sample_settings);
|
||||
BLI_task_parallel_range(
|
||||
0, nodes.size(), &sample_data, calc_clay_surface_task_cb, &sample_settings);
|
||||
|
||||
float d_offset = (csd.plane_dist[0] + csd.plane_dist[1]);
|
||||
d_offset = min_ff(radius, d_offset);
|
||||
@@ -1018,8 +1021,8 @@ void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
data.area_co = area_co;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_clay_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_clay_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata,
|
||||
@@ -1090,7 +1093,7 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_clay_strips_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -1112,11 +1115,11 @@ void SCULPT_do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
|
||||
float scale[4][4];
|
||||
float tmat[4][4];
|
||||
|
||||
SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no_sp, area_co);
|
||||
SCULPT_calc_brush_plane(sd, ob, nodes, area_no_sp, area_co);
|
||||
SCULPT_tilt_apply_to_normal(area_no_sp, ss->cache, brush->tilt_strength_factor);
|
||||
|
||||
if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA || (brush->flag & BRUSH_ORIGINAL_NORMAL)) {
|
||||
SCULPT_calc_area_normal(sd, ob, nodes, totnode, area_no);
|
||||
SCULPT_calc_area_normal(sd, ob, nodes, area_no);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(area_no, area_no_sp);
|
||||
@@ -1178,8 +1181,8 @@ void SCULPT_do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
|
||||
data.mat = mat;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_clay_strips_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_clay_strips_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
|
||||
@@ -1298,7 +1301,7 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_snake_hook_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -1331,8 +1334,8 @@ void SCULPT_do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
|
||||
data.grab_delta = grab_delta;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_snake_hook_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_snake_hook_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
static void do_thumb_brush_task_cb_ex(void *__restrict userdata,
|
||||
@@ -1390,7 +1393,7 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_thumb_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -1410,8 +1413,8 @@ void SCULPT_do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
||||
data.cono = cono;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_thumb_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_thumb_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
static void do_rotate_brush_task_cb_ex(void *__restrict userdata,
|
||||
@@ -1475,7 +1478,7 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_rotate_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -1491,8 +1494,8 @@ void SCULPT_do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
|
||||
data.angle = angle;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_rotate_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_rotate_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
static void do_layer_brush_task_cb_ex(void *__restrict userdata,
|
||||
@@ -1598,7 +1601,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_layer_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -1615,8 +1618,8 @@ void SCULPT_do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
||||
data.nodes = nodes;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_layer_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_layer_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
static void do_inflate_brush_task_cb_ex(void *__restrict userdata,
|
||||
@@ -1677,7 +1680,7 @@ static void do_inflate_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_inflate_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
|
||||
@@ -1688,8 +1691,8 @@ void SCULPT_do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
|
||||
data.nodes = nodes;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_inflate_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_inflate_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
static void do_nudge_brush_task_cb_ex(void *__restrict userdata,
|
||||
@@ -1742,7 +1745,7 @@ static void do_nudge_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_nudge_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -1762,8 +1765,8 @@ void SCULPT_do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
||||
data.cono = cono;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_nudge_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_nudge_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -1842,7 +1845,7 @@ static void do_crease_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_crease_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
const Scene *scene = ss->cache->vc->scene;
|
||||
@@ -1890,8 +1893,8 @@ void SCULPT_do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
|
||||
data.flippedbstrength = flippedbstrength;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_crease_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_crease_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
static void do_pinch_brush_task_cb_ex(void *__restrict userdata,
|
||||
@@ -1967,7 +1970,7 @@ static void do_pinch_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_pinch_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -1976,7 +1979,7 @@ void SCULPT_do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
||||
float area_co[3];
|
||||
|
||||
float mat[4][4];
|
||||
calc_sculpt_plane(sd, ob, nodes, totnode, area_no, area_co);
|
||||
calc_sculpt_plane(sd, ob, nodes, area_no, area_co);
|
||||
|
||||
/* delay the first daub because grab delta is not setup */
|
||||
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
||||
@@ -2010,8 +2013,8 @@ void SCULPT_do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
||||
data.stroke_xz = stroke_xz;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_pinch_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_pinch_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
static void do_grab_brush_task_cb_ex(void *__restrict userdata,
|
||||
@@ -2082,7 +2085,7 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_grab_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -2102,8 +2105,8 @@ void SCULPT_do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
data.grab_delta = grab_delta;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_grab_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_grab_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata,
|
||||
@@ -2196,7 +2199,7 @@ static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_elastic_deform_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_elastic_deform_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -2216,8 +2219,8 @@ void SCULPT_do_elastic_deform_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
|
||||
data.grab_delta = grab_delta;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_elastic_deform_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_elastic_deform_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -2280,7 +2283,7 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_draw_sharp_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -2307,8 +2310,8 @@ void SCULPT_do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
|
||||
data.offset = offset;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_draw_sharp_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_draw_sharp_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -2532,7 +2535,7 @@ static void do_topology_relax_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_slide_relax_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -2550,15 +2553,15 @@ void SCULPT_do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
|
||||
data.nodes = nodes;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
if (ss->cache->alt_smooth) {
|
||||
SCULPT_boundary_info_ensure(ob);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
BLI_task_parallel_range(0, totnode, &data, do_topology_relax_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_topology_relax_task_cb_ex, &settings);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_task_parallel_range(0, totnode, &data, do_topology_slide_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_topology_slide_task_cb_ex, &settings);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2619,7 +2622,7 @@ static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_displacement_eraser_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_displacement_eraser_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
BKE_curvemapping_init(brush->curve);
|
||||
@@ -2632,8 +2635,9 @@ void SCULPT_do_displacement_eraser_brush(Sculpt *sd, Object *ob, PBVHNode **node
|
||||
data.nodes = nodes;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_displacement_eraser_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(
|
||||
0, nodes.size(), &data, do_displacement_eraser_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -2752,7 +2756,7 @@ static void do_displacement_smear_store_prev_disp_task_cb_ex(
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_displacement_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_displacement_smear_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
@@ -2782,10 +2786,11 @@ void SCULPT_do_displacement_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes
|
||||
data.nodes = nodes;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(
|
||||
0, totnode, &data, do_displacement_smear_store_prev_disp_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_displacement_smear_brush_task_cb_ex, &settings);
|
||||
0, nodes.size(), &data, do_displacement_smear_store_prev_disp_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(
|
||||
0, nodes.size(), &data, do_displacement_smear_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -2865,8 +2870,7 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_bmesh_topology_rake(
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, const int totnode, float bstrength)
|
||||
void SCULPT_bmesh_topology_rake(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float bstrength)
|
||||
{
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
const float strength = clamp_f(bstrength, 0.0f, 1.0f);
|
||||
@@ -2888,9 +2892,9 @@ void SCULPT_bmesh_topology_rake(
|
||||
data.strength = factor;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
|
||||
BLI_task_parallel_range(0, totnode, &data, do_topology_rake_bmesh_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_topology_rake_bmesh_task_cb_ex, &settings);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2948,7 +2952,7 @@ static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_mask_brush_draw(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
|
||||
@@ -2960,21 +2964,21 @@ void SCULPT_do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int tot
|
||||
data.nodes = nodes;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_mask_brush_draw_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_mask_brush_draw_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
void SCULPT_do_mask_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_mask_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
|
||||
switch ((BrushMaskTool)brush->mask_tool) {
|
||||
case BRUSH_MASK_DRAW:
|
||||
SCULPT_do_mask_brush_draw(sd, ob, nodes, totnode);
|
||||
SCULPT_do_mask_brush_draw(sd, ob, nodes);
|
||||
break;
|
||||
case BRUSH_MASK_SMOOTH:
|
||||
SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, true);
|
||||
SCULPT_smooth(sd, ob, nodes, ss->cache->bstrength, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_task.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_customdata_types.h"
|
||||
@@ -53,6 +54,8 @@
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
using blender::Vector;
|
||||
|
||||
static void cloth_brush_simulation_location_get(SculptSession *ss,
|
||||
const Brush *brush,
|
||||
float r_location[3])
|
||||
@@ -69,13 +72,10 @@ static void cloth_brush_simulation_location_get(SculptSession *ss,
|
||||
copy_v3_v3(r_location, ss->cache->location);
|
||||
}
|
||||
|
||||
PBVHNode **SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss,
|
||||
Brush *brush,
|
||||
int *r_totnode)
|
||||
Vector<PBVHNode *> SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss, Brush *brush)
|
||||
{
|
||||
BLI_assert(ss->cache);
|
||||
BLI_assert(brush->sculpt_tool == SCULPT_TOOL_CLOTH);
|
||||
PBVHNode **nodes = nullptr;
|
||||
|
||||
switch (brush->cloth_simulation_area_type) {
|
||||
case BRUSH_CLOTH_SIMULATION_AREA_LOCAL: {
|
||||
@@ -85,11 +85,10 @@ PBVHNode **SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss,
|
||||
data.original = false;
|
||||
data.ignore_fully_ineffective = false;
|
||||
data.center = ss->cache->initial_location;
|
||||
BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode);
|
||||
} break;
|
||||
return blender::bke::pbvh::search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data);
|
||||
}
|
||||
case BRUSH_CLOTH_SIMULATION_AREA_GLOBAL:
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, r_totnode);
|
||||
break;
|
||||
return blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
case BRUSH_CLOTH_SIMULATION_AREA_DYNAMIC: {
|
||||
SculptSearchSphereData data{};
|
||||
data.ss = ss;
|
||||
@@ -97,11 +96,12 @@ PBVHNode **SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss,
|
||||
data.original = false;
|
||||
data.ignore_fully_ineffective = false;
|
||||
data.center = ss->cache->location;
|
||||
BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode);
|
||||
} break;
|
||||
return blender::bke::pbvh::search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data);
|
||||
}
|
||||
}
|
||||
|
||||
return nodes;
|
||||
BLI_assert_unreachable();
|
||||
return Vector<PBVHNode *>();
|
||||
}
|
||||
|
||||
static float cloth_brush_simulation_falloff_get(const Brush *brush,
|
||||
@@ -901,8 +901,10 @@ static void cloth_brush_satisfy_constraints(SculptSession *ss,
|
||||
}
|
||||
}
|
||||
|
||||
void SCULPT_cloth_brush_do_simulation_step(
|
||||
Sculpt *sd, Object *ob, SculptClothSimulation *cloth_sim, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_cloth_brush_do_simulation_step(Sculpt *sd,
|
||||
Object *ob,
|
||||
SculptClothSimulation *cloth_sim,
|
||||
Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -920,12 +922,15 @@ void SCULPT_cloth_brush_do_simulation_step(
|
||||
solve_simulation_data.cloth_sim = cloth_sim;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(
|
||||
0, totnode, &solve_simulation_data, do_cloth_brush_solve_simulation_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0,
|
||||
nodes.size(),
|
||||
&solve_simulation_data,
|
||||
do_cloth_brush_solve_simulation_task_cb_ex,
|
||||
&settings);
|
||||
}
|
||||
|
||||
static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -970,7 +975,7 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod
|
||||
|
||||
if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR ||
|
||||
brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_PLANE) {
|
||||
SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co);
|
||||
SCULPT_calc_brush_plane(sd, ob, nodes, area_no, area_co);
|
||||
|
||||
/* Initialize stroke local space matrix. */
|
||||
cross_v3_v3v3(mat[0], area_no, ss->cache->grab_delta_symmetry);
|
||||
@@ -1003,9 +1008,9 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod
|
||||
}
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(
|
||||
0, totnode, &apply_forces_data, do_cloth_brush_apply_forces_task_cb_ex, &settings);
|
||||
0, nodes.size(), &apply_forces_data, do_cloth_brush_apply_forces_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
/* Allocates nodes state and initializes them to Uninitialized, so constraints can be created for
|
||||
@@ -1013,18 +1018,15 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod
|
||||
static void cloth_sim_initialize_default_node_state(SculptSession *ss,
|
||||
SculptClothSimulation *cloth_sim)
|
||||
{
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
|
||||
cloth_sim->node_state = static_cast<eSculptClothNodeSimState *>(
|
||||
MEM_malloc_arrayN(totnode, sizeof(eSculptClothNodeSimState), "node sim state"));
|
||||
MEM_malloc_arrayN(nodes.size(), sizeof(eSculptClothNodeSimState), "node sim state"));
|
||||
cloth_sim->node_state_index = BLI_ghash_ptr_new("node sim state indices");
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
cloth_sim->node_state[i] = SCULPT_CLOTH_NODE_UNINITIALIZED;
|
||||
BLI_ghash_insert(cloth_sim->node_state_index, nodes[i], POINTER_FROM_INT(i));
|
||||
}
|
||||
MEM_SAFE_FREE(nodes);
|
||||
}
|
||||
|
||||
SculptClothSimulation *SCULPT_cloth_brush_simulation_create(Object *ob,
|
||||
@@ -1077,8 +1079,7 @@ SculptClothSimulation *SCULPT_cloth_brush_simulation_create(Object *ob,
|
||||
void SCULPT_cloth_brush_ensure_nodes_constraints(
|
||||
Sculpt *sd,
|
||||
Object *ob,
|
||||
PBVHNode **nodes,
|
||||
int totnode,
|
||||
Span<PBVHNode *> nodes,
|
||||
SculptClothSimulation *cloth_sim,
|
||||
/* Cannot be `const`, because it is assigned to a `non-const` variable.
|
||||
* NOLINTNEXTLINE: readability-non-const-parameter. */
|
||||
@@ -1092,7 +1093,7 @@ void SCULPT_cloth_brush_ensure_nodes_constraints(
|
||||
/* Currently all constrains are added to the same global array which can't be accessed from
|
||||
* different threads. */
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, false, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, false, nodes.size());
|
||||
|
||||
cloth_sim->created_length_constraints = BLI_edgeset_new("created length constraints");
|
||||
|
||||
@@ -1105,8 +1106,11 @@ void SCULPT_cloth_brush_ensure_nodes_constraints(
|
||||
build_constraints_data.cloth_sim_initial_location = initial_location;
|
||||
build_constraints_data.cloth_sim_radius = radius;
|
||||
|
||||
BLI_task_parallel_range(
|
||||
0, totnode, &build_constraints_data, do_cloth_brush_build_constraints_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(0,
|
||||
nodes.size(),
|
||||
&build_constraints_data,
|
||||
do_cloth_brush_build_constraints_task_cb_ex,
|
||||
&settings);
|
||||
|
||||
BLI_edgeset_free(cloth_sim->created_length_constraints);
|
||||
}
|
||||
@@ -1143,21 +1147,18 @@ void SCULPT_cloth_brush_store_simulation_state(SculptSession *ss, SculptClothSim
|
||||
}
|
||||
}
|
||||
|
||||
void SCULPT_cloth_sim_activate_nodes(SculptClothSimulation *cloth_sim,
|
||||
PBVHNode **nodes,
|
||||
int totnode)
|
||||
void SCULPT_cloth_sim_activate_nodes(SculptClothSimulation *cloth_sim, Span<PBVHNode *> nodes)
|
||||
{
|
||||
/* Activate the nodes inside the simulation area. */
|
||||
for (int n = 0; n < totnode; n++) {
|
||||
const int node_index = POINTER_AS_INT(BLI_ghash_lookup(cloth_sim->node_state_index, nodes[n]));
|
||||
for (PBVHNode *node : nodes) {
|
||||
const int node_index = POINTER_AS_INT(BLI_ghash_lookup(cloth_sim->node_state_index, node));
|
||||
cloth_sim->node_state[node_index] = SCULPT_CLOTH_NODE_ACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
static void sculpt_cloth_ensure_constraints_in_simulation_area(Sculpt *sd,
|
||||
Object *ob,
|
||||
PBVHNode **nodes,
|
||||
int totnode)
|
||||
Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -1166,10 +1167,10 @@ static void sculpt_cloth_ensure_constraints_in_simulation_area(Sculpt *sd,
|
||||
float sim_location[3];
|
||||
cloth_brush_simulation_location_get(ss, brush, sim_location);
|
||||
SCULPT_cloth_brush_ensure_nodes_constraints(
|
||||
sd, ob, nodes, totnode, ss->cache->cloth_sim, sim_location, limit);
|
||||
sd, ob, nodes, ss->cache->cloth_sim, sim_location, limit);
|
||||
}
|
||||
|
||||
void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -1201,7 +1202,7 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
||||
* as this will cause the ensure constraints function to skip the node in the next symmetry
|
||||
* passes. It needs to build the constraints here and skip simulating the first step, so all
|
||||
* passes can add their constraints to all affected nodes. */
|
||||
sculpt_cloth_ensure_constraints_in_simulation_area(sd, ob, nodes, totnode);
|
||||
sculpt_cloth_ensure_constraints_in_simulation_area(sd, ob, nodes);
|
||||
}
|
||||
/* The first step of a symmetry pass is never simulated as deformation modes need valid delta
|
||||
* for brush tip alignment. */
|
||||
@@ -1209,19 +1210,19 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
||||
}
|
||||
|
||||
/* Ensure the constraints for the nodes. */
|
||||
sculpt_cloth_ensure_constraints_in_simulation_area(sd, ob, nodes, totnode);
|
||||
sculpt_cloth_ensure_constraints_in_simulation_area(sd, ob, nodes);
|
||||
|
||||
/* Store the initial state in the simulation. */
|
||||
SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim);
|
||||
|
||||
/* Enable the nodes that should be simulated. */
|
||||
SCULPT_cloth_sim_activate_nodes(ss->cache->cloth_sim, nodes, totnode);
|
||||
SCULPT_cloth_sim_activate_nodes(ss->cache->cloth_sim, nodes);
|
||||
|
||||
/* Apply forces to the vertices. */
|
||||
cloth_brush_apply_brush_foces(sd, ob, nodes, totnode);
|
||||
cloth_brush_apply_brush_foces(sd, ob, nodes);
|
||||
|
||||
/* Update and write the simulation to the nodes. */
|
||||
SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode);
|
||||
SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes);
|
||||
}
|
||||
|
||||
void SCULPT_cloth_simulation_free(SculptClothSimulation *cloth_sim)
|
||||
@@ -1530,17 +1531,16 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent
|
||||
data.filter_strength = filter_strength;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->nodes.size());
|
||||
BLI_task_parallel_range(
|
||||
0, ss->filter_cache->totnode, &data, cloth_filter_apply_forces_task_cb, &settings);
|
||||
0, ss->filter_cache->nodes.size(), &data, cloth_filter_apply_forces_task_cb, &settings);
|
||||
|
||||
/* Activate all nodes. */
|
||||
SCULPT_cloth_sim_activate_nodes(
|
||||
ss->filter_cache->cloth_sim, ss->filter_cache->nodes, ss->filter_cache->totnode);
|
||||
SCULPT_cloth_sim_activate_nodes(ss->filter_cache->cloth_sim, ss->filter_cache->nodes);
|
||||
|
||||
/* Update and write the simulation to the nodes. */
|
||||
SCULPT_cloth_brush_do_simulation_step(
|
||||
sd, ob, ss->filter_cache->cloth_sim, ss->filter_cache->nodes, ss->filter_cache->totnode);
|
||||
sd, ob, ss->filter_cache->cloth_sim, ss->filter_cache->nodes);
|
||||
|
||||
if (ss->deform_modifiers_active || ss->shapekey_active) {
|
||||
SCULPT_flush_stroke_deform(sd, ob, true);
|
||||
@@ -1597,13 +1597,8 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent
|
||||
SCULPT_cloth_brush_simulation_init(ss, ss->filter_cache->cloth_sim);
|
||||
|
||||
float origin[3] = {0.0f, 0.0f, 0.0f};
|
||||
SCULPT_cloth_brush_ensure_nodes_constraints(sd,
|
||||
ob,
|
||||
ss->filter_cache->nodes,
|
||||
ss->filter_cache->totnode,
|
||||
ss->filter_cache->cloth_sim,
|
||||
origin,
|
||||
FLT_MAX);
|
||||
SCULPT_cloth_brush_ensure_nodes_constraints(
|
||||
sd, ob, ss->filter_cache->nodes, ss->filter_cache->cloth_sim, origin, FLT_MAX);
|
||||
|
||||
const bool use_face_sets = RNA_boolean_get(op->ptr, "use_face_sets");
|
||||
if (use_face_sets) {
|
||||
|
||||
@@ -82,17 +82,15 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *op)
|
||||
SculptSession *ss = ob->sculpt;
|
||||
float size;
|
||||
float bb_min[3], bb_max[3], center[3], dim[3];
|
||||
int totnodes;
|
||||
PBVHNode **nodes;
|
||||
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnodes);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
|
||||
if (!totnodes) {
|
||||
if (nodes.is_empty()) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
for (int i = 0; i < totnodes; i++) {
|
||||
BKE_pbvh_node_mark_topology_update(nodes[i]);
|
||||
for (PBVHNode *node : nodes) {
|
||||
BKE_pbvh_node_mark_topology_update(node);
|
||||
}
|
||||
/* Get the bounding box, its center and size. */
|
||||
BKE_pbvh_bounding_box(ob->sculpt->pbvh, bb_min, bb_max);
|
||||
@@ -111,12 +109,11 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *op)
|
||||
|
||||
while (BKE_pbvh_bmesh_update_topology(
|
||||
ss->pbvh, PBVH_Collapse | PBVH_Subdivide, center, nullptr, size, false, false)) {
|
||||
for (int i = 0; i < totnodes; i++) {
|
||||
BKE_pbvh_node_mark_topology_update(nodes[i]);
|
||||
for (PBVHNode *node : nodes) {
|
||||
BKE_pbvh_node_mark_topology_update(node);
|
||||
}
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
/* Force rebuild of PBVH for better BB placement. */
|
||||
|
||||
@@ -1138,14 +1138,13 @@ static void sculpt_expand_cache_data_free(ExpandCache *expand_cache)
|
||||
if (expand_cache->snap_enabled_face_sets) {
|
||||
BLI_gset_free(expand_cache->snap_enabled_face_sets, nullptr);
|
||||
}
|
||||
MEM_SAFE_FREE(expand_cache->nodes);
|
||||
MEM_SAFE_FREE(expand_cache->vert_falloff);
|
||||
MEM_SAFE_FREE(expand_cache->face_falloff);
|
||||
MEM_SAFE_FREE(expand_cache->original_mask);
|
||||
MEM_SAFE_FREE(expand_cache->original_face_sets);
|
||||
MEM_SAFE_FREE(expand_cache->initial_face_sets);
|
||||
MEM_SAFE_FREE(expand_cache->original_colors);
|
||||
MEM_SAFE_FREE(expand_cache);
|
||||
MEM_delete<ExpandCache>(expand_cache);
|
||||
}
|
||||
|
||||
static void sculpt_expand_cache_free(SculptSession *ss)
|
||||
@@ -1161,14 +1160,11 @@ static void sculpt_expand_cache_free(SculptSession *ss)
|
||||
*/
|
||||
static void sculpt_expand_restore_face_set_data(SculptSession *ss, ExpandCache *expand_cache)
|
||||
{
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
for (int n = 0; n < totnode; n++) {
|
||||
PBVHNode *node = nodes[n];
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
for (PBVHNode *node : nodes) {
|
||||
BKE_pbvh_node_mark_redraw(node);
|
||||
}
|
||||
MEM_freeN(nodes);
|
||||
|
||||
for (int i = 0; i < ss->totfaces; i++) {
|
||||
ss->face_sets[i] = expand_cache->original_face_sets[i];
|
||||
}
|
||||
@@ -1176,11 +1172,9 @@ static void sculpt_expand_restore_face_set_data(SculptSession *ss, ExpandCache *
|
||||
|
||||
static void sculpt_expand_restore_color_data(SculptSession *ss, ExpandCache *expand_cache)
|
||||
{
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
for (int n = 0; n < totnode; n++) {
|
||||
PBVHNode *node = nodes[n];
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
|
||||
for (PBVHNode *node : nodes) {
|
||||
PBVHVertexIter vd;
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
|
||||
SCULPT_vertex_color_set(ss, vd.vertex, expand_cache->original_colors[vd.index]);
|
||||
@@ -1188,16 +1182,12 @@ static void sculpt_expand_restore_color_data(SculptSession *ss, ExpandCache *exp
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
BKE_pbvh_node_mark_redraw(node);
|
||||
}
|
||||
MEM_freeN(nodes);
|
||||
}
|
||||
|
||||
static void sculpt_expand_restore_mask_data(SculptSession *ss, ExpandCache *expand_cache)
|
||||
{
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
for (int n = 0; n < totnode; n++) {
|
||||
PBVHNode *node = nodes[n];
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
for (PBVHNode *node : nodes) {
|
||||
PBVHVertexIter vd;
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
|
||||
*vd.mask = expand_cache->original_mask[vd.index];
|
||||
@@ -1205,7 +1195,6 @@ static void sculpt_expand_restore_mask_data(SculptSession *ss, ExpandCache *expa
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
BKE_pbvh_node_mark_redraw(node);
|
||||
}
|
||||
MEM_freeN(nodes);
|
||||
}
|
||||
|
||||
/* Main function to restore the original state of the data to how it was before starting the expand
|
||||
@@ -1327,8 +1316,8 @@ static void sculpt_expand_face_sets_update(SculptSession *ss, ExpandCache *expan
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < expand_cache->totnode; i++) {
|
||||
BKE_pbvh_node_mark_redraw(ss->expand_cache->nodes[i]);
|
||||
for (PBVHNode *node : ss->expand_cache->nodes) {
|
||||
BKE_pbvh_node_mark_redraw(node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1501,19 +1490,19 @@ static void sculpt_expand_update_for_vertex(bContext *C, Object *ob, const PBVHV
|
||||
data.nodes = expand_cache->nodes;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, expand_cache->totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, expand_cache->nodes.size());
|
||||
|
||||
switch (expand_cache->target) {
|
||||
case SCULPT_EXPAND_TARGET_MASK:
|
||||
BLI_task_parallel_range(
|
||||
0, expand_cache->totnode, &data, sculpt_expand_mask_update_task_cb, &settings);
|
||||
0, expand_cache->nodes.size(), &data, sculpt_expand_mask_update_task_cb, &settings);
|
||||
break;
|
||||
case SCULPT_EXPAND_TARGET_FACE_SETS:
|
||||
sculpt_expand_face_sets_update(ss, expand_cache);
|
||||
break;
|
||||
case SCULPT_EXPAND_TARGET_COLORS:
|
||||
BLI_task_parallel_range(
|
||||
0, expand_cache->totnode, &data, sculpt_expand_colors_update_task_cb, &settings);
|
||||
0, expand_cache->nodes.size(), &data, sculpt_expand_colors_update_task_cb, &settings);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1606,13 +1595,10 @@ static void sculpt_expand_finish(bContext *C)
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
/* Tag all nodes to redraw to avoid artifacts after the fast partial updates. */
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
for (int n = 0; n < totnode; n++) {
|
||||
BKE_pbvh_node_mark_update_mask(nodes[n]);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
for (PBVHNode *node : nodes) {
|
||||
BKE_pbvh_node_mark_update_mask(node);
|
||||
}
|
||||
MEM_freeN(nodes);
|
||||
|
||||
switch (ss->expand_cache->target) {
|
||||
case SCULPT_EXPAND_TARGET_MASK:
|
||||
@@ -2105,29 +2091,25 @@ static void sculpt_expand_cache_initial_config_set(bContext *C,
|
||||
static void sculpt_expand_undo_push(Object *ob, ExpandCache *expand_cache)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
|
||||
switch (expand_cache->target) {
|
||||
case SCULPT_EXPAND_TARGET_MASK:
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK);
|
||||
for (PBVHNode *node : nodes) {
|
||||
SCULPT_undo_push_node(ob, node, SCULPT_UNDO_MASK);
|
||||
}
|
||||
break;
|
||||
case SCULPT_EXPAND_TARGET_FACE_SETS:
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_FACE_SETS);
|
||||
for (PBVHNode *node : nodes) {
|
||||
SCULPT_undo_push_node(ob, node, SCULPT_UNDO_FACE_SETS);
|
||||
}
|
||||
break;
|
||||
case SCULPT_EXPAND_TARGET_COLORS:
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_COLOR);
|
||||
for (PBVHNode *node : nodes) {
|
||||
SCULPT_undo_push_node(ob, node, SCULPT_UNDO_COLOR);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
MEM_freeN(nodes);
|
||||
}
|
||||
|
||||
static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
@@ -2140,7 +2122,7 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even
|
||||
SCULPT_stroke_id_next(ob);
|
||||
|
||||
/* Create and configure the Expand Cache. */
|
||||
ss->expand_cache = MEM_cnew<ExpandCache>(__func__);
|
||||
ss->expand_cache = MEM_new<ExpandCache>(__func__);
|
||||
sculpt_expand_cache_initial_config_set(C, op, ss->expand_cache);
|
||||
|
||||
/* Update object. */
|
||||
@@ -2171,21 +2153,17 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
int nodes_num;
|
||||
PBVHNode **nodes;
|
||||
|
||||
/* TODO: implement SCULPT_vertex_mask_set and use it here. */
|
||||
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &nodes_num);
|
||||
for (int i = 0; i < nodes_num; i++) {
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
for (PBVHNode *node : nodes) {
|
||||
PBVHVertexIter vd;
|
||||
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[i], vd, PBVH_ITER_UNIQUE) {
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
|
||||
*vd.mask = 1.0f;
|
||||
}
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
|
||||
BKE_pbvh_node_mark_update_mask(nodes[i]);
|
||||
BKE_pbvh_node_mark_update_mask(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2223,8 +2201,7 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even
|
||||
sculpt_expand_set_initial_components_for_mouse(C, ob, ss->expand_cache, mouse);
|
||||
|
||||
/* Cache PBVH nodes. */
|
||||
BKE_pbvh_search_gather(
|
||||
ss->pbvh, nullptr, nullptr, &ss->expand_cache->nodes, &ss->expand_cache->totnode);
|
||||
ss->expand_cache->nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
|
||||
/* Store initial state. */
|
||||
sculpt_expand_original_state_store(ob, ss->expand_cache);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_array.hh"
|
||||
#include "BLI_bit_vector.hh"
|
||||
#include "BLI_function_ref.hh"
|
||||
#include "BLI_hash.h"
|
||||
@@ -55,6 +56,7 @@
|
||||
|
||||
#include "bmesh.h"
|
||||
|
||||
using blender::Array;
|
||||
using blender::float3;
|
||||
using blender::Vector;
|
||||
|
||||
@@ -252,7 +254,7 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -273,16 +275,17 @@ void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
|
||||
data.nodes = nodes;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
if (ss->cache->alt_smooth) {
|
||||
SCULPT_boundary_info_ensure(ob);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
data.iteration = i;
|
||||
BLI_task_parallel_range(0, totnode, &data, do_relax_face_sets_brush_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(
|
||||
0, nodes.size(), &data, do_relax_face_sets_brush_task_cb_ex, &settings);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_task_parallel_range(0, totnode, &data, do_draw_face_sets_brush_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_draw_face_sets_brush_task_cb_ex, &settings);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,17 +353,15 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op)
|
||||
float threshold = 0.5f;
|
||||
|
||||
PBVH *pbvh = ob->sculpt->pbvh;
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr);
|
||||
|
||||
if (!nodes) {
|
||||
if (nodes.is_empty()) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
SCULPT_undo_push_begin(ob, op);
|
||||
for (const int i : blender::IndexRange(totnode)) {
|
||||
SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_FACE_SETS);
|
||||
for (PBVHNode *node : nodes) {
|
||||
SCULPT_undo_push_node(ob, node, SCULPT_UNDO_FACE_SETS);
|
||||
}
|
||||
|
||||
const int next_face_set = SCULPT_face_set_next_available_get(ss);
|
||||
@@ -427,12 +428,10 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op)
|
||||
});
|
||||
}
|
||||
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
BKE_pbvh_node_mark_redraw(nodes[i]);
|
||||
for (PBVHNode *node : nodes) {
|
||||
BKE_pbvh_node_mark_redraw(node);
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
SCULPT_tag_update_overlays(C);
|
||||
@@ -638,17 +637,15 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
PBVH *pbvh = ob->sculpt->pbvh;
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr);
|
||||
|
||||
if (!nodes) {
|
||||
if (nodes.is_empty()) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
SCULPT_undo_push_begin(ob, op);
|
||||
for (const int i : blender::IndexRange(totnode)) {
|
||||
SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_FACE_SETS);
|
||||
for (PBVHNode *node : nodes) {
|
||||
SCULPT_undo_push_node(ob, node, SCULPT_UNDO_FACE_SETS);
|
||||
}
|
||||
|
||||
const float threshold = RNA_float_get(op->ptr, "threshold");
|
||||
@@ -734,14 +731,12 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
|
||||
/* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */
|
||||
SCULPT_visibility_sync_all_from_faces(ob);
|
||||
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
BKE_pbvh_node_mark_update_visibility(nodes[i]);
|
||||
for (PBVHNode *node : nodes) {
|
||||
BKE_pbvh_node_mark_update_visibility(node);
|
||||
}
|
||||
|
||||
BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateVisibility);
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
|
||||
if (BKE_pbvh_type(pbvh) == PBVH_FACES) {
|
||||
BKE_mesh_flush_hidden_from_verts(mesh);
|
||||
}
|
||||
@@ -836,21 +831,17 @@ static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op)
|
||||
const int tot_vert = SCULPT_vertex_count_get(ss);
|
||||
|
||||
PBVH *pbvh = ob->sculpt->pbvh;
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr);
|
||||
|
||||
BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
|
||||
if (totnode == 0) {
|
||||
MEM_SAFE_FREE(nodes);
|
||||
if (nodes.is_empty()) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
const int active_face_set = SCULPT_active_face_set_get(ss);
|
||||
|
||||
SCULPT_undo_push_begin(ob, op);
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_HIDDEN);
|
||||
for (PBVHNode *node : nodes) {
|
||||
SCULPT_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN);
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
@@ -940,14 +931,12 @@ static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op)
|
||||
SCULPT_visibility_sync_all_from_faces(ob);
|
||||
|
||||
SCULPT_undo_push_end(ob);
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
BKE_pbvh_node_mark_update_visibility(nodes[i]);
|
||||
for (PBVHNode *node : nodes) {
|
||||
BKE_pbvh_node_mark_update_visibility(node);
|
||||
}
|
||||
|
||||
BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateVisibility);
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
|
||||
SCULPT_tag_update_overlays(C);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -1008,8 +997,6 @@ static int sculpt_face_sets_randomize_colors_exec(bContext *C, wmOperator * /*op
|
||||
}
|
||||
|
||||
PBVH *pbvh = ob->sculpt->pbvh;
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
Mesh *mesh = static_cast<Mesh *>(ob->data);
|
||||
|
||||
mesh->face_sets_color_seed += 1;
|
||||
@@ -1021,13 +1008,11 @@ static int sculpt_face_sets_randomize_colors_exec(bContext *C, wmOperator * /*op
|
||||
}
|
||||
BKE_pbvh_face_sets_color_set(pbvh, mesh->face_sets_color_seed, mesh->face_sets_color_default);
|
||||
|
||||
BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
BKE_pbvh_node_mark_redraw(nodes[i]);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr);
|
||||
for (PBVHNode *node : nodes) {
|
||||
BKE_pbvh_node_mark_redraw(node);
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
|
||||
SCULPT_tag_update_overlays(C);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -1355,7 +1340,7 @@ static void sculpt_face_set_edit_modify_geometry(bContext *C,
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, mesh);
|
||||
}
|
||||
|
||||
static void face_set_edit_do_post_visibility_updates(Object *ob, PBVHNode **nodes, int totnode)
|
||||
static void face_set_edit_do_post_visibility_updates(Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
PBVH *pbvh = ss->pbvh;
|
||||
@@ -1364,8 +1349,8 @@ static void face_set_edit_do_post_visibility_updates(Object *ob, PBVHNode **node
|
||||
/* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */
|
||||
SCULPT_visibility_sync_all_from_faces(ob);
|
||||
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
BKE_pbvh_node_mark_update_visibility(nodes[i]);
|
||||
for (PBVHNode *node : nodes) {
|
||||
BKE_pbvh_node_mark_update_visibility(node);
|
||||
}
|
||||
|
||||
BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateVisibility);
|
||||
@@ -1382,21 +1367,18 @@ static void sculpt_face_set_edit_modify_face_sets(Object *ob,
|
||||
wmOperator *op)
|
||||
{
|
||||
PBVH *pbvh = ob->sculpt->pbvh;
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr);
|
||||
|
||||
if (!nodes) {
|
||||
if (nodes.is_empty()) {
|
||||
return;
|
||||
}
|
||||
SCULPT_undo_push_begin(ob, op);
|
||||
for (const int i : blender::IndexRange(totnode)) {
|
||||
SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_FACE_SETS);
|
||||
for (PBVHNode *node : nodes) {
|
||||
SCULPT_undo_push_node(ob, node, SCULPT_UNDO_FACE_SETS);
|
||||
}
|
||||
sculpt_face_set_apply_edit(ob, abs(active_face_set), mode, modify_hidden);
|
||||
SCULPT_undo_push_end(ob);
|
||||
face_set_edit_do_post_visibility_updates(ob, nodes, totnode);
|
||||
MEM_freeN(nodes);
|
||||
face_set_edit_do_post_visibility_updates(ob, nodes);
|
||||
}
|
||||
|
||||
static void sculpt_face_set_edit_modify_coordinates(bContext *C,
|
||||
@@ -1408,17 +1390,15 @@ static void sculpt_face_set_edit_modify_coordinates(bContext *C,
|
||||
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
||||
SculptSession *ss = ob->sculpt;
|
||||
PBVH *pbvh = ss->pbvh;
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
|
||||
BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr);
|
||||
|
||||
const float strength = RNA_float_get(op->ptr, "strength");
|
||||
|
||||
SCULPT_undo_push_begin(ob, op);
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
BKE_pbvh_node_mark_update(nodes[i]);
|
||||
SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_COORDS);
|
||||
for (PBVHNode *node : nodes) {
|
||||
BKE_pbvh_node_mark_update(node);
|
||||
SCULPT_undo_push_node(ob, node, SCULPT_UNDO_COORDS);
|
||||
}
|
||||
sculpt_face_set_apply_edit(ob, abs(active_face_set), mode, false, strength);
|
||||
|
||||
@@ -1428,7 +1408,6 @@ static void sculpt_face_set_edit_modify_coordinates(bContext *C,
|
||||
SCULPT_flush_update_step(C, SCULPT_UPDATE_COORDS);
|
||||
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
|
||||
SCULPT_undo_push_end(ob);
|
||||
MEM_freeN(nodes);
|
||||
}
|
||||
|
||||
static bool sculpt_face_set_edit_init(bContext *C, wmOperator *op)
|
||||
|
||||
@@ -289,8 +289,9 @@ static void sculpt_color_filter_apply(bContext *C, wmOperator *op, Object *ob)
|
||||
TaskParallelSettings settings;
|
||||
BLI_parallel_range_settings_defaults(&settings);
|
||||
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
|
||||
BLI_task_parallel_range(0, ss->filter_cache->totnode, &data, color_filter_task_cb, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->nodes.size());
|
||||
BLI_task_parallel_range(
|
||||
0, ss->filter_cache->nodes.size(), &data, color_filter_task_cb, &settings);
|
||||
|
||||
SCULPT_flush_update_step(C, SCULPT_UPDATE_COLOR);
|
||||
}
|
||||
|
||||
@@ -161,9 +161,7 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
||||
const Scene *scene = CTX_data_scene(C);
|
||||
PBVHNode **nodes;
|
||||
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
||||
int totnode;
|
||||
int filter_type = RNA_enum_get(op->ptr, "filter_type");
|
||||
|
||||
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
|
||||
@@ -182,11 +180,11 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
|
||||
|
||||
int num_verts = SCULPT_vertex_count_get(ss);
|
||||
|
||||
BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr);
|
||||
SCULPT_undo_push_begin(ob, op);
|
||||
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK);
|
||||
for (PBVHNode *node : nodes) {
|
||||
SCULPT_undo_push_node(ob, node, SCULPT_UNDO_MASK);
|
||||
}
|
||||
|
||||
float *prev_mask = nullptr;
|
||||
@@ -217,16 +215,14 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
|
||||
data.prev_mask = prev_mask;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, mask_filter_task_cb, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, mask_filter_task_cb, &settings);
|
||||
|
||||
if (ELEM(filter_type, MASK_FILTER_GROW, MASK_FILTER_SHRINK)) {
|
||||
MEM_freeN(prev_mask);
|
||||
}
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
SCULPT_tag_update_overlays(C);
|
||||
@@ -234,8 +230,10 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void SCULPT_mask_filter_smooth_apply(
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, const int totnode, const int smooth_iterations)
|
||||
void SCULPT_mask_filter_smooth_apply(Sculpt *sd,
|
||||
Object *ob,
|
||||
Span<PBVHNode *> nodes,
|
||||
const int smooth_iterations)
|
||||
{
|
||||
SculptThreadedTaskData data{};
|
||||
data.sd = sd;
|
||||
@@ -245,8 +243,8 @@ void SCULPT_mask_filter_smooth_apply(
|
||||
|
||||
for (int i = 0; i < smooth_iterations; i++) {
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, mask_filter_task_cb, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, mask_filter_task_cb, &settings);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ void SCULPT_filter_cache_init(bContext *C,
|
||||
SculptSession *ss = ob->sculpt;
|
||||
PBVH *pbvh = ob->sculpt->pbvh;
|
||||
|
||||
ss->filter_cache = MEM_cnew<FilterCache>(__func__);
|
||||
ss->filter_cache = MEM_new<FilterCache>(__func__);
|
||||
ss->filter_cache->start_filter_strength = start_strength;
|
||||
ss->filter_cache->random_seed = rand();
|
||||
|
||||
@@ -132,14 +132,11 @@ void SCULPT_filter_cache_init(bContext *C,
|
||||
search_data.radius_squared = FLT_MAX;
|
||||
search_data.ignore_fully_ineffective = true;
|
||||
|
||||
BKE_pbvh_search_gather(pbvh,
|
||||
SCULPT_search_sphere_cb,
|
||||
&search_data,
|
||||
&ss->filter_cache->nodes,
|
||||
&ss->filter_cache->totnode);
|
||||
ss->filter_cache->nodes = blender::bke::pbvh::search_gather(
|
||||
pbvh, SCULPT_search_sphere_cb, &search_data);
|
||||
|
||||
for (int i = 0; i < ss->filter_cache->totnode; i++) {
|
||||
BKE_pbvh_node_mark_normals_update(ss->filter_cache->nodes[i]);
|
||||
for (PBVHNode *node : ss->filter_cache->nodes) {
|
||||
BKE_pbvh_node_mark_normals_update(node);
|
||||
}
|
||||
|
||||
/* `mesh->runtime.subdiv_ccg` is not available. Updating of the normals is done during drawing.
|
||||
@@ -155,9 +152,9 @@ void SCULPT_filter_cache_init(bContext *C,
|
||||
data.filter_undo_type = undo_type;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->nodes.size());
|
||||
BLI_task_parallel_range(
|
||||
0, ss->filter_cache->totnode, &data, filter_cache_init_task_cb, &settings);
|
||||
0, ss->filter_cache->nodes.size(), &data, filter_cache_init_task_cb, &settings);
|
||||
|
||||
/* Setup orientation matrices. */
|
||||
copy_m4_m4(ss->filter_cache->obmat, ob->object_to_world);
|
||||
@@ -180,8 +177,7 @@ void SCULPT_filter_cache_init(bContext *C,
|
||||
float mval_fl[2] = {float(mval[0]), float(mval[1])};
|
||||
|
||||
if (vc.rv3d && SCULPT_stroke_get_location(C, co, mval_fl, false)) {
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
Vector<PBVHNode *> nodes;
|
||||
|
||||
/* Get radius from brush. */
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -206,19 +202,16 @@ void SCULPT_filter_cache_init(bContext *C,
|
||||
search_data2.radius_squared = radius * radius;
|
||||
search_data2.ignore_fully_ineffective = true;
|
||||
|
||||
BKE_pbvh_search_gather(pbvh, SCULPT_search_sphere_cb, &search_data2, &nodes, &totnode);
|
||||
nodes = blender::bke::pbvh::search_gather(pbvh, SCULPT_search_sphere_cb, &search_data2);
|
||||
|
||||
if (BKE_paint_brush(&sd->paint) &&
|
||||
SCULPT_pbvh_calc_area_normal(
|
||||
brush, ob, nodes, totnode, true, ss->filter_cache->initial_normal)) {
|
||||
SCULPT_pbvh_calc_area_normal(brush, ob, nodes, true, ss->filter_cache->initial_normal)) {
|
||||
copy_v3_v3(ss->last_normal, ss->filter_cache->initial_normal);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(ss->filter_cache->initial_normal, ss->last_normal);
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
|
||||
/* Update last stroke location */
|
||||
|
||||
mul_m4_v3(ob->object_to_world, co);
|
||||
@@ -257,7 +250,6 @@ void SCULPT_filter_cache_free(SculptSession *ss)
|
||||
if (ss->filter_cache->automasking) {
|
||||
SCULPT_automasking_cache_free(ss->filter_cache->automasking);
|
||||
}
|
||||
MEM_SAFE_FREE(ss->filter_cache->nodes);
|
||||
MEM_SAFE_FREE(ss->filter_cache->mask_update_it);
|
||||
MEM_SAFE_FREE(ss->filter_cache->prev_mask);
|
||||
MEM_SAFE_FREE(ss->filter_cache->normal_factor);
|
||||
@@ -267,7 +259,7 @@ void SCULPT_filter_cache_free(SculptSession *ss)
|
||||
MEM_SAFE_FREE(ss->filter_cache->detail_directions);
|
||||
MEM_SAFE_FREE(ss->filter_cache->limit_surface_co);
|
||||
MEM_SAFE_FREE(ss->filter_cache->pre_smoothed_color);
|
||||
MEM_SAFE_FREE(ss->filter_cache);
|
||||
MEM_delete<FilterCache>(ss->filter_cache);
|
||||
}
|
||||
|
||||
typedef enum eSculptMeshFilterType {
|
||||
@@ -778,12 +770,13 @@ static void sculpt_mesh_filter_apply(bContext *C, wmOperator *op)
|
||||
data.filter_strength = filter_strength;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
|
||||
BLI_task_parallel_range(0, ss->filter_cache->totnode, &data, mesh_filter_task_cb, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->nodes.size());
|
||||
BLI_task_parallel_range(
|
||||
0, ss->filter_cache->nodes.size(), &data, mesh_filter_task_cb, &settings);
|
||||
|
||||
if (filter_type == MESH_FILTER_SURFACE_SMOOTH) {
|
||||
BLI_task_parallel_range(0,
|
||||
ss->filter_cache->totnode,
|
||||
ss->filter_cache->nodes.size(),
|
||||
&data,
|
||||
mesh_filter_surface_smooth_displace_task_cb,
|
||||
&settings);
|
||||
@@ -872,22 +865,19 @@ static void sculpt_mesh_filter_cancel(bContext *C, wmOperator * /*op*/)
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
PBVHNode **nodes;
|
||||
int nodes_num;
|
||||
|
||||
if (!ss || !ss->pbvh) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Gather all PBVH leaf nodes. */
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &nodes_num);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
|
||||
for (int i : IndexRange(nodes_num)) {
|
||||
PBVHNode *node = nodes[i];
|
||||
for (PBVHNode *node : nodes) {
|
||||
PBVHVertexIter vd;
|
||||
|
||||
SculptOrigVertData orig_data;
|
||||
SCULPT_orig_vert_data_init(&orig_data, ob, nodes[i], SCULPT_UNDO_COORDS);
|
||||
SCULPT_orig_vert_data_init(&orig_data, ob, node, SCULPT_UNDO_COORDS);
|
||||
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
|
||||
SCULPT_orig_vert_data_update(&orig_data, &vd);
|
||||
@@ -899,7 +889,6 @@ static void sculpt_mesh_filter_cancel(bContext *C, wmOperator * /*op*/)
|
||||
BKE_pbvh_node_mark_update(node);
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
BKE_pbvh_update_bounds(ss->pbvh, PBVH_UpdateBB);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_compiler_compat.h"
|
||||
#include "BLI_gsqueue.h"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_threads.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "ED_view3d.h"
|
||||
|
||||
@@ -46,6 +48,9 @@ struct wmKeyConfig;
|
||||
struct wmOperator;
|
||||
struct wmOperatorType;
|
||||
|
||||
using blender::Span;
|
||||
using blender::Vector;
|
||||
|
||||
/* Updates */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@@ -243,8 +248,7 @@ struct SculptThreadedTaskData {
|
||||
Sculpt *sd;
|
||||
Object *ob;
|
||||
const Brush *brush;
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
Span<PBVHNode *> nodes;
|
||||
|
||||
VPaint *vp;
|
||||
WPaintData *wpd;
|
||||
@@ -469,8 +473,7 @@ struct FilterCache {
|
||||
float (*limit_surface_co)[3];
|
||||
|
||||
/* unmasked nodes */
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
Vector<PBVHNode *> nodes;
|
||||
|
||||
/* Cloth filter. */
|
||||
SculptClothSimulation *cloth_sim;
|
||||
@@ -781,8 +784,7 @@ struct ExpandCache {
|
||||
|
||||
/* Cached PBVH nodes. This allows to skip gathering all nodes from the PBVH each time expand
|
||||
* needs to update the state of the elements. */
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
Vector<PBVHNode *> nodes;
|
||||
|
||||
/* Expand state options. */
|
||||
|
||||
@@ -1171,18 +1173,16 @@ BLI_INLINE bool SCULPT_tool_needs_all_pbvh_nodes(const Brush *brush)
|
||||
}
|
||||
|
||||
void SCULPT_calc_brush_plane(
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3]);
|
||||
Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float r_area_no[3], float r_area_co[3]);
|
||||
|
||||
void SCULPT_calc_area_normal(
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3]);
|
||||
void SCULPT_calc_area_normal(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float r_area_no[3]);
|
||||
/**
|
||||
* This calculates flatten center and area normal together,
|
||||
* amortizing the memory bandwidth and loop overhead to calculate both at the same time.
|
||||
*/
|
||||
void SCULPT_calc_area_normal_and_center(
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3]);
|
||||
void SCULPT_calc_area_center(
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_co[3]);
|
||||
Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float r_area_no[3], float r_area_co[3]);
|
||||
void SCULPT_calc_area_center(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float r_area_co[3]);
|
||||
|
||||
PBVHVertRef SCULPT_nearest_vertex_get(
|
||||
Sculpt *sd, Object *ob, const float co[3], float max_distance, bool use_original);
|
||||
@@ -1453,8 +1453,10 @@ void SCULPT_filter_cache_init(bContext *C,
|
||||
void SCULPT_filter_cache_free(SculptSession *ss);
|
||||
void SCULPT_mesh_filter_properties(wmOperatorType *ot);
|
||||
|
||||
void SCULPT_mask_filter_smooth_apply(
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, int smooth_iterations);
|
||||
void SCULPT_mask_filter_smooth_apply(Sculpt *sd,
|
||||
Object *ob,
|
||||
Span<PBVHNode *> nodes,
|
||||
int smooth_iterations);
|
||||
|
||||
/* Filter orientation utils. */
|
||||
void SCULPT_filter_to_orientation_space(float r_v[3], FilterCache *filter_cache);
|
||||
@@ -1468,7 +1470,7 @@ void SCULPT_filter_zero_disabled_axis_components(float r_v[3], FilterCache *filt
|
||||
* \{ */
|
||||
|
||||
/* Main cloth brush function */
|
||||
void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
|
||||
void SCULPT_cloth_simulation_free(SculptClothSimulation *cloth_sim);
|
||||
|
||||
@@ -1482,20 +1484,19 @@ SculptClothSimulation *SCULPT_cloth_brush_simulation_create(Object *ob,
|
||||
bool needs_deform_coords);
|
||||
void SCULPT_cloth_brush_simulation_init(SculptSession *ss, SculptClothSimulation *cloth_sim);
|
||||
|
||||
void SCULPT_cloth_sim_activate_nodes(SculptClothSimulation *cloth_sim,
|
||||
PBVHNode **nodes,
|
||||
int totnode);
|
||||
void SCULPT_cloth_sim_activate_nodes(SculptClothSimulation *cloth_sim, Span<PBVHNode *> nodes);
|
||||
|
||||
void SCULPT_cloth_brush_store_simulation_state(SculptSession *ss,
|
||||
SculptClothSimulation *cloth_sim);
|
||||
|
||||
void SCULPT_cloth_brush_do_simulation_step(
|
||||
Sculpt *sd, Object *ob, SculptClothSimulation *cloth_sim, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_cloth_brush_do_simulation_step(Sculpt *sd,
|
||||
Object *ob,
|
||||
SculptClothSimulation *cloth_sim,
|
||||
Span<PBVHNode *> nodes);
|
||||
|
||||
void SCULPT_cloth_brush_ensure_nodes_constraints(Sculpt *sd,
|
||||
Object *ob,
|
||||
PBVHNode **nodes,
|
||||
int totnode,
|
||||
Span<PBVHNode *> nodes,
|
||||
SculptClothSimulation *cloth_sim,
|
||||
float initial_location[3],
|
||||
float radius);
|
||||
@@ -1516,9 +1517,7 @@ void SCULPT_cloth_plane_falloff_preview_draw(uint gpuattr,
|
||||
const float outline_col[3],
|
||||
float outline_alpha);
|
||||
|
||||
PBVHNode **SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss,
|
||||
Brush *brush,
|
||||
int *r_totnode);
|
||||
Vector<PBVHNode *> SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss, Brush *brush);
|
||||
|
||||
BLI_INLINE bool SCULPT_is_cloth_deform_brush(const Brush *brush)
|
||||
{
|
||||
@@ -1554,8 +1553,8 @@ void SCULPT_neighbor_coords_average_interior(SculptSession *ss,
|
||||
PBVHVertRef vertex);
|
||||
|
||||
void SCULPT_smooth(
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float bstrength, bool smooth_mask);
|
||||
void SCULPT_do_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float bstrength, bool smooth_mask);
|
||||
void SCULPT_do_smooth_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
|
||||
/* Surface Smooth Brush. */
|
||||
|
||||
@@ -1572,7 +1571,7 @@ void SCULPT_surface_smooth_displace_step(SculptSession *ss,
|
||||
PBVHVertRef vertex,
|
||||
float beta,
|
||||
float fade);
|
||||
void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
|
||||
/* Slide/Relax */
|
||||
void SCULPT_relax_vertex(SculptSession *ss,
|
||||
@@ -1588,8 +1587,7 @@ void SCULPT_relax_vertex(SculptSession *ss,
|
||||
*/
|
||||
bool SCULPT_pbvh_calc_area_normal(const Brush *brush,
|
||||
Object *ob,
|
||||
PBVHNode **nodes,
|
||||
int totnode,
|
||||
Span<PBVHNode *> nodes,
|
||||
bool use_threading,
|
||||
float r_area_no[3]);
|
||||
|
||||
@@ -1745,7 +1743,7 @@ void SCULPT_OT_dynamic_topology_toggle(wmOperatorType *ot);
|
||||
/**
|
||||
* Main Brush Function.
|
||||
*/
|
||||
void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
/**
|
||||
* Calculate the pose origin and (Optionally the pose factor)
|
||||
* that is used when using the pose brush.
|
||||
@@ -1782,7 +1780,7 @@ SculptBoundary *SCULPT_boundary_data_init(Object *object,
|
||||
float radius);
|
||||
void SCULPT_boundary_data_free(SculptBoundary *boundary);
|
||||
/* Main Brush Function. */
|
||||
void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
|
||||
void SCULPT_boundary_edges_preview_draw(uint gpuattr,
|
||||
SculptSession *ss,
|
||||
@@ -1792,30 +1790,28 @@ void SCULPT_boundary_pivot_line_preview_draw(uint gpuattr, SculptSession *ss);
|
||||
|
||||
/* Multi-plane Scrape Brush. */
|
||||
/* Main Brush Function. */
|
||||
void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_multiplane_scrape_preview_draw(uint gpuattr,
|
||||
Brush *brush,
|
||||
SculptSession *ss,
|
||||
const float outline_col[3],
|
||||
float outline_alpha);
|
||||
/* Draw Face Sets Brush. */
|
||||
void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
|
||||
/* Paint Brush. */
|
||||
void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings,
|
||||
Sculpt *sd,
|
||||
Object *ob,
|
||||
PBVHNode **nodes,
|
||||
int totnode,
|
||||
PBVHNode **texnodes,
|
||||
int texnodes_num) ATTR_NONNULL();
|
||||
Span<PBVHNode *> nodes,
|
||||
Span<PBVHNode *> texnodes);
|
||||
|
||||
/**
|
||||
* \brief Get the image canvas for painting on the given object.
|
||||
*
|
||||
* \return #true if an image is found. The #r_image and #r_image_user fields are filled with the
|
||||
* image and image user. Returns false when the image isn't found. In the later case the r_image
|
||||
* and r_image_user are set to NULL.
|
||||
* \return #true if an image is found. The #r_image and #r_image_user fields are filled with
|
||||
* the image and image user. Returns false when the image isn't found. In the later case the
|
||||
* r_image and r_image_user are set to NULL.
|
||||
*/
|
||||
bool SCULPT_paint_image_canvas_get(PaintModeSettings *paint_mode_settings,
|
||||
Object *ob,
|
||||
@@ -1824,44 +1820,42 @@ bool SCULPT_paint_image_canvas_get(PaintModeSettings *paint_mode_settings,
|
||||
void SCULPT_do_paint_brush_image(PaintModeSettings *paint_mode_settings,
|
||||
Sculpt *sd,
|
||||
Object *ob,
|
||||
PBVHNode **texnodes,
|
||||
int texnode_num) ATTR_NONNULL();
|
||||
Span<PBVHNode *> texnodes);
|
||||
bool SCULPT_use_image_paint_brush(PaintModeSettings *settings, Object *ob) ATTR_NONNULL();
|
||||
|
||||
/* Smear Brush. */
|
||||
void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
|
||||
float SCULPT_clay_thumb_get_stabilized_pressure(StrokeCache *cache);
|
||||
|
||||
void SCULPT_do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_draw_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
|
||||
void SCULPT_do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_elastic_deform_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_fill_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_scrape_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_clay_thumb_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_clay_strips_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_snake_hook_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_thumb_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_rotate_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_layer_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_inflate_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_nudge_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_crease_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_pinch_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_grab_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_elastic_deform_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_draw_sharp_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_slide_relax_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
|
||||
void SCULPT_do_displacement_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_displacement_eraser_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_mask_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
|
||||
void SCULPT_do_displacement_smear_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_displacement_eraser_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_mask_brush_draw(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
void SCULPT_do_mask_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes);
|
||||
/** \} */
|
||||
|
||||
void SCULPT_bmesh_topology_rake(
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float bstrength);
|
||||
void SCULPT_bmesh_topology_rake(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float bstrength);
|
||||
|
||||
/* end sculpt_brush_types.cc */
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ static void sculpt_mask_expand_cancel(bContext *C, wmOperator *op)
|
||||
|
||||
MEM_freeN(op->customdata);
|
||||
|
||||
for (int n = 0; n < ss->filter_cache->totnode; n++) {
|
||||
for (int n = 0; n < ss->filter_cache->nodes.size(); n++) {
|
||||
PBVHNode *node = ss->filter_cache->nodes[n];
|
||||
if (create_face_set) {
|
||||
for (int i = 0; i < ss->totfaces; i++) {
|
||||
@@ -190,8 +190,7 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *
|
||||
/* Smooth iterations. */
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
|
||||
const int smooth_iterations = RNA_int_get(op->ptr, "smooth_iterations");
|
||||
SCULPT_mask_filter_smooth_apply(
|
||||
sd, ob, ss->filter_cache->nodes, ss->filter_cache->totnode, smooth_iterations);
|
||||
SCULPT_mask_filter_smooth_apply(sd, ob, ss->filter_cache->nodes, smooth_iterations);
|
||||
|
||||
/* Pivot position. */
|
||||
if (RNA_boolean_get(op->ptr, "update_pivot")) {
|
||||
@@ -201,9 +200,9 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *
|
||||
int total = 0;
|
||||
zero_v3(avg);
|
||||
|
||||
for (int n = 0; n < ss->filter_cache->totnode; n++) {
|
||||
for (PBVHNode *node : ss->filter_cache->nodes) {
|
||||
PBVHVertexIter vd;
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, ss->filter_cache->nodes[n], vd, PBVH_ITER_UNIQUE) {
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
|
||||
const float mask = (vd.mask) ? *vd.mask : 0.0f;
|
||||
if (mask < (0.5f + threshold) && mask > (0.5f - threshold)) {
|
||||
if (SCULPT_check_vertex_pivot_symmetry(
|
||||
@@ -225,8 +224,8 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *
|
||||
|
||||
MEM_freeN(op->customdata);
|
||||
|
||||
for (int i = 0; i < ss->filter_cache->totnode; i++) {
|
||||
BKE_pbvh_node_mark_redraw(ss->filter_cache->nodes[i]);
|
||||
for (PBVHNode *node : ss->filter_cache->nodes) {
|
||||
BKE_pbvh_node_mark_redraw(node);
|
||||
}
|
||||
|
||||
SCULPT_filter_cache_free(ss);
|
||||
@@ -270,8 +269,9 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *
|
||||
data.mask_expand_create_face_set = RNA_boolean_get(op->ptr, "create_face_set");
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
|
||||
BLI_task_parallel_range(0, ss->filter_cache->totnode, &data, sculpt_expand_task_cb, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->nodes.size());
|
||||
BLI_task_parallel_range(
|
||||
0, ss->filter_cache->nodes.size(), &data, sculpt_expand_task_cb, &settings);
|
||||
ss->filter_cache->mask_update_current_it = mask_expand_update_it;
|
||||
}
|
||||
|
||||
@@ -353,23 +353,22 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent
|
||||
|
||||
int vertex_count = SCULPT_vertex_count_get(ss);
|
||||
|
||||
ss->filter_cache = MEM_cnew<FilterCache>(__func__);
|
||||
ss->filter_cache = MEM_new<FilterCache>(__func__);
|
||||
|
||||
BKE_pbvh_search_gather(
|
||||
pbvh, nullptr, nullptr, &ss->filter_cache->nodes, &ss->filter_cache->totnode);
|
||||
ss->filter_cache->nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr);
|
||||
|
||||
SCULPT_undo_push_begin(ob, op);
|
||||
|
||||
if (create_face_set) {
|
||||
for (int i = 0; i < ss->filter_cache->totnode; i++) {
|
||||
BKE_pbvh_node_mark_redraw(ss->filter_cache->nodes[i]);
|
||||
SCULPT_undo_push_node(ob, ss->filter_cache->nodes[i], SCULPT_UNDO_FACE_SETS);
|
||||
for (PBVHNode *node : ss->filter_cache->nodes) {
|
||||
BKE_pbvh_node_mark_redraw(node);
|
||||
SCULPT_undo_push_node(ob, node, SCULPT_UNDO_FACE_SETS);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < ss->filter_cache->totnode; i++) {
|
||||
SCULPT_undo_push_node(ob, ss->filter_cache->nodes[i], SCULPT_UNDO_MASK);
|
||||
BKE_pbvh_node_mark_redraw(ss->filter_cache->nodes[i]);
|
||||
for (PBVHNode *node : ss->filter_cache->nodes) {
|
||||
SCULPT_undo_push_node(ob, node, SCULPT_UNDO_MASK);
|
||||
BKE_pbvh_node_mark_redraw(node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,8 +446,9 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent
|
||||
data.mask_expand_create_face_set = RNA_boolean_get(op->ptr, "create_face_set");
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
|
||||
BLI_task_parallel_range(0, ss->filter_cache->totnode, &data, sculpt_expand_task_cb, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->nodes.size());
|
||||
BLI_task_parallel_range(
|
||||
0, ss->filter_cache->nodes.size(), &data, sculpt_expand_task_cb, &settings);
|
||||
|
||||
const char *status_str = TIP_(
|
||||
"Move the mouse to expand the mask from the active vertex. LMB: confirm mask, ESC/RMB: "
|
||||
|
||||
@@ -117,11 +117,9 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op)
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
|
||||
|
||||
PBVH *pbvh = ob->sculpt->pbvh;
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr);
|
||||
|
||||
if (totnode == 0) {
|
||||
if (nodes.is_empty()) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
@@ -138,15 +136,14 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op)
|
||||
data.mask_init_seed = PIL_check_seconds_timer();
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, mask_init_task_cb, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, mask_init_task_cb, &settings);
|
||||
|
||||
multires_stitch_grids(ob);
|
||||
|
||||
SCULPT_undo_push_end(ob);
|
||||
|
||||
BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateMask);
|
||||
MEM_SAFE_FREE(nodes);
|
||||
SCULPT_tag_update_overlays(C);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ static void do_multiplane_scrape_brush_task_cb_ex(void *__restrict userdata,
|
||||
|
||||
/* Public functions. */
|
||||
|
||||
void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -231,10 +231,10 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes,
|
||||
float temp[3];
|
||||
float mat[4][4];
|
||||
|
||||
SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no_sp, area_co);
|
||||
SCULPT_calc_brush_plane(sd, ob, nodes, area_no_sp, area_co);
|
||||
|
||||
if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA || (brush->flag & BRUSH_ORIGINAL_NORMAL)) {
|
||||
SCULPT_calc_area_normal(sd, ob, nodes, totnode, area_no);
|
||||
SCULPT_calc_area_normal(sd, ob, nodes, area_no);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(area_no, area_no_sp);
|
||||
@@ -281,19 +281,18 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes,
|
||||
sample_data.ob = ob;
|
||||
sample_data.brush = brush;
|
||||
sample_data.nodes = nodes;
|
||||
sample_data.totnode = totnode;
|
||||
sample_data.mat = mat;
|
||||
|
||||
MultiplaneScrapeSampleData mssd = {{{0}}};
|
||||
|
||||
TaskParallelSettings sample_settings;
|
||||
BKE_pbvh_parallel_range_settings(&sample_settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&sample_settings, true, nodes.size());
|
||||
sample_settings.func_reduce = calc_multiplane_scrape_surface_reduce;
|
||||
sample_settings.userdata_chunk = &mssd;
|
||||
sample_settings.userdata_chunk_size = sizeof(MultiplaneScrapeSampleData);
|
||||
|
||||
BLI_task_parallel_range(
|
||||
0, totnode, &sample_data, calc_multiplane_scrape_surface_task_cb, &sample_settings);
|
||||
0, nodes.size(), &sample_data, calc_multiplane_scrape_surface_task_cb, &sample_settings);
|
||||
|
||||
float sampled_plane_normals[2][3];
|
||||
float sampled_plane_co[2][3];
|
||||
@@ -377,8 +376,9 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes,
|
||||
plane_from_point_normal_v3(data.multiplane_scrape_planes[0], area_co, plane_no);
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_multiplane_scrape_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(
|
||||
0, nodes.size(), &data, do_multiplane_scrape_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
void SCULPT_multiplane_scrape_preview_draw(const uint gpuattr,
|
||||
|
||||
@@ -817,9 +817,7 @@ static void sculpt_mask_by_color_contiguous(Object *object,
|
||||
SCULPT_floodfill_execute(ss, &flood, sculpt_mask_by_color_contiguous_floodfill_cb, &ffd);
|
||||
SCULPT_floodfill_free(&flood);
|
||||
|
||||
int totnode;
|
||||
PBVHNode **nodes;
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
|
||||
SculptThreadedTaskData data{};
|
||||
data.ob = object;
|
||||
@@ -831,11 +829,9 @@ static void sculpt_mask_by_color_contiguous(Object *object,
|
||||
data.mask_by_color_preserve_mask = preserve_mask;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(
|
||||
0, totnode, &data, do_mask_by_color_contiguous_update_nodes_cb, &settings);
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
0, nodes.size(), &data, do_mask_by_color_contiguous_update_nodes_cb, &settings);
|
||||
|
||||
MEM_freeN(new_mask);
|
||||
}
|
||||
@@ -885,9 +881,7 @@ static void sculpt_mask_by_color_full_mesh(Object *object,
|
||||
{
|
||||
SculptSession *ss = object->sculpt;
|
||||
|
||||
int totnode;
|
||||
PBVHNode **nodes;
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
|
||||
SculptThreadedTaskData data{};
|
||||
data.ob = object;
|
||||
@@ -898,10 +892,8 @@ static void sculpt_mask_by_color_full_mesh(Object *object,
|
||||
data.mask_by_color_preserve_mask = preserve_mask;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_mask_by_color_task_cb, &settings);
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_mask_by_color_task_cb, &settings);
|
||||
}
|
||||
|
||||
static int sculpt_mask_by_color_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
@@ -1011,7 +1003,7 @@ enum CavityBakeSettingsSource {
|
||||
struct AutomaskBakeTaskData {
|
||||
SculptSession *ss;
|
||||
AutomaskingCache *automasking;
|
||||
PBVHNode **nodes;
|
||||
Span<PBVHNode *> nodes;
|
||||
CavityBakeMixMode mode;
|
||||
float factor;
|
||||
Object *ob;
|
||||
@@ -1089,10 +1081,7 @@ static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op)
|
||||
CavityBakeMixMode mode = CavityBakeMixMode(RNA_enum_get(op->ptr, "mix_mode"));
|
||||
float factor = RNA_float_get(op->ptr, "mix_factor");
|
||||
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
|
||||
AutomaskBakeTaskData tdata;
|
||||
|
||||
@@ -1165,10 +1154,9 @@ static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op)
|
||||
tdata.automasking = SCULPT_automasking_cache_init(&sd2, &brush2, ob);
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &tdata, sculpt_bake_cavity_exec_task_cb, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &tdata, sculpt_bake_cavity_exec_task_cb, &settings);
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
SCULPT_automasking_cache_free(tdata.automasking);
|
||||
|
||||
BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateMask);
|
||||
@@ -1304,13 +1292,11 @@ static int sculpt_reveal_all_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
bool with_bmesh = BKE_pbvh_type(ss->pbvh) == PBVH_BMESH;
|
||||
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
|
||||
if (!totnode) {
|
||||
if (nodes.is_empty()) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
@@ -1319,11 +1305,11 @@ static int sculpt_reveal_all_exec(bContext *C, wmOperator *op)
|
||||
|
||||
SCULPT_undo_push_begin(ob, op);
|
||||
|
||||
for (int i = 0; i < totnode; i++) {
|
||||
BKE_pbvh_node_mark_update_visibility(nodes[i]);
|
||||
for (PBVHNode *node : nodes) {
|
||||
BKE_pbvh_node_mark_update_visibility(node);
|
||||
|
||||
if (!with_bmesh) {
|
||||
SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_HIDDEN);
|
||||
SCULPT_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1367,7 +1353,6 @@ static int sculpt_reveal_all_exec(bContext *C, wmOperator *op)
|
||||
BKE_pbvh_update_visibility(ss->pbvh);
|
||||
|
||||
SCULPT_undo_push_end(ob);
|
||||
MEM_SAFE_FREE(nodes);
|
||||
|
||||
SCULPT_tag_update_overlays(C);
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_SHADING);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_math_color_blend.h"
|
||||
#include "BLI_task.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
||||
@@ -32,6 +33,8 @@
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
|
||||
using blender::Vector;
|
||||
|
||||
static void do_color_smooth_task_cb_exec(void *__restrict userdata,
|
||||
const int n,
|
||||
const TaskParallelTLS *__restrict tls)
|
||||
@@ -252,13 +255,11 @@ static void sample_wet_paint_reduce(const void *__restrict /*userdata*/,
|
||||
void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings,
|
||||
Sculpt *sd,
|
||||
Object *ob,
|
||||
PBVHNode **nodes,
|
||||
int totnode,
|
||||
PBVHNode **texnodes,
|
||||
int texnodes_num)
|
||||
Span<PBVHNode *> nodes,
|
||||
Span<PBVHNode *> texnodes)
|
||||
{
|
||||
if (SCULPT_use_image_paint_brush(paint_mode_settings, ob)) {
|
||||
SCULPT_do_paint_brush_image(paint_mode_settings, sd, ob, texnodes, texnodes_num);
|
||||
SCULPT_do_paint_brush_image(paint_mode_settings, sd, ob, texnodes);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -300,8 +301,8 @@ void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings,
|
||||
data.mat = mat;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_color_smooth_task_cb_exec, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_color_smooth_task_cb_exec, &settings);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -321,11 +322,12 @@ void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings,
|
||||
zero_v4(swptd.color);
|
||||
|
||||
TaskParallelSettings settings_sample;
|
||||
BKE_pbvh_parallel_range_settings(&settings_sample, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings_sample, true, nodes.size());
|
||||
settings_sample.func_reduce = sample_wet_paint_reduce;
|
||||
settings_sample.userdata_chunk = &swptd;
|
||||
settings_sample.userdata_chunk_size = sizeof(SampleWetPaintTLSData);
|
||||
BLI_task_parallel_range(0, totnode, &task_data, do_sample_wet_paint_task_cb, &settings_sample);
|
||||
BLI_task_parallel_range(
|
||||
0, nodes.size(), &task_data, do_sample_wet_paint_task_cb, &settings_sample);
|
||||
|
||||
if (swptd.tot_samples > 0 && is_finite_v4(swptd.color)) {
|
||||
copy_v4_v4(wet_color, swptd.color);
|
||||
@@ -354,8 +356,8 @@ void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings,
|
||||
data.mat = mat;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_paint_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_paint_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
static void do_smear_brush_task_cb_exec(void *__restrict userdata,
|
||||
@@ -525,7 +527,7 @@ static void do_smear_store_prev_colors_task_cb_exec(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
@@ -554,15 +556,16 @@ void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
||||
data.nodes = nodes;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
|
||||
/* Smooth colors mode. */
|
||||
if (ss->cache->alt_smooth) {
|
||||
BLI_task_parallel_range(0, totnode, &data, do_color_smooth_task_cb_exec, &settings);
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_color_smooth_task_cb_exec, &settings);
|
||||
}
|
||||
else {
|
||||
/* Smear mode. */
|
||||
BLI_task_parallel_range(0, totnode, &data, do_smear_store_prev_colors_task_cb_exec, &settings);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_smear_brush_task_cb_exec, &settings);
|
||||
BLI_task_parallel_range(
|
||||
0, nodes.size(), &data, do_smear_store_prev_colors_task_cb_exec, &settings);
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_smear_brush_task_cb_exec, &settings);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ struct ImageData {
|
||||
struct TexturePaintingUserData {
|
||||
Object *ob;
|
||||
Brush *brush;
|
||||
PBVHNode **nodes;
|
||||
Span<PBVHNode *> nodes;
|
||||
ImageData image_data;
|
||||
};
|
||||
|
||||
@@ -534,12 +534,9 @@ static void fix_non_manifold_seam_bleeding(PBVH &pbvh,
|
||||
}
|
||||
}
|
||||
|
||||
static void fix_non_manifold_seam_bleeding(Object &ob,
|
||||
const int totnode,
|
||||
TexturePaintingUserData &user_data)
|
||||
static void fix_non_manifold_seam_bleeding(Object &ob, TexturePaintingUserData &user_data)
|
||||
{
|
||||
Vector<image::TileNumber> dirty_tiles = collect_dirty_tiles(
|
||||
Span<PBVHNode *>(user_data.nodes, totnode));
|
||||
Vector<image::TileNumber> dirty_tiles = collect_dirty_tiles(user_data.nodes);
|
||||
fix_non_manifold_seam_bleeding(*ob.sculpt->pbvh, user_data, dirty_tiles);
|
||||
}
|
||||
|
||||
@@ -583,8 +580,7 @@ bool SCULPT_use_image_paint_brush(PaintModeSettings *settings, Object *ob)
|
||||
void SCULPT_do_paint_brush_image(PaintModeSettings *paint_mode_settings,
|
||||
Sculpt *sd,
|
||||
Object *ob,
|
||||
PBVHNode **texnodes,
|
||||
int texnodes_num)
|
||||
Span<PBVHNode *> texnodes)
|
||||
{
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
|
||||
@@ -598,13 +594,13 @@ void SCULPT_do_paint_brush_image(PaintModeSettings *paint_mode_settings,
|
||||
}
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, texnodes_num);
|
||||
BLI_task_parallel_range(0, texnodes_num, &data, do_push_undo_tile, &settings);
|
||||
BLI_task_parallel_range(0, texnodes_num, &data, do_paint_pixels, &settings);
|
||||
fix_non_manifold_seam_bleeding(*ob, texnodes_num, data);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, texnodes.size());
|
||||
BLI_task_parallel_range(0, texnodes.size(), &data, do_push_undo_tile, &settings);
|
||||
BLI_task_parallel_range(0, texnodes.size(), &data, do_paint_pixels, &settings);
|
||||
fix_non_manifold_seam_bleeding(*ob, data);
|
||||
|
||||
TaskParallelSettings settings_flush;
|
||||
|
||||
BKE_pbvh_parallel_range_settings(&settings_flush, false, texnodes_num);
|
||||
BLI_task_parallel_range(0, texnodes_num, &data, do_mark_dirty_regions, &settings_flush);
|
||||
BKE_pbvh_parallel_range_settings(&settings_flush, false, texnodes.size());
|
||||
BLI_task_parallel_range(0, texnodes.size(), &data, do_mark_dirty_regions, &settings_flush);
|
||||
}
|
||||
|
||||
@@ -259,16 +259,14 @@ static void sculpt_pose_grow_pose_factor(Sculpt *sd,
|
||||
float *r_pose_origin,
|
||||
float *pose_factor)
|
||||
{
|
||||
PBVHNode **nodes;
|
||||
PBVH *pbvh = ob->sculpt->pbvh;
|
||||
int totnode;
|
||||
|
||||
BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr);
|
||||
|
||||
SculptThreadedTaskData data{};
|
||||
data.sd = sd;
|
||||
data.ob = ob;
|
||||
data.nodes = nodes;
|
||||
data.totnode = totnode;
|
||||
data.pose_factor = pose_factor;
|
||||
|
||||
data.pose_initial_co = pose_target;
|
||||
@@ -276,7 +274,7 @@ static void sculpt_pose_grow_pose_factor(Sculpt *sd,
|
||||
PoseGrowFactorTLSData gftd;
|
||||
gftd.pos_count = 0;
|
||||
zero_v3(gftd.pos_avg);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
settings.func_reduce = pose_brush_grow_factor_reduce;
|
||||
settings.userdata_chunk = &gftd;
|
||||
settings.userdata_chunk_size = sizeof(PoseGrowFactorTLSData);
|
||||
@@ -289,7 +287,7 @@ static void sculpt_pose_grow_pose_factor(Sculpt *sd,
|
||||
zero_v3(gftd.pos_avg);
|
||||
gftd.pos_count = 0;
|
||||
memcpy(data.prev_mask, pose_factor, SCULPT_vertex_count_get(ss) * sizeof(float));
|
||||
BLI_task_parallel_range(0, totnode, &data, pose_brush_grow_factor_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, pose_brush_grow_factor_task_cb_ex, &settings);
|
||||
|
||||
if (gftd.pos_count != 0) {
|
||||
mul_v3_fl(gftd.pos_avg, 1.0f / float(gftd.pos_count));
|
||||
@@ -332,8 +330,6 @@ static void sculpt_pose_grow_pose_factor(Sculpt *sd,
|
||||
}
|
||||
}
|
||||
MEM_freeN(data.prev_mask);
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
}
|
||||
|
||||
static bool sculpt_pose_brush_is_vertex_inside_brush_radius(const float vertex[3],
|
||||
@@ -972,11 +968,9 @@ SculptPoseIKChain *SCULPT_pose_ik_chain_init(Sculpt *sd,
|
||||
|
||||
void SCULPT_pose_brush_init(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br)
|
||||
{
|
||||
PBVHNode **nodes;
|
||||
PBVH *pbvh = ob->sculpt->pbvh;
|
||||
int totnode;
|
||||
|
||||
BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr);
|
||||
|
||||
SculptThreadedTaskData data{};
|
||||
data.sd = sd;
|
||||
@@ -993,12 +987,10 @@ void SCULPT_pose_brush_init(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br
|
||||
data.pose_factor = ss->cache->pose_ik_chain->segments[ik].weights;
|
||||
for (int i = 0; i < br->pose_smooth_iterations; i++) {
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, pose_brush_init_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, pose_brush_init_task_cb_ex, &settings);
|
||||
}
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
}
|
||||
|
||||
static void sculpt_pose_do_translate_deform(SculptSession *ss, Brush *brush)
|
||||
@@ -1124,7 +1116,7 @@ static void sculpt_pose_align_pivot_local_space(float r_mat[4][4],
|
||||
ortho_basis_v3v3_v3(r_mat[0], r_mat[1], r_mat[2]);
|
||||
}
|
||||
|
||||
void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -1216,8 +1208,8 @@ void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
data.nodes = nodes;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_pose_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_pose_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
void SCULPT_pose_ik_chain_free(SculptPoseIKChain *ik_chain)
|
||||
|
||||
@@ -228,10 +228,7 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
static void SCULPT_enhance_details_brush(Sculpt *sd,
|
||||
Object *ob,
|
||||
PBVHNode **nodes,
|
||||
const int totnode)
|
||||
static void SCULPT_enhance_details_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -260,8 +257,8 @@ static void SCULPT_enhance_details_brush(Sculpt *sd,
|
||||
data.nodes = nodes;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_enhance_details_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_enhance_details_brush_task_cb_ex, &settings);
|
||||
}
|
||||
|
||||
static void do_smooth_brush_task_cb_ex(void *__restrict userdata,
|
||||
@@ -326,12 +323,8 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata,
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_smooth(Sculpt *sd,
|
||||
Object *ob,
|
||||
PBVHNode **nodes,
|
||||
const int totnode,
|
||||
float bstrength,
|
||||
const bool smooth_mask)
|
||||
void SCULPT_smooth(
|
||||
Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float bstrength, const bool smooth_mask)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
@@ -367,12 +360,12 @@ void SCULPT_smooth(Sculpt *sd,
|
||||
data.strength = strength;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(0, totnode, &data, do_smooth_brush_task_cb_ex, &settings);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0, nodes.size(), &data, do_smooth_brush_task_cb_ex, &settings);
|
||||
}
|
||||
}
|
||||
|
||||
void SCULPT_do_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_smooth_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
|
||||
@@ -382,11 +375,11 @@ void SCULPT_do_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
|
||||
* middle of the stroke. */
|
||||
if (ss->cache->bstrength < 0.0f) {
|
||||
/* Invert mode, intensify details. */
|
||||
SCULPT_enhance_details_brush(sd, ob, nodes, totnode);
|
||||
SCULPT_enhance_details_brush(sd, ob, nodes);
|
||||
}
|
||||
else {
|
||||
/* Regular mode, smooth. */
|
||||
SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, false);
|
||||
SCULPT_smooth(sd, ob, nodes, ss->cache->bstrength, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,7 +529,7 @@ static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex(
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
}
|
||||
|
||||
void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
|
||||
void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
|
||||
{
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
|
||||
@@ -548,11 +541,11 @@ void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
|
||||
data.nodes = nodes;
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
for (int i = 0; i < brush->surface_smooth_iterations; i++) {
|
||||
BLI_task_parallel_range(
|
||||
0, totnode, &data, SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex, &settings);
|
||||
0, nodes.size(), &data, SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex, &settings);
|
||||
BLI_task_parallel_range(
|
||||
0, totnode, &data, SCULPT_do_surface_smooth_brush_displace_task_cb_ex, &settings);
|
||||
0, nodes.size(), &data, SCULPT_do_surface_smooth_brush_displace_task_cb_ex, &settings);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,9 +195,9 @@ static void sculpt_transform_all_vertices(Sculpt *sd, Object *ob)
|
||||
/* Regular transform applies all symmetry passes at once as it is split by symmetry areas
|
||||
* (each vertex can only be transformed once by the transform matrix of its area). */
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->nodes.size());
|
||||
BLI_task_parallel_range(
|
||||
0, ss->filter_cache->totnode, &data, sculpt_transform_task_cb, &settings);
|
||||
0, ss->filter_cache->nodes.size(), &data, sculpt_transform_task_cb, &settings);
|
||||
}
|
||||
|
||||
static void sculpt_elastic_transform_task_cb(void *__restrict userdata,
|
||||
@@ -270,7 +270,7 @@ static void sculpt_transform_radius_elastic(Sculpt *sd, Object *ob, const float
|
||||
ss, symm, ss->filter_cache->transform_displacement_mode, data.transform_mats);
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode);
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->nodes.size());
|
||||
|
||||
/* Elastic transform needs to apply all transform matrices to all vertices and then combine the
|
||||
* displacement proxies as all vertices are modified by all symmetry passes. */
|
||||
@@ -282,7 +282,7 @@ static void sculpt_transform_radius_elastic(Sculpt *sd, Object *ob, const float
|
||||
const int symm_area = SCULPT_get_vertex_symm_area(data.elastic_transform_pivot);
|
||||
copy_m4_m4(data.elastic_transform_mat, data.transform_mats[symm_area]);
|
||||
BLI_task_parallel_range(
|
||||
0, ss->filter_cache->totnode, &data, sculpt_elastic_transform_task_cb, &settings);
|
||||
0, ss->filter_cache->nodes.size(), &data, sculpt_elastic_transform_task_cb, &settings);
|
||||
}
|
||||
}
|
||||
SCULPT_combine_transform_proxies(sd, ob);
|
||||
@@ -413,9 +413,7 @@ static int sculpt_set_pivot_position_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
}
|
||||
else {
|
||||
PBVHNode **nodes;
|
||||
int totnode;
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
|
||||
float avg[3];
|
||||
int total = 0;
|
||||
@@ -423,9 +421,9 @@ static int sculpt_set_pivot_position_exec(bContext *C, wmOperator *op)
|
||||
|
||||
/* Pivot to unmasked. */
|
||||
if (mode == SCULPT_PIVOT_POSITION_UNMASKED) {
|
||||
for (int n = 0; n < totnode; n++) {
|
||||
for (PBVHNode *node : nodes) {
|
||||
PBVHVertexIter vd;
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) {
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
|
||||
const float mask = (vd.mask) ? *vd.mask : 0.0f;
|
||||
if (mask < 1.0f) {
|
||||
if (SCULPT_check_vertex_pivot_symmetry(vd.co, ss->pivot_pos, symm)) {
|
||||
@@ -441,9 +439,9 @@ static int sculpt_set_pivot_position_exec(bContext *C, wmOperator *op)
|
||||
else if (mode == SCULPT_PIVOT_POSITION_MASK_BORDER) {
|
||||
const float threshold = 0.2f;
|
||||
|
||||
for (int n = 0; n < totnode; n++) {
|
||||
for (PBVHNode *node : nodes) {
|
||||
PBVHVertexIter vd;
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) {
|
||||
BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
|
||||
const float mask = (vd.mask) ? *vd.mask : 0.0f;
|
||||
if (mask < (0.5f + threshold) && mask > (0.5f - threshold)) {
|
||||
if (SCULPT_check_vertex_pivot_symmetry(vd.co, ss->pivot_pos, symm)) {
|
||||
@@ -460,8 +458,6 @@ static int sculpt_set_pivot_position_exec(bContext *C, wmOperator *op)
|
||||
mul_v3_fl(avg, 1.0f / total);
|
||||
copy_v3_v3(ss->pivot_pos, avg);
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
}
|
||||
|
||||
/* Update the viewport navigation rotation origin. */
|
||||
|
||||
@@ -659,19 +659,15 @@ static void sculpt_undo_bmesh_restore_generic(SculptUndoNode *unode, Object *ob,
|
||||
}
|
||||
|
||||
if (unode->type == SCULPT_UNDO_MASK) {
|
||||
int totnode;
|
||||
PBVHNode **nodes;
|
||||
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
BLI_task_parallel_range(
|
||||
0, totnode, nodes, sculpt_undo_bmesh_restore_generic_task_cb, &settings);
|
||||
|
||||
if (nodes) {
|
||||
MEM_freeN(nodes);
|
||||
}
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, nodes.size());
|
||||
BLI_task_parallel_range(0,
|
||||
nodes.size(),
|
||||
static_cast<void *>(nodes.data()),
|
||||
sculpt_undo_bmesh_restore_generic_task_cb,
|
||||
&settings);
|
||||
}
|
||||
else {
|
||||
SCULPT_pbvh_clear(ob);
|
||||
@@ -2153,16 +2149,11 @@ static void sculpt_undo_push_all_grids(Object *object)
|
||||
return;
|
||||
}
|
||||
|
||||
PBVHNode **nodes;
|
||||
int totnodes;
|
||||
|
||||
BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnodes);
|
||||
for (int i = 0; i < totnodes; i++) {
|
||||
SculptUndoNode *unode = SCULPT_undo_push_node(object, nodes[i], SCULPT_UNDO_COORDS);
|
||||
Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr);
|
||||
for (PBVHNode *node : nodes) {
|
||||
SculptUndoNode *unode = SCULPT_undo_push_node(object, node, SCULPT_UNDO_COORDS);
|
||||
unode->node = nullptr;
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(nodes);
|
||||
}
|
||||
|
||||
void ED_sculpt_undo_push_multires_mesh_begin(bContext *C, const char *str)
|
||||
|
||||
Reference in New Issue
Block a user