Sculpt: Refactor persistent base to make it usable from other tools

This renames the layer persistent base and adds new API functions to get
the mesh state from the base, so it can be used from other tools and
replaced in the future with a better system.

Reviewed By: sergey

Maniphest Tasks: T77738

Differential Revision: https://developer.blender.org/D8003
This commit is contained in:
Pablo Dobarro 2020-06-11 20:15:57 +02:00
parent 981d7381cd
commit a3e6b7c2ce
Notes: blender-bot 2023-02-13 22:11:11 +01:00
Referenced by issue #78510, Boolean and Parenting Inconsistencies
Referenced by issue #78517, 'Crop Image size' in 'Crop' node removes helpful compositor transform widget
Referenced by issue #78486, Blender crashes on keymap->poll
Referenced by issue #78483, EEVEE animation render crashes periodically
Referenced by issue #78384, Mantaflow - liquid sim - strange behaviour
Referenced by issue #77738, Sculpt persistent mesh state management
3 changed files with 32 additions and 15 deletions

View File

@ -283,11 +283,11 @@ typedef struct SculptClothSimulation {
} SculptClothSimulation;
typedef struct SculptLayerPersistentBase {
typedef struct SculptPersistentBase {
float co[3];
float no[3];
float disp;
} SculptLayerPersistentBase;
} SculptPersistentBase;
typedef struct SculptVertexInfo {
/* Idexed by vertex, stores and ID of its topologycally connected component. */
@ -392,9 +392,9 @@ typedef struct SculptSession {
float pose_origin[3];
SculptPoseIKChain *pose_ik_chain_preview;
/* Layer brush persistence between strokes */
/* Mesh State Persistence */
/* This is freed with the PBVH, so it is always in sync with the mesh. */
SculptLayerPersistentBase *layer_base;
SculptPersistentBase *persistent_base;
SculptVertexInfo vertex_info;
SculptFakeNeighbors fake_neighbors;

View File

@ -1310,7 +1310,7 @@ static void sculptsession_free_pbvh(Object *object)
MEM_SAFE_FREE(ss->pmap);
MEM_SAFE_FREE(ss->pmap_mem);
MEM_SAFE_FREE(ss->layer_base);
MEM_SAFE_FREE(ss->persistent_base);
MEM_SAFE_FREE(ss->preview_vert_index_list);
ss->preview_vert_index_count = 0;

View File

@ -198,6 +198,23 @@ void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3])
}
}
const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, int index)
{
if (ss->persistent_base) {
return ss->persistent_base[index].co;
}
return SCULPT_vertex_co_get(ss, index);
}
void SCULPT_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3])
{
if (ss->persistent_base) {
copy_v3_v3(no, ss->persistent_base[index].no);
return;
}
SCULPT_vertex_normal_get(ss, index, no);
}
float SCULPT_vertex_mask_get(SculptSession *ss, int index)
{
BMVert *v;
@ -4136,7 +4153,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
Sculpt *sd = data->sd;
const Brush *brush = data->brush;
const bool use_persistent_base = ss->layer_base && brush->flag & BRUSH_PERSISTENT;
const bool use_persistent_base = ss->persistent_base && brush->flag & BRUSH_PERSISTENT;
PBVHVertexIter vd;
SculptOrigVertData orig_data;
@ -4166,7 +4183,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
const int vi = vd.index;
float *disp_factor;
if (use_persistent_base) {
disp_factor = &ss->layer_base[vi].disp;
disp_factor = &ss->persistent_base[vi].disp;
}
else {
disp_factor = &ss->cache->layer_displacement_factor[vi];
@ -4196,9 +4213,9 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
float normal[3];
if (use_persistent_base) {
copy_v3_v3(normal, ss->layer_base[vi].no);
SCULPT_vertex_persistent_normal_get(ss, vi, normal);
mul_v3_fl(normal, brush->height);
madd_v3_v3v3fl(final_co, ss->layer_base[vi].co, normal, *disp_factor);
madd_v3_v3v3fl(final_co, SCULPT_vertex_persistent_co_get(ss, vi), normal, *disp_factor);
}
else {
normal_short_to_float_v3(normal, orig_data.no);
@ -7457,16 +7474,16 @@ static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op))
SCULPT_vertex_random_access_init(ss);
BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
MEM_SAFE_FREE(ss->layer_base);
MEM_SAFE_FREE(ss->persistent_base);
const int totvert = SCULPT_vertex_count_get(ss);
ss->layer_base = MEM_mallocN(sizeof(SculptLayerPersistentBase) * totvert,
"layer persistent base");
ss->persistent_base = MEM_mallocN(sizeof(SculptPersistentBase) * totvert,
"layer persistent base");
for (int i = 0; i < totvert; i++) {
copy_v3_v3(ss->layer_base[i].co, SCULPT_vertex_co_get(ss, i));
SCULPT_vertex_normal_get(ss, i, ss->layer_base[i].no);
ss->layer_base[i].disp = 0.0f;
copy_v3_v3(ss->persistent_base[i].co, SCULPT_vertex_co_get(ss, i));
SCULPT_vertex_normal_get(ss, i, ss->persistent_base[i].no);
ss->persistent_base[i].disp = 0.0f;
}
}