Sculpt Expand: vertex colors target

This commit is contained in:
Pablo Dobarro 2021-01-16 00:42:26 +01:00
parent cd0cf0a5b7
commit df7857a364
2 changed files with 158 additions and 15 deletions

View File

@ -63,6 +63,9 @@
#include "paint_intern.h"
#include "sculpt_intern.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
#include "bmesh.h"
#include <math.h>
@ -79,7 +82,7 @@ enum {
SCULPT_EXPAND_MODAL_FALLOFF_CYCLE,
};
static EnumPropertyItem prop_sculpt_expand_faloff_type_items[] = {
static EnumPropertyItem prop_sculpt_expand_falloff_type_items[] = {
{SCULPT_EXPAND_FALLOFF_GEODESICS, "GEODESICS", 0, "Surface", ""},
{SCULPT_EXPAND_FALLOFF_TOPOLOGY, "TOPOLOGY", 0, "Topology", ""},
{SCULPT_EXPAND_FALLOFF_NORMALS, "NORMALS", 0, "Normals", ""},
@ -88,6 +91,13 @@ static EnumPropertyItem prop_sculpt_expand_faloff_type_items[] = {
{0, NULL, 0, NULL, NULL},
};
static EnumPropertyItem prop_sculpt_expand_target_type_items[] = {
{SCULPT_EXPAND_TARGET_MASK, "MASK", 0, "Mask", ""},
{SCULPT_EXPAND_TARGET_FACE_SETS, "FACE_SETS", 0, "Face Sets", ""},
{SCULPT_EXPAND_TARGET_COLORS, "COLOR", 0, "Color", ""},
{0, NULL, 0, NULL, NULL},
};
static float *sculpt_expand_geodesic_falloff_create(Sculpt *sd, Object *ob, const int vertex)
{
return SCULPT_geodesic_from_vertex_and_symm(sd, ob, vertex, FLT_MAX);
@ -359,6 +369,7 @@ static void sculpt_expand_cache_free(ExpandCache *expand_cache)
MEM_SAFE_FREE(expand_cache->falloff_factor);
MEM_SAFE_FREE(expand_cache->initial_mask);
MEM_SAFE_FREE(expand_cache->initial_face_sets);
MEM_SAFE_FREE(expand_cache->initial_color);
MEM_SAFE_FREE(expand_cache);
}
@ -476,6 +487,59 @@ static void sculpt_expand_mask_update_task_cb(void *__restrict userdata,
}
}
static void sculpt_expand_colors_update_task_cb(void *__restrict userdata,
const int i,
const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
PBVHNode *node = data->nodes[i];
ExpandCache *expand_cache = ss->expand_cache;
bool any_changed = false;
PBVHVertexIter vd;
BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL)
{
float initial_color[4];
copy_v4_v4(initial_color, vd.col);
const bool enabled = sculpt_expand_state_get(expand_cache, vd.index);
float fade;
if (enabled) {
fade = sculpt_expand_gradient_falloff_get(expand_cache, vd.index);
}
else {
fade = 0.0f;
}
fade = clamp_f(fade, 0.0f, 1.0f);
float final_color[4];
float final_fill_color[4];
mul_v4_v4fl(final_fill_color, expand_cache->fill_color, fade);
IMB_blend_color_float(final_color,
expand_cache->initial_color[vd.index],
final_fill_color,
expand_cache->blend_mode);
if (equals_v4v4(initial_color, final_color)) {
continue;
}
copy_v4_v4(vd.col, final_color);
any_changed = true;
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
}
BKE_pbvh_vertex_iter_end;
if (any_changed) {
BKE_pbvh_node_mark_update_color(node);
}
}
static void sculpt_expand_flush_updates(bContext *C)
{
Object *ob = CTX_data_active_object(C);
@ -483,7 +547,21 @@ static void sculpt_expand_flush_updates(bContext *C)
for (int i = 0; i < ss->expand_cache->totnode; i++) {
BKE_pbvh_node_mark_redraw(ss->expand_cache->nodes[i]);
}
SCULPT_flush_update_step(C, SCULPT_UPDATE_MASK);
switch (ss->expand_cache->target) {
case SCULPT_EXPAND_TARGET_MASK:
SCULPT_flush_update_step(C, SCULPT_UPDATE_MASK);
break;
case SCULPT_EXPAND_TARGET_FACE_SETS:
SCULPT_flush_update_step(C, SCULPT_UPDATE_MASK);
break;
case SCULPT_EXPAND_TARGET_COLORS:
SCULPT_flush_update_step(C, SCULPT_UPDATE_COLOR);
break;
default:
break;
}
}
static void sculpt_expand_initial_state_store(Object *ob, ExpandCache *expand_cache)
@ -501,6 +579,13 @@ static void sculpt_expand_initial_state_store(Object *ob, ExpandCache *expand_ca
for (int i = 0; i < totface; i++) {
expand_cache->initial_face_sets[i] = ss->face_sets[i];
}
if (expand_cache->target == SCULPT_EXPAND_TARGET_COLORS) {
expand_cache->initial_color = MEM_malloc_arrayN(totvert, sizeof(float[4]), "initial colors");
for (int i = 0; i < totvert; i++) {
copy_v4_v4(expand_cache->initial_color[i], SCULPT_vertex_color_get(ss, i));
}
}
}
static void sculpt_expand_update_for_vertex(bContext *C, Object *ob, const int vertex)
@ -525,8 +610,21 @@ static void sculpt_expand_update_for_vertex(bContext *C, Object *ob, const int v
TaskParallelSettings settings;
BKE_pbvh_parallel_range_settings(&settings, true, expand_cache->totnode);
BLI_task_parallel_range(
0, expand_cache->totnode, &data, sculpt_expand_mask_update_task_cb, &settings);
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);
break;
case SCULPT_EXPAND_TARGET_FACE_SETS:
BLI_task_parallel_range(
0, expand_cache->totnode, &data, sculpt_expand_mask_update_task_cb, &settings);
break;
case SCULPT_EXPAND_TARGET_COLORS:
BLI_task_parallel_range(
0, expand_cache->totnode, &data, sculpt_expand_colors_update_task_cb, &settings);
break;
}
sculpt_expand_flush_updates(C);
}
@ -550,9 +648,23 @@ static void sculpt_expand_finish(bContext *C)
{
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
sculpt_expand_cache_free(ss->expand_cache);
SCULPT_undo_push_end();
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
switch (ss->expand_cache->target) {
case SCULPT_EXPAND_TARGET_MASK:
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
break;
case SCULPT_EXPAND_TARGET_FACE_SETS:
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
break;
case SCULPT_EXPAND_TARGET_COLORS:
SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COLOR);
break;
default:
break;
}
sculpt_expand_cache_free(ss->expand_cache);
ED_workspace_status_text(C, NULL);
}
@ -595,32 +707,50 @@ static int sculpt_expand_modal(bContext *C, wmOperator *op, const wmEvent *event
return OPERATOR_RUNNING_MODAL;
}
static void sculpt_expand_cache_initial_config_set(ExpandCache *expand_cache, wmOperator *op)
static void sculpt_expand_cache_initial_config_set(Sculpt *sd,
Object *ob,
ExpandCache *expand_cache,
wmOperator *op)
{
expand_cache->invert = RNA_boolean_get(op->ptr, "invert");
expand_cache->mask_preserve = RNA_boolean_get(op->ptr, "use_mask_preserve");
expand_cache->falloff_gradient = RNA_boolean_get(op->ptr, "use_falloff_gradient");
expand_cache->target = RNA_enum_get(op->ptr, "target");
SculptSession *ss = ob->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
copy_v4_fl(expand_cache->fill_color, 1.0f);
copy_v3_v3(expand_cache->fill_color, BKE_brush_color_get(ss->scene, brush));
IMB_colormanagement_srgb_to_scene_linear_v3(expand_cache->fill_color);
expand_cache->blend_mode = brush->blend;
}
static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
/* Create and configure the Expand Cache. */
ss->expand_cache = MEM_callocN(sizeof(ExpandCache), "expand cache");
sculpt_expand_cache_initial_config_set(sd, ob, ss->expand_cache, op);
/* Update object. */
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
const bool needs_colors = ss->expand_cache->target = SCULPT_EXPAND_TARGET_COLORS;
if (needs_colors) {
BKE_sculpt_color_layer_create_if_needed(ob);
depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
}
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, needs_colors);
SCULPT_vertex_random_access_ensure(ss);
SCULPT_boundary_info_ensure(ob);
SCULPT_undo_push_begin(ob, "expand");
/* Create the Expand Cache. */
ss->expand_cache = MEM_callocN(sizeof(ExpandCache), "expand cache");
/* Configure the cache with the operator properties. */
sculpt_expand_cache_initial_config_set(ss->expand_cache, op);
/* Set the initial element for expand. */
int initial_vertex = sculpt_expand_target_vertex_update_and_get(C, ob, event);
if (initial_vertex == SCULPT_EXPAND_VERTEX_NONE) {
@ -699,6 +829,14 @@ void SCULPT_OT_expand(wmOperatorType *ot)
ot->poll = SCULPT_mode_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_enum(ot->srna,
"target",
prop_sculpt_expand_target_type_items,
SCULPT_EXPAND_TARGET_COLORS,
"Data Target",
"Data that is going to be modified in the expand operation");
ot->prop = RNA_def_boolean(
ot->srna, "invert", true, "Invert", "Invert the expand active elements");
ot->prop = RNA_def_boolean(ot->srna,

View File

@ -1161,6 +1161,7 @@ typedef enum eSculptExpandFalloffType {
typedef enum eSculptExpandTargetType {
SCULPT_EXPAND_TARGET_MASK,
SCULPT_EXPAND_TARGET_FACE_SETS,
SCULPT_EXPAND_TARGET_COLORS,
} eSculptExpandTargetType;
typedef struct ExpandCache {
@ -1180,9 +1181,13 @@ typedef struct ExpandCache {
int update_face_set;
float fill_color[4];
short blend_mode;
eSculptExpandTargetType target;
float *initial_mask;
int *initial_face_sets;
float (*initial_color)[4];
} ExpandCache;