diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 6dd42380a11..e95632ef8c4 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -118,12 +118,16 @@ void PAINT_OT_vertex_paint(struct wmOperatorType *ot); unsigned int vpaint_get_current_col(struct VPaint *vp); +typedef struct VertProjData { + struct DMCoNo *vcosnos; + float *dists_sq; + float (*ss_co)[2]; +} VertProjData; /* paint_vertex_proj.c */ struct VertProjHandle; -struct VertProjHandle *ED_vpaint_proj_handle_create( - struct Scene *scene, struct Object *ob, - struct DMCoNo **r_vcosnos); +struct VertProjHandle *ED_vpaint_proj_handle_create(struct Scene *scene, struct Object *ob, + VertProjData **r_vcosnos); void ED_vpaint_proj_handle_update( struct VertProjHandle *vp_handle, /* runtime vars */ diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index e058f924a7b..17e86b2738f 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -910,37 +910,29 @@ static int sample_backbuf_area(ViewContext *vc, int *indexar, int totface, int x } /* whats _dl mean? */ -static float calc_vp_strength_col_dl(VPaint *vp, ViewContext *vc, const float co[3], - const float mval[2], const float brush_size_pressure, float rgba[4]) +static float calc_vp_strength_col_dl(VPaint *vp, ViewContext *vc, const VertProjData *data, const int index, + const float brush_size_pressure, float rgba[4]) { - float co_ss[2]; /* screenspace */ + float dist_sq = data->dists_sq[index]; + if (dist_sq <= brush_size_pressure * brush_size_pressure) { + Brush *brush = BKE_paint_brush(&vp->paint); + const float dist = sqrtf(dist_sq); + float factor; - if (ED_view3d_project_float_object(vc->ar, - co, co_ss, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) - { - const float dist_sq = len_squared_v2v2(mval, co_ss); - - if (dist_sq <= brush_size_pressure * brush_size_pressure) { - Brush *brush = BKE_paint_brush(&vp->paint); - const float dist = sqrtf(dist_sq); - float factor; - - if (brush->mtex.tex && rgba) { - if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) { - BKE_brush_sample_tex_3D(vc->scene, brush, co, rgba, 0, NULL); - } - else { - const float co_ss_3d[3] = {co_ss[0], co_ss[1], 0.0f}; /* we need a 3rd empty value */ - BKE_brush_sample_tex_3D(vc->scene, brush, co_ss_3d, rgba, 0, NULL); - } - factor = rgba[3]; + if (brush->mtex.tex && rgba) { + if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) { + BKE_brush_sample_tex_3D(vc->scene, brush, data->vcosnos[index].co, rgba, 0, NULL); } else { - factor = 1.0f; + const float co_ss_3d[3] = {data->ss_co[index][0], data->ss_co[index][1], 0.0f}; /* we need a 3rd empty value */ + BKE_brush_sample_tex_3D(vc->scene, brush, co_ss_3d, rgba, 0, NULL); } - return factor * BKE_brush_curve_strength_clamp(brush, dist, brush_size_pressure); + factor = rgba[3]; } + else { + factor = 1.0f; + } + return factor * BKE_brush_curve_strength_clamp(brush, dist, brush_size_pressure); } if (rgba) zero_v4(rgba); @@ -948,11 +940,11 @@ static float calc_vp_strength_col_dl(VPaint *vp, ViewContext *vc, const float co } static float calc_vp_alpha_col_dl(VPaint *vp, ViewContext *vc, - float vpimat[3][3], const DMCoNo *v_co_no, - const float mval[2], + float vpimat[3][3], const VertProjData *data, + const int index, const float brush_size_pressure, const float brush_alpha_pressure, float rgba[4]) { - float strength = calc_vp_strength_col_dl(vp, vc, v_co_no->co, mval, brush_size_pressure, rgba); + float strength = calc_vp_strength_col_dl(vp, vc, data, index, brush_size_pressure, rgba); if (strength > 0.0f) { float alpha = brush_alpha_pressure * strength; @@ -961,10 +953,10 @@ static float calc_vp_alpha_col_dl(VPaint *vp, ViewContext *vc, float dvec[3]; /* transpose ! */ - dvec[2] = dot_v3v3(vpimat[2], v_co_no->no); + dvec[2] = dot_v3v3(vpimat[2], data->vcosnos[index].no); if (dvec[2] > 0.0f) { - dvec[0] = dot_v3v3(vpimat[0], v_co_no->no); - dvec[1] = dot_v3v3(vpimat[1], v_co_no->no); + dvec[0] = dot_v3v3(vpimat[0], data->vcosnos[index].no); + dvec[1] = dot_v3v3(vpimat[1], data->vcosnos[index].no); alpha *= dvec[2] / len_v3(dvec); } @@ -2131,7 +2123,7 @@ struct WPaintData { int vgroup_mirror; void *vp_handle; - DMCoNo *vertexcosnos; + VertProjData *data; float wpimat[3][3]; @@ -2241,7 +2233,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UN } /* painting on subsurfs should give correct points too, this returns me->totvert amount */ - wpd->vp_handle = ED_vpaint_proj_handle_create(scene, ob, &wpd->vertexcosnos); + wpd->vp_handle = ED_vpaint_proj_handle_create(scene, ob, &wpd->data); wpd->indexar = get_indexarray(me); copy_wpaint_prev(wp, me->dvert, me->totvert); @@ -2385,7 +2377,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P #define WP_BLUR_ACCUM(v_idx_var) \ { \ const unsigned int vidx = v_idx_var; \ - const float fac = calc_vp_strength_col_dl(wp, vc, wpd->vertexcosnos[vidx].co, mval, brush_size_pressure, NULL); \ + const float fac = calc_vp_strength_col_dl(wp, vc, wpd->data, vidx, brush_size_pressure, NULL); \ if (fac > 0.0f) { \ MDeformWeight *dw = dw_func(&me->dvert[vidx], wpi.vgroup_active); \ paintweight += dw ? (dw->weight * fac) : 0.0f; \ @@ -2455,8 +2447,8 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P { \ unsigned int vidx = v_idx_var; \ if (me->dvert[vidx].flag) { \ - alpha = calc_vp_alpha_col_dl(wp, vc, wpd->wpimat, &wpd->vertexcosnos[vidx], \ - mval, brush_size_pressure, brush_alpha_pressure, NULL); \ + alpha = calc_vp_alpha_col_dl(wp, vc, wpd->wpimat, wpd->data, vidx, \ + brush_size_pressure, brush_alpha_pressure, NULL); \ if (alpha) { \ do_weight_paint_vertex(wp, ob, &wpi, vidx, alpha, paintweight); \ } \ @@ -2743,7 +2735,7 @@ typedef struct VPaintData { int *indexar; struct VertProjHandle *vp_handle; - DMCoNo *vertexcosnos; + VertProjData *data; float vpimat[3][3]; @@ -2811,7 +2803,7 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f paint_stroke_set_mode_data(stroke, vpd); view3d_set_viewcontext(C, &vpd->vc); - vpd->vp_handle = ED_vpaint_proj_handle_create(vpd->vc.scene, ob, &vpd->vertexcosnos); + vpd->vp_handle = ED_vpaint_proj_handle_create(vpd->vc.scene, ob, &vpd->data); vpd->indexar = get_indexarray(me); vpd->paintcol = vpaint_get_current_col(vp); @@ -2849,9 +2841,8 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f return 1; } -static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me, - const unsigned int index, const float mval[2], - const float brush_size_pressure, const float brush_alpha_pressure) +static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me, const unsigned int index, + const float brush_size_pressure, const float brush_alpha_pressure) { ViewContext *vc = &vpd->vc; Brush *brush = BKE_paint_brush(&vp->paint); @@ -2901,7 +2892,7 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me, float rgba[4]; unsigned int paintcol; alpha = calc_vp_alpha_col_dl(vp, vc, vpd->vpimat, - &vpd->vertexcosnos[ml->v], mval, + vpd->data, ml->v, brush_size_pressure, brush_alpha_pressure, rgba); if (vpd->is_texbrush) { @@ -3005,7 +2996,7 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P for (index = 0; index < totindex; index++) { if (indexar[index] && indexar[index] <= me->totpoly) { - vpaint_paint_poly(vp, vpd, me, indexar[index] - 1, mval, brush_size_pressure, brush_alpha_pressure); + vpaint_paint_poly(vp, vpd, me, indexar[index] - 1, brush_size_pressure, brush_alpha_pressure); } } diff --git a/source/blender/editors/sculpt_paint/paint_vertex_proj.c b/source/blender/editors/sculpt_paint/paint_vertex_proj.c index a04e15d3729..3175a5a4235 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_proj.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_proj.c @@ -52,13 +52,10 @@ /* stored while painting */ struct VertProjHandle { - DMCoNo *vcosnos; + VertProjData *data; bool use_update; - /* use for update */ - float *dists_sq; - Object *ob; Scene *scene; }; @@ -80,7 +77,7 @@ static void vpaint_proj_dm_map_cosnos_init__map_cb(void *userData, int index, co const float no_f[3], const short no_s[3]) { struct VertProjHandle *vp_handle = userData; - DMCoNo *co_no = &vp_handle->vcosnos[index]; + DMCoNo *co_no = &vp_handle->data->vcosnos[index]; /* check if we've been here before (normal should not be 0) */ if (!is_zero_v3(co_no->no)) { @@ -107,11 +104,10 @@ static void vpaint_proj_dm_map_cosnos_init(Scene *scene, Object *ob, dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX); if (dm->foreachMappedVert) { - memset(vp_handle->vcosnos, 0, sizeof(DMCoNo) * me->totvert); dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_init__map_cb, vp_handle, DM_FOREACH_USE_NORMAL); } else { - DMCoNo *v_co_no = vp_handle->vcosnos; + DMCoNo *v_co_no = vp_handle->data->vcosnos; int a; for (a = 0; a < me->totvert; a++, v_co_no++) { dm->getVertCo(dm, a, v_co_no->co); @@ -129,44 +125,41 @@ static void vpaint_proj_dm_map_cosnos_init(Scene *scene, Object *ob, /* Same as init but take mouse location into account */ static void vpaint_proj_dm_map_cosnos_update__map_cb(void *userData, int index, const float co[3], - const float no_f[3], const short no_s[3]) + const float no_f[3], const short no_s[3]) { struct VertProjUpdate *vp_update = userData; - struct VertProjHandle *vp_handle = vp_update->vp_handle; - DMCoNo *co_no = &vp_handle->vcosnos[index]; + VertProjData *data = vp_update->vp_handle->data; + DMCoNo *co_no = &data->vcosnos[index]; - /* find closest vertex */ + /* first find distance to this vertex */ + float co_ss[2]; /* screenspace */ + + if (ED_view3d_project_float_object(vp_update->ar, + co, co_ss, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) { - /* first find distance to this vertex */ - float co_ss[2]; /* screenspace */ - - if (ED_view3d_project_float_object(vp_update->ar, - co, co_ss, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK) - { - const float dist_sq = len_squared_v2v2(vp_update->mval_fl, co_ss); - if (dist_sq > vp_handle->dists_sq[index]) { - /* bail out! */ - return; - } - - vp_handle->dists_sq[index] = dist_sq; + const float dist_sq = len_squared_v2v2(vp_update->mval_fl, co_ss); + if (dist_sq > data->dists_sq[index]) { + /* bail out! */ + return; } - } - /* continue with regular functionality */ - copy_v3_v3(co_no->co, co); - if (no_f) { - copy_v3_v3(co_no->no, no_f); - } - else { - normal_short_to_float_v3(co_no->no, no_s); + data->dists_sq[index] = dist_sq; + copy_v2_v2(data->ss_co[index], co_ss); + + copy_v3_v3(co_no->co, co); + if (no_f) { + copy_v3_v3(co_no->no, no_f); + } + else { + normal_short_to_float_v3(co_no->no, no_s); + } } } static void vpaint_proj_dm_map_cosnos_update(struct VertProjHandle *vp_handle, - ARegion *ar, const float mval_fl[2]) + ARegion *ar, const float mval_fl[2]) { struct VertProjUpdate vp_update = {vp_handle, ar, mval_fl}; @@ -182,7 +175,7 @@ static void vpaint_proj_dm_map_cosnos_update(struct VertProjHandle *vp_handle, /* highly unlikely this will become unavailable once painting starts (perhaps with animated modifiers) */ if (LIKELY(dm->foreachMappedVert)) { - fill_vn_fl(vp_handle->dists_sq, me->totvert, FLT_MAX); + fill_vn_fl(vp_handle->data->dists_sq, me->totvert, FLT_MAX); dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_update__map_cb, &vp_update, DM_FOREACH_USE_NORMAL); } @@ -195,32 +188,36 @@ static void vpaint_proj_dm_map_cosnos_update(struct VertProjHandle *vp_handle, /* Public Functions */ struct VertProjHandle *ED_vpaint_proj_handle_create(Scene *scene, Object *ob, - DMCoNo **r_vcosnos) + VertProjData **r_vcosnos) { struct VertProjHandle *vp_handle = MEM_mallocN(sizeof(struct VertProjHandle), __func__); Mesh *me = ob->data; /* setup the handle */ - vp_handle->vcosnos = MEM_mallocN(sizeof(DMCoNo) * me->totvert, "vertexcosnos map"); + vp_handle->data = MEM_mallocN(sizeof(VertProjData), AT); + + vp_handle->data->vcosnos = MEM_mallocN(sizeof(DMCoNo) * me->totvert, "vertexcosnos map"); vp_handle->use_update = false; /* sets 'use_update' if needed */ vpaint_proj_dm_map_cosnos_init(scene, ob, vp_handle); if (vp_handle->use_update) { - vp_handle->dists_sq = MEM_mallocN(sizeof(float) * me->totvert, __func__); + vp_handle->data->dists_sq = MEM_mallocN(sizeof(float) * me->totvert, AT); + vp_handle->data->ss_co = MEM_mallocN(2 * sizeof(float) * me->totvert, AT); vp_handle->ob = ob; vp_handle->scene = scene; } else { - vp_handle->dists_sq = NULL; + vp_handle->data->dists_sq = NULL; + vp_handle->data->ss_co = NULL; vp_handle->ob = NULL; vp_handle->scene = NULL; } - *r_vcosnos = vp_handle->vcosnos; + *r_vcosnos = vp_handle->data; return vp_handle; } @@ -235,9 +232,11 @@ void ED_vpaint_proj_handle_update(struct VertProjHandle *vp_handle, void ED_vpaint_proj_handle_free(struct VertProjHandle *vp_handle) { if (vp_handle->use_update) { - MEM_freeN(vp_handle->dists_sq); + MEM_freeN(vp_handle->data->dists_sq); + MEM_freeN(vp_handle->data->ss_co); } - MEM_freeN(vp_handle->vcosnos); + MEM_freeN(vp_handle->data->vcosnos); + MEM_freeN(vp_handle->data); MEM_freeN(vp_handle); }