Cleanup: de-duplicate copied code w/ vertex paint
This commit is contained in:
@@ -1334,101 +1334,6 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo
|
||||
return true;
|
||||
}
|
||||
|
||||
static void calc_area_normal_and_center_task_cb(void *userdata, const int n)
|
||||
{
|
||||
SculptThreadedTaskData *data = userdata;
|
||||
SculptSession *ss = data->ob->sculpt;
|
||||
float(*area_nos)[3] = data->area_nos;
|
||||
float(*area_cos)[3] = data->area_cos;
|
||||
|
||||
float private_co[2][3] = {{0.0f}};
|
||||
float private_no[2][3] = {{0.0f}};
|
||||
int private_count[2] = {0};
|
||||
|
||||
SculptBrushTest test;
|
||||
sculpt_brush_test_init(ss, &test);
|
||||
|
||||
PBVHVertexIter vd;
|
||||
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
|
||||
{
|
||||
const float *co;
|
||||
|
||||
co = vd.co;
|
||||
|
||||
if (sculpt_brush_test_fast(&test, co)) {
|
||||
float no_buf[3];
|
||||
const float *no;
|
||||
int flip_index;
|
||||
|
||||
if (vd.no) {
|
||||
normal_short_to_float_v3(no_buf, vd.no);
|
||||
no = no_buf;
|
||||
}
|
||||
else {
|
||||
no = vd.fno;
|
||||
}
|
||||
|
||||
flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f);
|
||||
if (area_cos)
|
||||
add_v3_v3(private_co[flip_index], co);
|
||||
if (area_nos)
|
||||
add_v3_v3(private_no[flip_index], no);
|
||||
private_count[flip_index] += 1;
|
||||
}
|
||||
}
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
|
||||
|
||||
BLI_mutex_lock(&data->mutex);
|
||||
|
||||
/* for flatten center */
|
||||
if (area_cos) {
|
||||
add_v3_v3(area_cos[0], private_co[0]);
|
||||
add_v3_v3(area_cos[1], private_co[1]);
|
||||
}
|
||||
|
||||
/* for area normal */
|
||||
if (area_nos) {
|
||||
add_v3_v3(area_nos[0], private_no[0]);
|
||||
add_v3_v3(area_nos[1], private_no[1]);
|
||||
}
|
||||
|
||||
/* weights */
|
||||
data->count[0] += private_count[0];
|
||||
data->count[1] += private_count[1];
|
||||
|
||||
BLI_mutex_unlock(&data->mutex);
|
||||
}
|
||||
|
||||
static void calc_area_normal(
|
||||
VPaint *vp, Object *ob,
|
||||
PBVHNode **nodes, int totnode,
|
||||
float r_area_no[3])
|
||||
{
|
||||
/* 0=towards view, 1=flipped */
|
||||
float area_nos[2][3] = {{0.0f}};
|
||||
|
||||
int count[2] = {0};
|
||||
|
||||
SculptThreadedTaskData data = {
|
||||
.vp = vp, .ob = ob, .nodes = nodes, .totnode = totnode,
|
||||
.area_cos = NULL, .area_nos = area_nos, .count = count,
|
||||
};
|
||||
BLI_mutex_init(&data.mutex);
|
||||
|
||||
BLI_task_parallel_range(
|
||||
0, totnode, &data, calc_area_normal_and_center_task_cb, true);
|
||||
|
||||
BLI_mutex_end(&data.mutex);
|
||||
|
||||
/* for area normal */
|
||||
for (int i = 0; i < ARRAY_SIZE(area_nos); i++) {
|
||||
if (normalize_v3_v3(r_area_no, area_nos[i]) != 0.0f) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static float dot_vf3vs3(const float brushNormal[3], const short vertexNormal[3])
|
||||
{
|
||||
float normal[3];
|
||||
@@ -1436,42 +1341,6 @@ static float dot_vf3vs3(const float brushNormal[3], const short vertexNormal[3])
|
||||
return dot_v3v3(brushNormal, normal);
|
||||
}
|
||||
|
||||
/* Flip all the editdata across the axis/axes specified by symm. Used to
|
||||
* calculate multiple modifications to the mesh when symmetry is enabled. */
|
||||
static void calc_brushdata_symm(
|
||||
VPaint *vd, StrokeCache *cache, const char symm,
|
||||
const char axis, const float angle)
|
||||
{
|
||||
(void)vd; /* unused */
|
||||
|
||||
flip_v3_v3(cache->location, cache->true_location, symm);
|
||||
flip_v3_v3(cache->last_location, cache->true_last_location, symm);
|
||||
flip_v3_v3(cache->grab_delta_symmetry, cache->grab_delta, symm);
|
||||
flip_v3_v3(cache->view_normal, cache->true_view_normal, symm);
|
||||
|
||||
unit_m4(cache->symm_rot_mat);
|
||||
unit_m4(cache->symm_rot_mat_inv);
|
||||
zero_v3(cache->plane_offset);
|
||||
|
||||
if (axis) { /* expects XYZ */
|
||||
rotate_m4(cache->symm_rot_mat, axis, angle);
|
||||
rotate_m4(cache->symm_rot_mat_inv, axis, -angle);
|
||||
}
|
||||
|
||||
mul_m4_v3(cache->symm_rot_mat, cache->location);
|
||||
mul_m4_v3(cache->symm_rot_mat, cache->last_location);
|
||||
mul_m4_v3(cache->symm_rot_mat, cache->grab_delta_symmetry);
|
||||
|
||||
if (cache->supports_gravity) {
|
||||
flip_v3_v3(cache->gravity_direction, cache->true_gravity_direction, symm);
|
||||
mul_m4_v3(cache->symm_rot_mat, cache->gravity_direction);
|
||||
}
|
||||
|
||||
if (cache->is_rake_rotation_valid) {
|
||||
flip_qt_qt(cache->rake_rotation_symmetry, cache->rake_rotation, symm);
|
||||
}
|
||||
}
|
||||
|
||||
static void get_brush_alpha_data(
|
||||
Scene *scene, SculptSession *ss, Brush *brush,
|
||||
float *r_brush_size_pressure, float *r_brush_alpha_value, float *r_brush_alpha_pressure)
|
||||
@@ -1829,11 +1698,11 @@ static void wpaint_paint_leaves(
|
||||
|
||||
static void wpaint_do_paint(
|
||||
bContext *C, Object *ob, VPaint *wp, Sculpt *sd, struct WPaintData *wpd, WeightPaintInfo *wpi,
|
||||
Mesh *me, Brush *UNUSED(brush), const char symm, const int axis, const int i, const float angle)
|
||||
Mesh *me, Brush *brush, const char symm, const int axis, const int i, const float angle)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
ss->cache->radial_symmetry_pass = i;
|
||||
calc_brushdata_symm(wp, ss->cache, symm, axis, angle);
|
||||
sculpt_cache_calc_brushdata_symm(ss->cache, symm, axis, angle);
|
||||
|
||||
SculptSearchSphereData data;
|
||||
PBVHNode **nodes = NULL;
|
||||
@@ -1847,7 +1716,7 @@ static void wpaint_do_paint(
|
||||
data.original = true;
|
||||
BKE_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode);
|
||||
|
||||
calc_area_normal(wp, ob, nodes, totnode, ss->cache->sculpt_normal_symm);
|
||||
sculpt_pbvh_calc_area_normal(brush, ob, nodes, totnode, true, ss->cache->sculpt_normal_symm);
|
||||
wpaint_paint_leaves(C, ob, sd, wp, wpd, wpi, me, nodes, totnode);
|
||||
|
||||
if (nodes)
|
||||
@@ -1864,6 +1733,7 @@ static void wpaint_do_radial_symmetry(
|
||||
}
|
||||
}
|
||||
|
||||
/* near duplicate of: sculpt.c's, 'do_symmetrical_brush_actions' and 'vpaint_do_symmetrical_brush_actions'. */
|
||||
static void wpaint_do_symmetrical_brush_actions(
|
||||
bContext *C, Object *ob, VPaint *wp, Sculpt *sd, struct WPaintData *wpd, WeightPaintInfo *wpi)
|
||||
{
|
||||
@@ -1887,7 +1757,7 @@ static void wpaint_do_symmetrical_brush_actions(
|
||||
if ((symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) {
|
||||
cache->mirror_symmetry_pass = i;
|
||||
cache->radial_symmetry_pass = 0;
|
||||
calc_brushdata_symm(wp, cache, i, 0, 0);
|
||||
sculpt_cache_calc_brushdata_symm(cache, i, 0, 0);
|
||||
|
||||
if (i & (1 << 0)) {
|
||||
wpaint_do_paint(C, ob, wp, sd, wpd, wpi, me, brush, i, 'X', 0, 0);
|
||||
@@ -2757,11 +2627,11 @@ static void vpaint_paint_leaves(
|
||||
|
||||
static void vpaint_do_paint(
|
||||
bContext *C, Sculpt *sd, VPaint *vd, struct VPaintData *vpd,
|
||||
Object *ob, Mesh *me, Brush *UNUSED(brush), const char symm, const int axis, const int i, const float angle)
|
||||
Object *ob, Mesh *me, Brush *brush, const char symm, const int axis, const int i, const float angle)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
ss->cache->radial_symmetry_pass = i;
|
||||
calc_brushdata_symm(vd, ss->cache, symm, axis, angle);
|
||||
sculpt_cache_calc_brushdata_symm(ss->cache, symm, axis, angle);
|
||||
SculptSearchSphereData data;
|
||||
PBVHNode **nodes = NULL;
|
||||
int totnode;
|
||||
@@ -2773,7 +2643,7 @@ static void vpaint_do_paint(
|
||||
data.original = true;
|
||||
BKE_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode);
|
||||
|
||||
calc_area_normal(vd, ob, nodes, totnode, ss->cache->sculpt_normal_symm);
|
||||
sculpt_pbvh_calc_area_normal(brush, ob, nodes, totnode, true, ss->cache->sculpt_normal_symm);
|
||||
|
||||
/* Paint those leaves. */
|
||||
vpaint_paint_leaves(C, sd, vd, vpd, ob, me, nodes, totnode);
|
||||
@@ -2793,6 +2663,7 @@ static void vpaint_do_radial_symmetry(
|
||||
}
|
||||
}
|
||||
|
||||
/* near duplicate of: sculpt.c's, 'do_symmetrical_brush_actions' and 'wpaint_do_symmetrical_brush_actions'. */
|
||||
static void vpaint_do_symmetrical_brush_actions(
|
||||
bContext *C, Sculpt *sd, VPaint *vd, struct VPaintData *vpd, Object *ob)
|
||||
{
|
||||
@@ -2816,7 +2687,7 @@ static void vpaint_do_symmetrical_brush_actions(
|
||||
if (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5))) {
|
||||
cache->mirror_symmetry_pass = i;
|
||||
cache->radial_symmetry_pass = 0;
|
||||
calc_brushdata_symm(vd, cache, i, 0, 0);
|
||||
sculpt_cache_calc_brushdata_symm(cache, i, 0, 0);
|
||||
|
||||
if (i & (1 << 0)) {
|
||||
vpaint_do_paint(C, sd, vd, vpd, ob, me, brush, i, 'X', 0, 0);
|
||||
|
||||
@@ -752,17 +752,19 @@ static void calc_area_normal_and_center_task_cb(void *userdata, const int n)
|
||||
|
||||
PBVHVertexIter vd;
|
||||
SculptBrushTest test;
|
||||
SculptUndoNode *unode;
|
||||
SculptUndoNode *unode = NULL;
|
||||
|
||||
float private_co[2][3] = {{0.0f}};
|
||||
float private_no[2][3] = {{0.0f}};
|
||||
int private_count[2] = {0};
|
||||
bool use_original;
|
||||
bool use_original = false;
|
||||
|
||||
unode = sculpt_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
|
||||
if (ss->cache->original) {
|
||||
unode = sculpt_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
|
||||
use_original = (unode->co || unode->bm_entry);
|
||||
}
|
||||
sculpt_brush_test_init(ss, &test);
|
||||
|
||||
use_original = (ss->cache->original && (unode->co || unode->bm_entry));
|
||||
|
||||
/* when the mesh is edited we can't rely on original coords
|
||||
* (original mesh may not even have verts in brush radius) */
|
||||
@@ -884,8 +886,9 @@ static void calc_area_center(
|
||||
|
||||
int count[2] = {0};
|
||||
|
||||
/* Intentionally set 'sd' to NULL since we share logic with vertex paint. */
|
||||
SculptThreadedTaskData data = {
|
||||
.sd = sd, .ob = ob, .nodes = nodes, .totnode = totnode,
|
||||
.sd = NULL, .ob = ob, .nodes = nodes, .totnode = totnode,
|
||||
.has_bm_orco = has_bm_orco, .area_cos = area_cos, .area_nos = NULL, .count = count,
|
||||
};
|
||||
BLI_mutex_init(&data.mutex);
|
||||
@@ -908,42 +911,53 @@ static void calc_area_center(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void calc_area_normal(
|
||||
Sculpt *sd, Object *ob,
|
||||
PBVHNode **nodes, int totnode,
|
||||
float r_area_no[3])
|
||||
{
|
||||
const Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
bool use_threading = (sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT;
|
||||
sculpt_pbvh_calc_area_normal(brush, ob, nodes, totnode, use_threading, r_area_no);
|
||||
}
|
||||
|
||||
/* expose 'calc_area_normal' externally. */
|
||||
void sculpt_pbvh_calc_area_normal(
|
||||
const Brush *brush, Object *ob,
|
||||
PBVHNode **nodes, int totnode,
|
||||
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);
|
||||
int n;
|
||||
|
||||
/* 0=towards view, 1=flipped */
|
||||
float area_nos[2][3] = {{0.0f}};
|
||||
|
||||
int count[2] = {0};
|
||||
|
||||
/* Intentionally set 'sd' to NULL since this is used for vertex paint too. */
|
||||
SculptThreadedTaskData data = {
|
||||
.sd = sd, .ob = ob, .nodes = nodes, .totnode = totnode,
|
||||
.sd = NULL, .ob = ob, .nodes = nodes, .totnode = totnode,
|
||||
.has_bm_orco = has_bm_orco, .area_cos = NULL, .area_nos = area_nos, .count = count,
|
||||
};
|
||||
BLI_mutex_init(&data.mutex);
|
||||
|
||||
BLI_task_parallel_range(
|
||||
0, totnode, &data, calc_area_normal_and_center_task_cb,
|
||||
((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT));
|
||||
use_threading);
|
||||
|
||||
BLI_mutex_end(&data.mutex);
|
||||
|
||||
/* for area normal */
|
||||
for (n = 0; n < ARRAY_SIZE(area_nos); n++) {
|
||||
if (normalize_v3_v3(r_area_no, area_nos[n]) != 0.0f) {
|
||||
for (int i = 0; i < ARRAY_SIZE(area_nos); i++) {
|
||||
if (normalize_v3_v3(r_area_no, area_nos[i]) != 0.0f) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* this calculates flatten center and area normal together,
|
||||
* amortizing the memory bandwidth and loop overhead to calculate both at the same time */
|
||||
static void calc_area_normal_and_center(
|
||||
@@ -962,8 +976,9 @@ static void calc_area_normal_and_center(
|
||||
|
||||
int count[2] = {0};
|
||||
|
||||
/* Intentionally set 'sd' to NULL since this is used for vertex paint too. */
|
||||
SculptThreadedTaskData data = {
|
||||
.sd = sd, .ob = ob, .nodes = nodes, .totnode = totnode,
|
||||
.sd = NULL, .ob = ob, .nodes = nodes, .totnode = totnode,
|
||||
.has_bm_orco = has_bm_orco, .area_cos = area_cos, .area_nos = area_nos, .count = count,
|
||||
};
|
||||
BLI_mutex_init(&data.mutex);
|
||||
@@ -3552,12 +3567,10 @@ static void sculpt_flush_stroke_deform(Sculpt *sd, Object *ob)
|
||||
|
||||
/* Flip all the editdata across the axis/axes specified by symm. Used to
|
||||
* calculate multiple modifications to the mesh when symmetry is enabled. */
|
||||
static void calc_brushdata_symm(Sculpt *sd, StrokeCache *cache, const char symm,
|
||||
const char axis, const float angle,
|
||||
const float UNUSED(feather))
|
||||
void sculpt_cache_calc_brushdata_symm(
|
||||
StrokeCache *cache, const char symm,
|
||||
const char axis, const float angle)
|
||||
{
|
||||
(void)sd; /* unused */
|
||||
|
||||
flip_v3_v3(cache->location, cache->true_location, symm);
|
||||
flip_v3_v3(cache->grab_delta_symmetry, cache->grab_delta, symm);
|
||||
flip_v3_v3(cache->view_normal, cache->true_view_normal, symm);
|
||||
@@ -3655,7 +3668,7 @@ static void do_tiled(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings
|
||||
static void do_radial_symmetry(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings *ups,
|
||||
BrushActionFunc action,
|
||||
const char symm, const int axis,
|
||||
const float feather)
|
||||
const float UNUSED(feather))
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
int i;
|
||||
@@ -3663,7 +3676,7 @@ static void do_radial_symmetry(Sculpt *sd, Object *ob, Brush *brush, UnifiedPain
|
||||
for (i = 1; i < sd->radial_symm[axis - 'X']; ++i) {
|
||||
const float angle = 2 * M_PI * i / sd->radial_symm[axis - 'X'];
|
||||
ss->cache->radial_symmetry_pass = i;
|
||||
calc_brushdata_symm(sd, ss->cache, symm, axis, angle, feather);
|
||||
sculpt_cache_calc_brushdata_symm(ss->cache, symm, axis, angle);
|
||||
do_tiled(sd, ob, brush, ups, action);
|
||||
}
|
||||
}
|
||||
@@ -3681,8 +3694,9 @@ static void sculpt_fix_noise_tear(Sculpt *sd, Object *ob)
|
||||
multires_stitch_grids(ob);
|
||||
}
|
||||
|
||||
static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob,
|
||||
BrushActionFunc action, UnifiedPaintSettings *ups)
|
||||
static void do_symmetrical_brush_actions(
|
||||
Sculpt *sd, Object *ob,
|
||||
BrushActionFunc action, UnifiedPaintSettings *ups)
|
||||
{
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
@@ -3701,7 +3715,7 @@ static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob,
|
||||
cache->mirror_symmetry_pass = i;
|
||||
cache->radial_symmetry_pass = 0;
|
||||
|
||||
calc_brushdata_symm(sd, cache, i, 0, 0, feather);
|
||||
sculpt_cache_calc_brushdata_symm(cache, i, 0, 0);
|
||||
do_tiled(sd, ob, brush, ups, action);
|
||||
|
||||
do_radial_symmetry(sd, ob, brush, ups, action, i, 'X', feather);
|
||||
|
||||
@@ -207,6 +207,12 @@ float tex_strength(
|
||||
const float mask,
|
||||
const int thread_id);
|
||||
|
||||
/* just for vertex paint. */
|
||||
void sculpt_pbvh_calc_area_normal(
|
||||
const struct Brush *brush, Object *ob,
|
||||
PBVHNode **nodes, int totnode,
|
||||
bool use_threading,
|
||||
float r_area_no[3]);
|
||||
|
||||
/* Cache stroke properties. Used because
|
||||
* RNA property lookup isn't particularly fast.
|
||||
@@ -304,6 +310,9 @@ typedef struct StrokeCache {
|
||||
|
||||
} StrokeCache;
|
||||
|
||||
void sculpt_cache_calc_brushdata_symm(
|
||||
StrokeCache *cache, const char symm,
|
||||
const char axis, const float angle);
|
||||
void sculpt_cache_free(StrokeCache *cache);
|
||||
|
||||
SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType type);
|
||||
|
||||
Reference in New Issue
Block a user