From 974053f7e9443c71250c4c83f1a864c0f11bd473 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 5 Oct 2017 12:32:24 +1100 Subject: Fix brush reset (missing notifier) D2843 by @uvwxyz --- source/blender/editors/sculpt_paint/paint_ops.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source/blender/editors/sculpt_paint') diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 4f6b3d100c5..2899cfeedcf 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -264,9 +264,14 @@ static int brush_reset_exec(bContext *C, wmOperator *UNUSED(op)) if (!ob || !brush) return OPERATOR_CANCELLED; - if (ob->mode & OB_MODE_SCULPT) - BKE_brush_sculpt_reset(brush); /* TODO: other modes */ + if (ob->mode & OB_MODE_SCULPT) { + BKE_brush_sculpt_reset(brush); + } + else { + return OPERATOR_CANCELLED; + } + WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush); return OPERATOR_FINISHED; } -- cgit v1.2.3 From 775c773cf48c0acbcab48ba04e32890830574c4c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 5 Oct 2017 12:57:24 +1100 Subject: Fix sculpt secondary color missing some brushes D2841 by @uvwxyz w/ edits --- source/blender/editors/sculpt_paint/paint_cursor.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'source/blender/editors/sculpt_paint') diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index 53c11e2a6a9..6145c549e9b 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -1043,11 +1043,8 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) /* check if brush is subtracting, use different color then */ /* TODO: no way currently to know state of pen flip or * invert key modifier without starting a stroke */ - if (((ups->draw_inverted == 0) ^ - ((brush->flag & BRUSH_DIR_IN) == 0)) && - ELEM(brush->sculpt_tool, SCULPT_TOOL_DRAW, - SCULPT_TOOL_INFLATE, SCULPT_TOOL_CLAY, - SCULPT_TOOL_PINCH, SCULPT_TOOL_CREASE)) + if (((ups->draw_inverted == 0) ^ ((brush->flag & BRUSH_DIR_IN) == 0)) && + BKE_brush_sculpt_has_secondary_color(brush)) { outline_col = brush->sub_col; } -- cgit v1.2.3 From 82d6a30015a753efd7ed4145e85141a30ebb5f67 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 5 Oct 2017 17:35:46 +1100 Subject: Disable cursor drawing while navigating Was performing ray-casts in sculpt mode on every update. --- source/blender/editors/sculpt_paint/paint_cursor.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source/blender/editors/sculpt_paint') diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index 6145c549e9b..5bc21457d54 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -42,6 +42,7 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_userdef_types.h" +#include "DNA_view3d_types.h" #include "BKE_brush.h" #include "BKE_context.h" @@ -1002,8 +1003,9 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) * mouse over too, not just during a stroke */ view3d_set_viewcontext(C, &vc); - get_imapaint_zoom(C, &zoomx, &zoomy); - zoomx = max_ff(zoomx, zoomy); + if (vc.rv3d->rflag & RV3D_NAVIGATING) { + return; + } /* skip everything and draw brush here */ if (brush->flag & BRUSH_CURVE) { @@ -1011,6 +1013,9 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) return; } + get_imapaint_zoom(C, &zoomx, &zoomy); + zoomx = max_ff(zoomx, zoomy); + /* set various defaults */ translation[0] = x; translation[1] = y; -- cgit v1.2.3 From 21d91de8e79fb143943f2a467dc568a7688b567c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 5 Oct 2017 17:52:05 +1100 Subject: Cleanup: remove unused struct member Merged with soc-2016-pbvh-painting, no longer needed. --- source/blender/editors/sculpt_paint/sculpt.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source/blender/editors/sculpt_paint') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 961fac287c1..3035f4b7979 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1540,7 +1540,6 @@ typedef struct { bool hit; float dist; bool original; - PBVHNode* node; } SculptRaycastData; typedef struct { @@ -4327,9 +4326,6 @@ static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin) { srd->hit = 1; *tmin = srd->dist; - - //for vwpaint testing - srd->node = node; } } } -- cgit v1.2.3 From 0badb6c804c24d5d5f5b78e8711fcb76b7f5ee6b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 5 Oct 2017 21:06:04 +1100 Subject: Cleanup: rename dist -> depth Prepare to add code that stores distance to the ray, avoid confusion. --- source/blender/editors/sculpt_paint/sculpt.c | 60 +++++++++++++++------------- 1 file changed, 33 insertions(+), 27 deletions(-) (limited to 'source/blender/editors/sculpt_paint') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 3035f4b7979..1bff1f460ea 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1538,14 +1538,14 @@ typedef struct { SculptSession *ss; const float *ray_start, *ray_normal; bool hit; - float dist; + float depth; bool original; } SculptRaycastData; typedef struct { const float *ray_start, *ray_normal; bool hit; - float dist; + float depth; float detail; } SculptDetailRaycastData; @@ -4322,10 +4322,10 @@ static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin) } if (BKE_pbvh_node_raycast(srd->ss->pbvh, node, origco, use_origco, - srd->ray_start, srd->ray_normal, &srd->dist)) + srd->ray_start, srd->ray_normal, &srd->depth)) { srd->hit = 1; - *tmin = srd->dist; + *tmin = srd->depth; } } } @@ -4335,10 +4335,10 @@ static void sculpt_raycast_detail_cb(PBVHNode *node, void *data_v, float *tmin) if (BKE_pbvh_node_get_tmin(node) < *tmin) { SculptDetailRaycastData *srd = data_v; if (BKE_pbvh_bmesh_node_raycast_detail(node, srd->ray_start, srd->ray_normal, - &srd->dist, &srd->detail)) + &srd->depth, &srd->detail)) { srd->hit = 1; - *tmin = srd->dist; + *tmin = srd->depth; } } } @@ -4385,8 +4385,7 @@ bool sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]) Object *ob; SculptSession *ss; StrokeCache *cache; - float ray_start[3], ray_end[3], ray_normal[3], dist; - SculptRaycastData srd; + float ray_start[3], ray_end[3], ray_normal[3], depth; bool original; ViewContext vc; @@ -4400,28 +4399,35 @@ bool sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]) sculpt_stroke_modifiers_check(C, ob); - dist = sculpt_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, original); - - srd.original = original; - srd.ss = ob->sculpt; - srd.hit = 0; - srd.ray_start = ray_start; - srd.ray_normal = ray_normal; - srd.dist = dist; + depth = sculpt_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, original); - BKE_pbvh_raycast(ss->pbvh, sculpt_raycast_cb, &srd, - ray_start, ray_normal, srd.original); - - copy_v3_v3(out, ray_normal); - mul_v3_fl(out, srd.dist); - add_v3_v3(out, ray_start); + bool hit = false; + { + SculptRaycastData srd = { + .original = original, + .ss = ob->sculpt, + .hit = 0, + .ray_start = ray_start, + .ray_normal = ray_normal, + .depth = depth, + }; + BKE_pbvh_raycast( + ss->pbvh, sculpt_raycast_cb, &srd, + ray_start, ray_normal, srd.original); + if (srd.hit) { + hit = true; + copy_v3_v3(out, ray_normal); + mul_v3_fl(out, srd.depth); + add_v3_v3(out, ray_start); + } + } //used in vwpaint - if (cache && srd.hit){ + if (cache && hit){ copy_v3_v3(cache->true_location, out); } - return srd.hit; + return hit; } static void sculpt_brush_init_tex(const Scene *scene, Sculpt *sd, SculptSession *ss) @@ -5487,7 +5493,7 @@ static void sample_detail(bContext *C, int ss_co[2]) ViewContext vc; Object *ob; Sculpt *sd; - float ray_start[3], ray_end[3], ray_normal[3], dist; + float ray_start[3], ray_end[3], ray_normal[3], depth; SculptDetailRaycastData srd; float mouse[2] = {ss_co[0], ss_co[1]}; view3d_set_viewcontext(C, &vc); @@ -5497,12 +5503,12 @@ static void sample_detail(bContext *C, int ss_co[2]) sculpt_stroke_modifiers_check(C, ob); - dist = sculpt_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, false); + depth = sculpt_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, false); srd.hit = 0; srd.ray_start = ray_start; srd.ray_normal = ray_normal; - srd.dist = dist; + srd.depth = depth; srd.detail = sd->constant_detail; BKE_pbvh_raycast(ob->sculpt->pbvh, sculpt_raycast_detail_cb, &srd, -- cgit v1.2.3 From 56a07ba70650b1e65f5979eab39730a1db314c56 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 5 Oct 2017 21:16:25 +1100 Subject: Vertex Paint: apply when cursor isn't over faces This behavior makes more sense for sculpt, less so for painting. Restores non PBVH behavior, adding `BKE_pbvh_find_nearest_to_ray` - similar to ray-cast except it finds the closest point on the surface. --- source/blender/editors/sculpt_paint/sculpt.c | 63 ++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'source/blender/editors/sculpt_paint') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 1bff1f460ea..f74ac68262f 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1549,6 +1549,15 @@ typedef struct { float detail; } SculptDetailRaycastData; +typedef struct { + SculptSession *ss; + const float *ray_start, *ray_normal; + bool hit; + float depth; + float dist_sq_to_ray; + bool original; +} SculptFindNearestToRayData; + static void do_smooth_brush_mesh_task_cb_ex( void *userdata, void *UNUSED(userdata_chunk), const int n, const int thread_id) { @@ -4330,6 +4339,36 @@ static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin) } } +static void sculpt_find_nearest_to_ray_cb(PBVHNode *node, void *data_v, float *tmin) +{ + if (BKE_pbvh_node_get_tmin(node) < *tmin) { + SculptFindNearestToRayData *srd = data_v; + float (*origco)[3] = NULL; + bool use_origco = false; + + if (srd->original && srd->ss->cache) { + if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_BMESH) { + use_origco = true; + } + else { + /* intersect with coordinates from before we started stroke */ + SculptUndoNode *unode = sculpt_undo_get_node(node); + origco = (unode) ? unode->co : NULL; + use_origco = origco ? true : false; + } + } + + if (BKE_pbvh_node_find_nearest_to_ray( + srd->ss->pbvh, node, origco, use_origco, + srd->ray_start, srd->ray_normal, + &srd->depth, &srd->dist_sq_to_ray)) + { + srd->hit = 1; + *tmin = srd->dist_sq_to_ray; + } + } +} + static void sculpt_raycast_detail_cb(PBVHNode *node, void *data_v, float *tmin) { if (BKE_pbvh_node_get_tmin(node) < *tmin) { @@ -4422,6 +4461,30 @@ bool sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]) } } + /* We may want to move this into a brush option, it could be useful in sculpt mode too. */ + const bool use_nearest = ((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) != 0); + + if (hit == false && use_nearest) { + SculptFindNearestToRayData srd = { + .original = original, + .ss = ob->sculpt, + .hit = 0, + .ray_start = ray_start, + .ray_normal = ray_normal, + .depth = FLT_MAX, + .dist_sq_to_ray = FLT_MAX, + }; + BKE_pbvh_find_nearest_to_ray( + ss->pbvh, sculpt_find_nearest_to_ray_cb, &srd, + ray_start, ray_normal, srd.original); + if (srd.hit) { + hit = true; + copy_v3_v3(out, ray_normal); + mul_v3_fl(out, srd.depth); + add_v3_v3(out, ray_start); + } + } + //used in vwpaint if (cache && hit){ copy_v3_v3(cache->true_location, out); -- cgit v1.2.3 From d8509b349d1d6219923615e7af81267bb6f06b68 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 6 Oct 2017 00:18:11 +1100 Subject: Sculpt Mode: 2D falloff option This makes brush influence into a tube instead of a sphere. It can be used along the outline of a mesh to adjust it's silhouette. Note that all this takes advantage of changes from vertex paint, from testing this seems useful so exposing from the brush options. --- source/blender/editors/sculpt_paint/paint_vertex.c | 34 +-- source/blender/editors/sculpt_paint/sculpt.c | 337 ++++++++++++--------- .../blender/editors/sculpt_paint/sculpt_intern.h | 9 +- 3 files changed, 219 insertions(+), 161 deletions(-) (limited to 'source/blender/editors/sculpt_paint') diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index a6b41b51ca6..7c54277639a 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -1500,22 +1500,6 @@ static float wpaint_get_active_weight(const MDeformVert *dv, const WeightPaintIn } } -static SculptBrushTestFn sculpt_brush_test_init_with_falloff_shape( - SculptSession *ss, SculptBrushTest *test, char falloff_shape) -{ - sculpt_brush_test_init(ss, test); - SculptBrushTestFn sculpt_brush_test_sq_fn; - if (falloff_shape == VP_FALLOFF_SHAPE_SPHERE) { - sculpt_brush_test_sq_fn = sculpt_brush_test_sphere_sq; - } - else { - /* VP_FALLOFF_SHAPE_TUBE */ - plane_from_point_normal_v3(test->plane, test->location, ss->cache->view_normal); - sculpt_brush_test_sq_fn = sculpt_brush_test_circle_sq; - } - return sculpt_brush_test_sq_fn; -} - static void do_wpaint_brush_blur_task_cb_ex( void *userdata, void *UNUSED(userdata_chunk), const int n, const int UNUSED(thread_id)) { @@ -1536,7 +1520,7 @@ static void do_wpaint_brush_blur_task_cb_ex( SculptBrushTest test; SculptBrushTestFn sculpt_brush_test_sq_fn = - sculpt_brush_test_init_with_falloff_shape(ss, &test, data->vp->falloff_shape); + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); /* For each vertex */ PBVHVertexIter vd; @@ -1629,7 +1613,7 @@ static void do_wpaint_brush_smear_task_cb_ex( SculptBrushTest test; SculptBrushTestFn sculpt_brush_test_sq_fn = - sculpt_brush_test_init_with_falloff_shape(ss, &test, data->vp->falloff_shape); + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); /* For each vertex */ PBVHVertexIter vd; @@ -1729,7 +1713,7 @@ static void do_wpaint_brush_draw_task_cb_ex( SculptBrushTest test; SculptBrushTestFn sculpt_brush_test_sq_fn = - sculpt_brush_test_init_with_falloff_shape(ss, &test, data->vp->falloff_shape); + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); /* For each vertex */ PBVHVertexIter vd; @@ -1794,7 +1778,7 @@ static void do_wpaint_brush_calc_average_weight_cb_ex( SculptBrushTest test; SculptBrushTestFn sculpt_brush_test_sq_fn = - sculpt_brush_test_init_with_falloff_shape(ss, &test, data->vp->falloff_shape); + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); /* For each vertex */ PBVHVertexIter vd; @@ -1896,7 +1880,7 @@ static PBVHNode **vwpaint_pbvh_gather_generic( PBVHNode **nodes = NULL; /* Build a list of all nodes that are potentially within the brush's area of influence */ - if (wp->falloff_shape == VP_FALLOFF_SHAPE_SPHERE) { + if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { SculptSearchSphereData data = { .ss = ss, .sd = sd, @@ -2455,7 +2439,7 @@ static void do_vpaint_brush_calc_average_color_cb_ex( SculptBrushTest test; SculptBrushTestFn sculpt_brush_test_sq_fn = - sculpt_brush_test_init_with_falloff_shape(ss, &test, data->vp->falloff_shape); + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); /* For each vertex */ PBVHVertexIter vd; @@ -2524,7 +2508,7 @@ static void do_vpaint_brush_draw_task_cb_ex( SculptBrushTest test; SculptBrushTestFn sculpt_brush_test_sq_fn = - sculpt_brush_test_init_with_falloff_shape(ss, &test, data->vp->falloff_shape); + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); /* For each vertex */ PBVHVertexIter vd; @@ -2613,7 +2597,7 @@ static void do_vpaint_brush_blur_task_cb_ex( SculptBrushTest test; SculptBrushTestFn sculpt_brush_test_sq_fn = - sculpt_brush_test_init_with_falloff_shape(ss, &test, data->vp->falloff_shape); + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); /* For each vertex */ PBVHVertexIter vd; @@ -2726,7 +2710,7 @@ static void do_vpaint_brush_smear_task_cb_ex( SculptBrushTest test; SculptBrushTestFn sculpt_brush_test_sq_fn = - sculpt_brush_test_init_with_falloff_shape(ss, &test, data->vp->falloff_shape); + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); /* For each vertex */ PBVHVertexIter vd; diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index f74ac68262f..487ab32c5a6 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -524,7 +524,8 @@ void sculpt_brush_test_init(SculptSession *ss, SculptBrushTest *test) test->dist = 0.0f; /* just for initialize */ /* Only for 2D projection. */ - zero_v4(test->plane); + zero_v4(test->plane_view); + zero_v4(test->plane_tool); test->mirror_symmetry_pass = ss->cache->mirror_symmetry_pass; @@ -590,7 +591,7 @@ bool sculpt_brush_test_sphere_fast(const SculptBrushTest *test, const float co[3 bool sculpt_brush_test_circle_sq(SculptBrushTest *test, const float co[3]) { float co_proj[3]; - closest_to_plane_normalized_v3(co_proj, test->plane, co); + closest_to_plane_normalized_v3(co_proj, test->plane_view, co); float distsq = len_squared_v3v3(co_proj, test->location); if (distsq <= test->radius_squared) { @@ -634,6 +635,22 @@ bool sculpt_brush_test_cube(SculptBrushTest *test, const float co[3], float loca } } +SculptBrushTestFn sculpt_brush_test_init_with_falloff_shape( + SculptSession *ss, SculptBrushTest *test, char falloff_shape) +{ + sculpt_brush_test_init(ss, test); + SculptBrushTestFn sculpt_brush_test_sq_fn; + if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { + sculpt_brush_test_sq_fn = sculpt_brush_test_sphere_sq; + } + else { + /* PAINT_FALLOFF_SHAPE_TUBE */ + plane_from_point_normal_v3(test->plane_view, test->location, ss->cache->view_normal); + sculpt_brush_test_sq_fn = sculpt_brush_test_circle_sq; + } + return sculpt_brush_test_sq_fn; +} + static float frontface(const Brush *br, const float sculpt_normal[3], const short no[3], const float fno[3]) { @@ -1249,7 +1266,7 @@ bool sculpt_search_circle_cb(PBVHNode *node, void *data_v) const float dist_sq = dist_squared_ray_to_aabb( data->dist_ray_to_aabb_precalc, bb_min, bb_max, dummy_co, &dummy_depth); - return dist_sq < data->radius_squared; + return dist_sq < data->radius_squared || 1; } /* Handles clipping against a mirror modifier and SCULPT_LOCK axis flags */ @@ -1268,6 +1285,37 @@ static void sculpt_clip(Sculpt *sd, SculptSession *ss, float co[3], const float } } +static PBVHNode **sculpt_pbvh_gather_generic( + Object *ob, Sculpt *sd, const Brush *brush, bool use_original, float radius_scale, int *r_totnode) +{ + SculptSession *ss = ob->sculpt; + PBVHNode **nodes = NULL; + + /* Build a list of all nodes that are potentially within the brush's area of influence */ + if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { + SculptSearchSphereData data = { + .ss = ss, + .sd = sd, + .radius_squared = SQUARE(ss->cache->radius * radius_scale), + .original = use_original, + }; + BKE_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, r_totnode); + } + else { + struct DistRayAABB_Precalc dist_ray_to_aabb_precalc; + dist_squared_ray_to_aabb_precalc(&dist_ray_to_aabb_precalc, ss->cache->location, ss->cache->view_normal); + SculptSearchCircleData data = { + .ss = ss, + .sd = sd, + .radius_squared = SQUARE(ss->cache->radius * radius_scale), + .original = use_original, + .dist_ray_to_aabb_precalc = &dist_ray_to_aabb_precalc, + }; + BKE_pbvh_search_gather(ss->pbvh, sculpt_search_circle_cb, &data, &nodes, r_totnode); + } + return nodes; +} + /* Calculate primary direction of movement for many brushes */ static void calc_sculpt_normal( Sculpt *sd, Object *ob, @@ -1569,19 +1617,19 @@ static void do_smooth_brush_mesh_task_cb_ex( float bstrength = data->strength; PBVHVertexIter vd; - SculptBrushTest test; CLAMP(bstrength, 0.0f, 1.0f); - sculpt_brush_test_init(ss, &test); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (sculpt_brush_test_sphere(&test, vd.co)) { + if (sculpt_brush_test_sq_fn(&test, vd.co)) { const float fade = bstrength * tex_strength( - ss, brush, vd.co, test.dist, vd.no, vd.fno, - smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f), - thread_id); + ss, brush, vd.co, sqrtf(test.dist), + vd.no, vd.fno, smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f), thread_id); if (smooth_mask) { float val = neighbor_average_mask(ss, vd.vert_indices[vd.i]) - *vd.mask; val *= fade * bstrength; @@ -1617,18 +1665,19 @@ static void do_smooth_brush_bmesh_task_cb_ex( float bstrength = data->strength; PBVHVertexIter vd; - SculptBrushTest test; CLAMP(bstrength, 0.0f, 1.0f); - sculpt_brush_test_init(ss, &test); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (sculpt_brush_test_sphere(&test, vd.co)) { + if (sculpt_brush_test_sq_fn(&test, vd.co)) { const float fade = bstrength * tex_strength( - ss, brush, vd.co, test.dist, vd.no, vd.fno, smooth_mask ? 0.0f : *vd.mask, - thread_id); + ss, brush, vd.co, sqrtf(test.dist), + vd.no, vd.fno, smooth_mask ? 0.0f : *vd.mask, thread_id); if (smooth_mask) { float val = bmesh_neighbor_average_mask(vd.bm_vert, vd.cd_vert_mask_offset) - *vd.mask; val *= fade * bstrength; @@ -1664,7 +1713,6 @@ static void do_smooth_brush_multires_task_cb_ex( const bool smooth_mask = data->smooth_mask; float bstrength = data->strength; - SculptBrushTest test; CCGElem **griddata, *gddata; CCGKey key; @@ -1677,7 +1725,9 @@ static void do_smooth_brush_multires_task_cb_ex( int *grid_indices, totgrid, gridsize; int i, x, y; - sculpt_brush_test_init(ss, &test); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); CLAMP(bstrength, 0.0f, 1.0f); @@ -1764,10 +1814,11 @@ static void do_smooth_brush_multires_task_cb_ex( fno = CCG_elem_offset_no(&key, gddata, index); mask = CCG_elem_offset_mask(&key, gddata, index); - if (sculpt_brush_test_sphere(&test, co)) { + if (sculpt_brush_test_sq_fn(&test, co)) { const float strength_mask = (smooth_mask ? 0.0f : *mask); const float fade = bstrength * tex_strength( - ss, brush, co, test.dist, NULL, fno, strength_mask, thread_id); + ss, brush, co, sqrtf(test.dist), + NULL, fno, strength_mask, thread_id); float f = 1.0f / 16.0f; if (x == 0 || x == gridsize - 1) @@ -1878,14 +1929,17 @@ static void do_mask_brush_draw_task_cb_ex( const float bstrength = ss->cache->bstrength; PBVHVertexIter vd; - SculptBrushTest test; - sculpt_brush_test_init(ss, &test); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (sculpt_brush_test_sphere(&test, vd.co)) { - const float fade = tex_strength(ss, brush, vd.co, test.dist, vd.no, vd.fno, 0.0f, thread_id); + if (sculpt_brush_test_sq_fn(&test, vd.co)) { + const float fade = tex_strength( + ss, brush, vd.co, sqrtf(test.dist), + vd.no, vd.fno, 0.0f, thread_id); (*vd.mask) += fade * bstrength; CLAMP(*vd.mask, 0, 1); @@ -1935,19 +1989,21 @@ static void do_draw_brush_task_cb_ex( const float *offset = data->offset; PBVHVertexIter vd; - SculptBrushTest test; float (*proxy)[3]; proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; - sculpt_brush_test_init(ss, &test); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (sculpt_brush_test_sphere(&test, vd.co)) { + if (sculpt_brush_test_sq_fn(&test, vd.co)) { /* offset vertex */ const float fade = tex_strength( - ss, brush, vd.co, test.dist, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); + ss, brush, vd.co, sqrtf(test.dist), + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); mul_v3_v3fl(proxy[vd.i], offset, fade); @@ -1992,19 +2048,21 @@ static void do_crease_brush_task_cb_ex( const float *offset = data->offset; PBVHVertexIter vd; - SculptBrushTest test; float (*proxy)[3]; proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; - sculpt_brush_test_init(ss, &test); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (sculpt_brush_test_sphere(&test, vd.co)) { + if (sculpt_brush_test_sq_fn(&test, vd.co)) { /* offset vertex */ const float fade = tex_strength( - ss, brush, vd.co, test.dist, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); + ss, brush, vd.co, sqrtf(test.dist), + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); float val1[3]; float val2[3]; @@ -2077,19 +2135,21 @@ static void do_pinch_brush_task_cb_ex( const Brush *brush = data->brush; PBVHVertexIter vd; - SculptBrushTest test; float (*proxy)[3]; const float bstrength = ss->cache->bstrength; proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; - sculpt_brush_test_init(ss, &test); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (sculpt_brush_test_sphere(&test, vd.co)) { + if (sculpt_brush_test_sq_fn(&test, vd.co)) { const float fade = bstrength * tex_strength( - ss, brush, vd.co, test.dist, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); + ss, brush, vd.co, sqrtf(test.dist), + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); float val[3]; sub_v3_v3v3(val, test.location, vd.co); @@ -2124,7 +2184,6 @@ static void do_grab_brush_task_cb_ex( const float *grab_delta = data->grab_delta; PBVHVertexIter vd; - SculptBrushTest test; SculptOrigVertData orig_data; float (*proxy)[3]; const float bstrength = ss->cache->bstrength; @@ -2133,16 +2192,18 @@ static void do_grab_brush_task_cb_ex( proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; - sculpt_brush_test_init(ss, &test); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { sculpt_orig_vert_data_update(&orig_data, &vd); - if (sculpt_brush_test_sphere(&test, orig_data.co)) { + if (sculpt_brush_test_sq_fn(&test, orig_data.co)) { const float fade = bstrength * tex_strength( - ss, brush, orig_data.co, test.dist, orig_data.no, NULL, vd.mask ? *vd.mask : 0.0f, - thread_id); + ss, brush, orig_data.co, sqrtf(test.dist), + orig_data.no, NULL, vd.mask ? *vd.mask : 0.0f, thread_id); mul_v3_v3fl(proxy[vd.i], grab_delta, fade); @@ -2184,19 +2245,21 @@ static void do_nudge_brush_task_cb_ex( const float *cono = data->cono; PBVHVertexIter vd; - SculptBrushTest test; float (*proxy)[3]; const float bstrength = ss->cache->bstrength; proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; - sculpt_brush_test_init(ss, &test); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (sculpt_brush_test_sphere(&test, vd.co)) { + if (sculpt_brush_test_sq_fn(&test, vd.co)) { const float fade = bstrength * tex_strength( - ss, brush, vd.co, test.dist, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); + ss, brush, vd.co, sqrtf(test.dist), + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); mul_v3_v3fl(proxy[vd.i], cono, fade); @@ -2239,7 +2302,6 @@ static void do_snake_hook_brush_task_cb_ex( const float *grab_delta = data->grab_delta; PBVHVertexIter vd; - SculptBrushTest test; float (*proxy)[3]; const float bstrength = ss->cache->bstrength; const bool do_rake_rotation = ss->cache->is_rake_rotation_valid; @@ -2249,13 +2311,16 @@ static void do_snake_hook_brush_task_cb_ex( proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; - sculpt_brush_test_init(ss, &test); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (sculpt_brush_test_sphere(&test, vd.co)) { + if (sculpt_brush_test_sq_fn(&test, vd.co)) { const float fade = bstrength * tex_strength( - ss, brush, vd.co, test.dist, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); + ss, brush, vd.co, sqrtf(test.dist), + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); mul_v3_v3fl(proxy[vd.i], grab_delta, fade); @@ -2339,7 +2404,6 @@ static void do_thumb_brush_task_cb_ex( const float *cono = data->cono; PBVHVertexIter vd; - SculptBrushTest test; SculptOrigVertData orig_data; float (*proxy)[3]; const float bstrength = ss->cache->bstrength; @@ -2348,16 +2412,18 @@ static void do_thumb_brush_task_cb_ex( proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; - sculpt_brush_test_init(ss, &test); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { sculpt_orig_vert_data_update(&orig_data, &vd); - if (sculpt_brush_test_sphere(&test, orig_data.co)) { + if (sculpt_brush_test_sq_fn(&test, orig_data.co)) { const float fade = bstrength * tex_strength( - ss, brush, orig_data.co, test.dist, orig_data.no, NULL, vd.mask ? *vd.mask : 0.0f, - thread_id); + ss, brush, orig_data.co, sqrtf(test.dist), + orig_data.no, NULL, vd.mask ? *vd.mask : 0.0f, thread_id); mul_v3_v3fl(proxy[vd.i], cono, fade); @@ -2399,7 +2465,6 @@ static void do_rotate_brush_task_cb_ex( const float angle = data->angle; PBVHVertexIter vd; - SculptBrushTest test; SculptOrigVertData orig_data; float (*proxy)[3]; const float bstrength = ss->cache->bstrength; @@ -2408,17 +2473,19 @@ static void do_rotate_brush_task_cb_ex( proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; - sculpt_brush_test_init(ss, &test); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { sculpt_orig_vert_data_update(&orig_data, &vd); - if (sculpt_brush_test_sphere(&test, orig_data.co)) { + if (sculpt_brush_test_sq_fn(&test, orig_data.co)) { float vec[3], rot[3][3]; const float fade = bstrength * tex_strength( - ss, brush, orig_data.co, test.dist, orig_data.no, NULL, vd.mask ? *vd.mask : 0.0f, - thread_id); + ss, brush, orig_data.co, sqrtf(test.dist), + orig_data.no, NULL, vd.mask ? *vd.mask : 0.0f, thread_id); sub_v3_v3v3(vec, orig_data.co, ss->cache->location); axis_angle_normalized_to_mat3(rot, ss->cache->sculpt_normal_symm, angle * fade); @@ -2461,7 +2528,6 @@ static void do_layer_brush_task_cb_ex( const float *offset = data->offset; PBVHVertexIter vd; - SculptBrushTest test; SculptOrigVertData orig_data; float *layer_disp; const float bstrength = ss->cache->bstrength; @@ -2476,15 +2542,18 @@ static void do_layer_brush_task_cb_ex( layer_disp = BKE_pbvh_node_layer_disp_get(ss->pbvh, data->nodes[n]); BLI_mutex_unlock(&data->mutex); - sculpt_brush_test_init(ss, &test); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { sculpt_orig_vert_data_update(&orig_data, &vd); - if (sculpt_brush_test_sphere(&test, orig_data.co)) { + if (sculpt_brush_test_sq_fn(&test, orig_data.co)) { const float fade = bstrength * tex_strength( - ss, brush, vd.co, test.dist, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); + ss, brush, vd.co, sqrtf(test.dist), + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); float *disp = &layer_disp[vd.i]; float val[3]; @@ -2544,19 +2613,21 @@ static void do_inflate_brush_task_cb_ex( const Brush *brush = data->brush; PBVHVertexIter vd; - SculptBrushTest test; float (*proxy)[3]; const float bstrength = ss->cache->bstrength; proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; - sculpt_brush_test_init(ss, &test); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (sculpt_brush_test_sphere(&test, vd.co)) { + if (sculpt_brush_test_sq_fn(&test, vd.co)) { const float fade = bstrength * tex_strength( - ss, brush, vd.co, test.dist, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); + ss, brush, vd.co, sqrtf(test.dist), + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); float val[3]; if (vd.fno) @@ -2704,29 +2775,31 @@ static void do_flatten_brush_task_cb_ex( const float *area_co = data->area_co; PBVHVertexIter vd; - SculptBrushTest test; float (*proxy)[3]; const float bstrength = ss->cache->bstrength; proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; - sculpt_brush_test_init(ss, &test); - plane_from_point_normal_v3(test.plane, area_co, area_no); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); + + plane_from_point_normal_v3(test.plane_tool, area_co, area_no); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (sculpt_brush_test_sphere_sq(&test, vd.co)) { + if (sculpt_brush_test_sq_fn(&test, vd.co)) { float intr[3]; float val[3]; - closest_to_plane_normalized_v3(intr, test.plane, vd.co); + closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co); sub_v3_v3v3(val, intr, vd.co); if (plane_trim(ss->cache, brush, val)) { const float fade = bstrength * tex_strength( - ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - thread_id); + ss, brush, vd.co, sqrtf(test.dist), + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -2780,24 +2853,26 @@ static void do_clay_brush_task_cb_ex( const float *area_co = data->area_co; PBVHVertexIter vd; - SculptBrushTest test; float (*proxy)[3]; const bool flip = (ss->cache->bstrength < 0); const float bstrength = flip ? -ss->cache->bstrength : ss->cache->bstrength; proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; - sculpt_brush_test_init(ss, &test); - plane_from_point_normal_v3(test.plane, area_co, area_no); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); + + plane_from_point_normal_v3(test.plane_tool, area_co, area_no); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (sculpt_brush_test_sphere_sq(&test, vd.co)) { - if (plane_point_side_flip(vd.co, test.plane, flip)) { + if (sculpt_brush_test_sq_fn(&test, vd.co)) { + if (plane_point_side_flip(vd.co, test.plane_tool, flip)) { float intr[3]; float val[3]; - closest_to_plane_normalized_v3(intr, test.plane, vd.co); + closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co); sub_v3_v3v3(val, intr, vd.co); @@ -2805,8 +2880,8 @@ static void do_clay_brush_task_cb_ex( /* note, the normal from the vertices is ignored, * causes glitch with planes, see: T44390 */ const float fade = bstrength * tex_strength( - ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - thread_id); + ss, brush, vd.co, sqrtf(test.dist), + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -2873,16 +2948,16 @@ static void do_clay_strips_brush_task_cb_ex( proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; sculpt_brush_test_init(ss, &test); - plane_from_point_normal_v3(test.plane, area_co, area_no_sp); + plane_from_point_normal_v3(test.plane_tool, area_co, area_no_sp); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { if (sculpt_brush_test_cube(&test, vd.co, mat)) { - if (plane_point_side_flip(vd.co, test.plane, flip)) { + if (plane_point_side_flip(vd.co, test.plane_tool, flip)) { float intr[3]; float val[3]; - closest_to_plane_normalized_v3(intr, test.plane, vd.co); + closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co); sub_v3_v3v3(val, intr, vd.co); @@ -2890,8 +2965,8 @@ static void do_clay_strips_brush_task_cb_ex( /* note, the normal from the vertices is ignored, * causes glitch with planes, see: T44390 */ const float fade = bstrength * tex_strength( - ss, brush, vd.co, ss->cache->radius * test.dist, - vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); + ss, brush, vd.co, ss->cache->radius * test.dist, + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -2974,30 +3049,32 @@ static void do_fill_brush_task_cb_ex( const float *area_co = data->area_co; PBVHVertexIter vd; - SculptBrushTest test; float (*proxy)[3]; const float bstrength = ss->cache->bstrength; proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; - sculpt_brush_test_init(ss, &test); - plane_from_point_normal_v3(test.plane, area_co, area_no); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); + + plane_from_point_normal_v3(test.plane_tool, area_co, area_no); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (sculpt_brush_test_sphere_sq(&test, vd.co)) { - if (plane_point_side(vd.co, test.plane)) { + if (sculpt_brush_test_sq_fn(&test, vd.co)) { + if (plane_point_side(vd.co, test.plane_tool)) { float intr[3]; float val[3]; - closest_to_plane_normalized_v3(intr, test.plane, vd.co); + closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co); sub_v3_v3v3(val, intr, vd.co); if (plane_trim(ss->cache, brush, val)) { const float fade = bstrength * tex_strength( - ss, brush, vd.co, sqrtf(test.dist), - vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); + ss, brush, vd.co, sqrtf(test.dist), + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -3053,30 +3130,31 @@ static void do_scrape_brush_task_cb_ex( const float *area_co = data->area_co; PBVHVertexIter vd; - SculptBrushTest test; float (*proxy)[3]; const float bstrength = ss->cache->bstrength; proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; - sculpt_brush_test_init(ss, &test); - plane_from_point_normal_v3(test.plane, area_co, area_no); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); + plane_from_point_normal_v3(test.plane_tool, area_co, area_no); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (sculpt_brush_test_sphere_sq(&test, vd.co)) { - if (!plane_point_side(vd.co, test.plane)) { + if (sculpt_brush_test_sq_fn(&test, vd.co)) { + if (!plane_point_side(vd.co, test.plane_tool)) { float intr[3]; float val[3]; - closest_to_plane_normalized_v3(intr, test.plane, vd.co); + closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co); sub_v3_v3v3(val, intr, vd.co); if (plane_trim(ss->cache, brush, val)) { const float fade = bstrength * tex_strength( - ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - thread_id); + ss, brush, vd.co, sqrtf(test.dist), + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -3131,18 +3209,19 @@ static void do_gravity_task_cb_ex( float *offset = data->offset; PBVHVertexIter vd; - SculptBrushTest test; float (*proxy)[3]; proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; - sculpt_brush_test_init(ss, &test); + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (sculpt_brush_test_sphere_sq(&test, vd.co)) { + if (sculpt_brush_test_sq_fn(&test, vd.co)) { const float fade = tex_strength( - ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - thread_id); + ss, brush, vd.co, sqrtf(test.dist), + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); mul_v3_v3fl(proxy[vd.i], offset, fade); @@ -3226,22 +3305,12 @@ void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]) static void sculpt_topology_update(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings *UNUSED(ups)) { SculptSession *ss = ob->sculpt; - SculptSearchSphereData data; - PBVHNode **nodes = NULL; - float radius; - int n, totnode; - - /* Build a list of all nodes that are potentially within the - * brush's area of influence */ - data.ss = ss; - data.sd = sd; - - radius = ss->cache->radius * 1.25f; - - data.radius_squared = radius * radius; - data.original = sculpt_tool_needs_original(brush->sculpt_tool) ? true : ss->cache->original; - BKE_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode); + 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); /* Only act if some verts are inside the brush area */ if (totnode) { @@ -3273,8 +3342,10 @@ static void sculpt_topology_update(Sculpt *sd, Object *ob, Brush *brush, Unified BKE_pbvh_bmesh_update_topology( ss->pbvh, mode, ss->cache->location, - (brush->flag & BRUSH_FRONTFACE) ? ss->cache->view_normal : NULL, - ss->cache->radius); + ss->cache->view_normal, + ss->cache->radius, + (brush->flag & BRUSH_FRONTFACE) != 0, + (brush->falloff_shape != PAINT_FALLOFF_SHAPE_SPHERE)); } MEM_freeN(nodes); @@ -3297,16 +3368,12 @@ static void do_brush_action_task_cb(void *userdata, const int n) static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings *ups) { SculptSession *ss = ob->sculpt; - SculptSearchSphereData data; - PBVHNode **nodes = NULL; int totnode; /* Build a list of all nodes that are potentially within the brush's area of influence */ - data.ss = ss; - data.sd = sd; - data.radius_squared = ss->cache->radius_squared; - data.original = sculpt_tool_needs_original(brush->sculpt_tool) ? true : ss->cache->original; - BKE_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode); + const bool use_original = sculpt_tool_needs_original(brush->sculpt_tool) ? true : ss->cache->original; + const float radius_scale = 1.0f; + PBVHNode **nodes = sculpt_pbvh_gather_generic(ob, sd, brush, use_original, radius_scale, &totnode); /* Only act if some verts are inside the brush area */ if (totnode) { @@ -4461,10 +4528,9 @@ bool sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]) } } - /* We may want to move this into a brush option, it could be useful in sculpt mode too. */ - const bool use_nearest = ((ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) != 0); - - if (hit == false && use_nearest) { + if (hit == false) { + const Brush *brush = BKE_paint_brush(BKE_paint_get_active_from_context(C)); + if (ELEM(brush->falloff_shape, PAINT_FALLOFF_SHAPE_TUBE)) { SculptFindNearestToRayData srd = { .original = original, .ss = ob->sculpt, @@ -4483,6 +4549,7 @@ bool sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]) mul_v3_fl(out, srd.depth); add_v3_v3(out, ray_start); } + } } //used in vwpaint @@ -5520,7 +5587,7 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op)) while (BKE_pbvh_bmesh_update_topology( ss->pbvh, PBVH_Collapse | PBVH_Subdivide, - center, NULL, size)) + center, NULL, size, false, false)) { for (i = 0; i < totnodes; i++) BKE_pbvh_node_mark_topology_update(nodes[i]); diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index b9b662f4157..73581d402cf 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -182,7 +182,10 @@ typedef struct SculptBrushTest { int mirror_symmetry_pass; /* For circle (not sphere) projection. */ - float plane[4]; + float plane_view[4]; + + /* Some tool code uses a plane for it's calculateions. */ + float plane_tool[4]; /* View3d clipping - only set rv3d for clipping */ struct RegionView3D *clip_rv3d; @@ -213,6 +216,10 @@ bool sculpt_brush_test_cube(SculptBrushTest *test, const float co[3], float loca bool sculpt_brush_test_circle_sq(SculptBrushTest *test, const float co[3]); bool sculpt_search_sphere_cb(PBVHNode *node, void *data_v); bool sculpt_search_circle_cb(PBVHNode *node, void *data_v); + +SculptBrushTestFn sculpt_brush_test_init_with_falloff_shape( + SculptSession *ss, SculptBrushTest *test, char falloff_shape); + float tex_strength( struct SculptSession *ss, const struct Brush *br, const float point[3], -- cgit v1.2.3 From c454d816a936e509aa3daaa27bd92037cfe6de0e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 6 Oct 2017 16:56:41 +1100 Subject: Cleanup: style --- .../sculpt_paint/paint_vertex_color_utils.c | 2 +- source/blender/editors/sculpt_paint/sculpt.c | 39 +++++++++++----------- 2 files changed, 20 insertions(+), 21 deletions(-) (limited to 'source/blender/editors/sculpt_paint') diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c b/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c index 096bebba0e4..398512287c4 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c @@ -297,7 +297,7 @@ BLI_INLINE uint mcol_colordodge(uint col1, uint col2, int fac) cp[0] = (mfac * cp1[0] + temp * fac) / 255; temp = (cp2[1] == 255) ? 255 : min_ii((cp1[1] * 225) / (255 - cp2[1]), 255); cp[1] = (mfac * cp1[1] + temp * fac) / 255; - temp = (cp2[2] == 255) ? 255 : min_ii((cp1[2] * 225 )/ (255 - cp2[2]), 255); + temp = (cp2[2] == 255) ? 255 : min_ii((cp1[2] * 225) / (255 - cp2[2]), 255); cp[2] = (mfac * cp1[2] + temp * fac) / 255; temp = (cp2[3] == 255) ? 255 : min_ii((cp1[3] * 225) / (255 - cp2[3]), 255); cp[3] = (mfac * cp1[3] + temp * fac) / 255; diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 487ab32c5a6..64eff7186d9 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -4531,29 +4531,28 @@ bool sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]) if (hit == false) { const Brush *brush = BKE_paint_brush(BKE_paint_get_active_from_context(C)); if (ELEM(brush->falloff_shape, PAINT_FALLOFF_SHAPE_TUBE)) { - SculptFindNearestToRayData srd = { - .original = original, - .ss = ob->sculpt, - .hit = 0, - .ray_start = ray_start, - .ray_normal = ray_normal, - .depth = FLT_MAX, - .dist_sq_to_ray = FLT_MAX, - }; - BKE_pbvh_find_nearest_to_ray( - ss->pbvh, sculpt_find_nearest_to_ray_cb, &srd, - ray_start, ray_normal, srd.original); - if (srd.hit) { - hit = true; - copy_v3_v3(out, ray_normal); - mul_v3_fl(out, srd.depth); - add_v3_v3(out, ray_start); - } + SculptFindNearestToRayData srd = { + .original = original, + .ss = ob->sculpt, + .hit = 0, + .ray_start = ray_start, + .ray_normal = ray_normal, + .depth = FLT_MAX, + .dist_sq_to_ray = FLT_MAX, + }; + BKE_pbvh_find_nearest_to_ray( + ss->pbvh, sculpt_find_nearest_to_ray_cb, &srd, + ray_start, ray_normal, srd.original); + if (srd.hit) { + hit = true; + copy_v3_v3(out, ray_normal); + mul_v3_fl(out, srd.depth); + add_v3_v3(out, ray_start); + } } } - //used in vwpaint - if (cache && hit){ + if (cache && hit) { copy_v3_v3(cache->true_location, out); } -- cgit v1.2.3 From 3282218983762197f8c4dfe478d357f6cfa20e4a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 6 Oct 2017 17:38:56 +1100 Subject: Sculpt: clamp normal to plane w/ projected falloff Allows for editing outlines w/o pushing geometry towards/away from the view. --- source/blender/editors/sculpt_paint/sculpt.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source/blender/editors/sculpt_paint') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 64eff7186d9..202acd32579 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1362,6 +1362,10 @@ static void update_sculpt_normal(Sculpt *sd, Object *ob, (cache->first_time || !(brush->flag & BRUSH_ORIGINAL_NORMAL))) { calc_sculpt_normal(sd, ob, nodes, totnode, 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); + } copy_v3_v3(cache->sculpt_normal_symm, cache->sculpt_normal); } else { @@ -2690,6 +2694,10 @@ static void calc_sculpt_plane( case SCULPT_DISP_DIR_AREA: calc_area_normal_and_center(sd, ob, nodes, totnode, 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); + } break; default: -- cgit v1.2.3 From 082987ec74c3fd8e6a4acba098882041694b86c2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 6 Oct 2017 18:29:54 +1100 Subject: Sculpt: use tube falloff when calculating normals Also apply 2D clamping for other tools when the option is set. --- source/blender/editors/sculpt_paint/sculpt.c | 32 ++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'source/blender/editors/sculpt_paint') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 202acd32579..5f38eaa4de2 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -789,7 +789,6 @@ static void calc_area_normal_and_center_task_cb(void *userdata, const int n) float (*area_cos)[3] = data->area_cos; PBVHVertexIter vd; - SculptBrushTest test; SculptUndoNode *unode = NULL; float private_co[2][3] = {{0.0f}}; @@ -801,7 +800,10 @@ static void calc_area_normal_and_center_task_cb(void *userdata, const int n) 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); + + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = + sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); /* when the mesh is edited we can't rely on original coords @@ -824,7 +826,7 @@ static void calc_area_normal_and_center_task_cb(void *userdata, const int n) closest_on_tri_to_point_v3(co, test.location, UNPACK3(co_tri)); - if (sculpt_brush_test_sphere_fast(&test, co)) { + if (sculpt_brush_test_sq_fn(&test, co)) { float no[3]; int flip_index; @@ -858,7 +860,7 @@ static void calc_area_normal_and_center_task_cb(void *userdata, const int n) co = vd.co; } - if (sculpt_brush_test_sphere_fast(&test, co)) { + if (sculpt_brush_test_sq_fn(&test, co)) { float no_buf[3]; const float *no; int flip_index; @@ -976,7 +978,7 @@ void sculpt_pbvh_calc_area_normal( /* Intentionally set 'sd' to NULL since this is used for vertex paint too. */ SculptThreadedTaskData data = { - .sd = NULL, .ob = ob, .nodes = nodes, .totnode = totnode, + .sd = NULL, .ob = ob, .brush = brush, .nodes = nodes, .totnode = totnode, .has_bm_orco = has_bm_orco, .area_cos = NULL, .area_nos = area_nos, .count = count, }; BLI_mutex_init(&data.mutex); @@ -1016,7 +1018,7 @@ static void calc_area_normal_and_center( /* Intentionally set 'sd' to NULL since this is used for vertex paint too. */ SculptThreadedTaskData data = { - .sd = NULL, .ob = ob, .nodes = nodes, .totnode = totnode, + .sd = NULL, .ob = ob, .brush = brush, .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); @@ -2041,6 +2043,9 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT), false); } +/** + * Used for 'SCULPT_TOOL_CREASE' and 'SCULPT_TOOL_BLOB' + */ static void do_crease_brush_task_cb_ex( void *userdata, void *UNUSED(userdata_chunk), const int n, const int thread_id) { @@ -2072,6 +2077,10 @@ static void do_crease_brush_task_cb_ex( /* first we pinch */ sub_v3_v3v3(val1, test.location, vd.co); + if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) { + project_plane_v3_v3v3(val1, val1, ss->cache->view_normal); + } + mul_v3_fl(val1, fade * flippedbstrength); sculpt_project_v3(spvc, val1, val1); @@ -2157,6 +2166,9 @@ static void do_pinch_brush_task_cb_ex( float val[3]; sub_v3_v3v3(val, test.location, vd.co); + if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) { + project_plane_v3_v3v3(val, val, ss->cache->view_normal); + } mul_v3_v3fl(proxy[vd.i], val, fade); if (vd.mvert) @@ -2333,6 +2345,9 @@ static void do_snake_hook_brush_task_cb_ex( float delta_pinch_init[3], delta_pinch[3]; sub_v3_v3v3(delta_pinch, vd.co, test.location); + if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) { + project_plane_v3_v3v3(delta_pinch, delta_pinch, ss->cache->true_view_normal); + } /* important to calculate based on the grabbed location (intentionally ignore fade here). */ add_v3_v3(delta_pinch, grab_delta); @@ -4199,7 +4214,6 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location); } - invert_m4_m4(imat, ob->obmat); mul_mat3_m4_v3(imat, cache->grab_delta); break; @@ -4209,6 +4223,10 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru zero_v3(cache->grab_delta); } + if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) { + project_plane_v3_v3v3(cache->grab_delta, cache->grab_delta, ss->cache->true_view_normal); + } + copy_v3_v3(cache->old_grab_location, grab_location); if (tool == SCULPT_TOOL_GRAB) -- cgit v1.2.3 From 8ef757df3d2ab5867f2361908e524a7de0f4489e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 6 Oct 2017 18:57:37 +1100 Subject: Vertex Paint: use brush front-face setting Follow sculpt mode more closely by using the brush front-face option. --- source/blender/editors/sculpt_paint/paint_vertex.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source/blender/editors/sculpt_paint') diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 7c54277639a..1487b75a4d6 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -143,7 +143,7 @@ static float view_angle_limits_apply_falloff( static bool vwpaint_use_normal(const VPaint *vp) { - return ((vp->flag & VP_FLAG_PROJECT_BACKFACE) == 0) || + return ((vp->paint.brush->flag & BRUSH_FRONTFACE) != 0) || ((vp->flag & VP_FLAG_PROJECT_FLAT) == 0); } @@ -1556,7 +1556,7 @@ static void do_wpaint_brush_blur_task_cb_ex( float brush_strength = cache->bstrength; const float angle_cos = (use_normal && vd.no) ? dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f; - if (((data->vp->flag & VP_FLAG_PROJECT_BACKFACE) || + if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && ((data->vp->flag & VP_FLAG_PROJECT_FLAT) || view_angle_limits_apply_falloff(&data->wpd->normal_angle_precalc, angle_cos, &brush_strength))) @@ -1632,7 +1632,7 @@ static void do_wpaint_brush_smear_task_cb_ex( float brush_strength = cache->bstrength; const float angle_cos = (use_normal && vd.no) ? dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f; - if (((data->vp->flag & VP_FLAG_PROJECT_BACKFACE) || + if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && ((data->vp->flag & VP_FLAG_PROJECT_FLAT) || view_angle_limits_apply_falloff(&data->wpd->normal_angle_precalc, angle_cos, &brush_strength))) @@ -1733,7 +1733,7 @@ static void do_wpaint_brush_draw_task_cb_ex( float brush_strength = cache->bstrength; const float angle_cos = (use_normal && vd.no) ? dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f; - if (((data->vp->flag & VP_FLAG_PROJECT_BACKFACE) || + if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && ((data->vp->flag & VP_FLAG_PROJECT_FLAT) || view_angle_limits_apply_falloff(&data->wpd->normal_angle_precalc, angle_cos, &brush_strength))) @@ -2530,7 +2530,7 @@ static void do_vpaint_brush_draw_task_cb_ex( float brush_strength = cache->bstrength; const float angle_cos = (use_normal && vd.no) ? dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f; - if (((data->vp->flag & VP_FLAG_PROJECT_BACKFACE) || + if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && ((data->vp->flag & VP_FLAG_PROJECT_FLAT) || view_angle_limits_apply_falloff(&data->vpd->normal_angle_precalc, angle_cos, &brush_strength))) @@ -2616,7 +2616,7 @@ static void do_vpaint_brush_blur_task_cb_ex( float brush_strength = cache->bstrength; const float angle_cos = (use_normal && vd.no) ? dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f; - if (((data->vp->flag & VP_FLAG_PROJECT_BACKFACE) || + if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && ((data->vp->flag & VP_FLAG_PROJECT_FLAT) || view_angle_limits_apply_falloff(&data->vpd->normal_angle_precalc, angle_cos, &brush_strength))) @@ -2731,7 +2731,7 @@ static void do_vpaint_brush_smear_task_cb_ex( float brush_strength = cache->bstrength; const float angle_cos = (use_normal && vd.no) ? dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f; - if (((data->vp->flag & VP_FLAG_PROJECT_BACKFACE) || + if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && ((data->vp->flag & VP_FLAG_PROJECT_FLAT) || view_angle_limits_apply_falloff(&data->vpd->normal_angle_precalc, angle_cos, &brush_strength))) -- cgit v1.2.3 From 6c43490616973af78f91062df402e2ca34cedac5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 6 Oct 2017 19:10:33 +1100 Subject: Vertex Paint: use view normal w/ 2D falloff When projecting to the view, cull faces pointing away from the view normal. --- source/blender/editors/sculpt_paint/paint_vertex.c | 28 ++++++++++++++++------ source/blender/editors/sculpt_paint/sculpt.c | 13 ++++++++++ .../blender/editors/sculpt_paint/sculpt_intern.h | 2 ++ 3 files changed, 36 insertions(+), 7 deletions(-) (limited to 'source/blender/editors/sculpt_paint') diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 1487b75a4d6..d10f483c52e 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -1521,6 +1521,8 @@ static void do_wpaint_brush_blur_task_cb_ex( SculptBrushTest test; SculptBrushTestFn sculpt_brush_test_sq_fn = sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); + const float *sculpt_normal_frontface = + sculpt_brush_frontface_normal_from_falloff_shape(ss, data->brush->falloff_shape); /* For each vertex */ PBVHVertexIter vd; @@ -1555,7 +1557,7 @@ static void do_wpaint_brush_blur_task_cb_ex( if (total_hit_loops != 0) { float brush_strength = cache->bstrength; const float angle_cos = (use_normal && vd.no) ? - dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f; + dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f; if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && ((data->vp->flag & VP_FLAG_PROJECT_FLAT) || @@ -1614,6 +1616,8 @@ static void do_wpaint_brush_smear_task_cb_ex( SculptBrushTest test; SculptBrushTestFn sculpt_brush_test_sq_fn = sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); + const float *sculpt_normal_frontface = + sculpt_brush_frontface_normal_from_falloff_shape(ss, data->brush->falloff_shape); /* For each vertex */ PBVHVertexIter vd; @@ -1631,7 +1635,7 @@ static void do_wpaint_brush_smear_task_cb_ex( if (!(use_face_sel || use_vert_sel) || mv_curr->flag & SELECT) { float brush_strength = cache->bstrength; const float angle_cos = (use_normal && vd.no) ? - dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f; + dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f; if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && ((data->vp->flag & VP_FLAG_PROJECT_FLAT) || @@ -1714,6 +1718,8 @@ static void do_wpaint_brush_draw_task_cb_ex( SculptBrushTest test; SculptBrushTestFn sculpt_brush_test_sq_fn = sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); + const float *sculpt_normal_frontface = + sculpt_brush_frontface_normal_from_falloff_shape(ss, data->brush->falloff_shape); /* For each vertex */ PBVHVertexIter vd; @@ -1732,7 +1738,7 @@ static void do_wpaint_brush_draw_task_cb_ex( if (!(use_face_sel || use_vert_sel) || v_flag & SELECT) { float brush_strength = cache->bstrength; const float angle_cos = (use_normal && vd.no) ? - dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f; + dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f; if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && ((data->vp->flag & VP_FLAG_PROJECT_FLAT) || @@ -1779,6 +1785,8 @@ static void do_wpaint_brush_calc_average_weight_cb_ex( SculptBrushTest test; SculptBrushTestFn sculpt_brush_test_sq_fn = sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); + const float *sculpt_normal_frontface = + sculpt_brush_frontface_normal_from_falloff_shape(ss, data->brush->falloff_shape); /* For each vertex */ PBVHVertexIter vd; @@ -1787,7 +1795,7 @@ static void do_wpaint_brush_calc_average_weight_cb_ex( /* Test to see if the vertex coordinates are within the spherical brush region. */ if (sculpt_brush_test_sq_fn(&test, vd.co)) { const float angle_cos = (use_normal && vd.no) ? - dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f; + dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f; if (angle_cos > 0.0 && BKE_brush_curve_strength(data->brush, sqrtf(test.dist), cache->radius) > 0.0) { const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; // const float grid_alpha = ccgdm ? 1.0f / vd.gridsize : 1.0f; @@ -2509,6 +2517,8 @@ static void do_vpaint_brush_draw_task_cb_ex( SculptBrushTest test; SculptBrushTestFn sculpt_brush_test_sq_fn = sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); + const float *sculpt_normal_frontface = + sculpt_brush_frontface_normal_from_falloff_shape(ss, data->brush->falloff_shape); /* For each vertex */ PBVHVertexIter vd; @@ -2529,7 +2539,7 @@ static void do_vpaint_brush_draw_task_cb_ex( * (ie splash prevention factor), and only paint front facing verts. */ float brush_strength = cache->bstrength; const float angle_cos = (use_normal && vd.no) ? - dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f; + dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f; if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && ((data->vp->flag & VP_FLAG_PROJECT_FLAT) || @@ -2598,6 +2608,8 @@ static void do_vpaint_brush_blur_task_cb_ex( SculptBrushTest test; SculptBrushTestFn sculpt_brush_test_sq_fn = sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); + const float *sculpt_normal_frontface = + sculpt_brush_frontface_normal_from_falloff_shape(ss, data->brush->falloff_shape); /* For each vertex */ PBVHVertexIter vd; @@ -2615,7 +2627,7 @@ static void do_vpaint_brush_blur_task_cb_ex( if (!use_vert_sel || mv->flag & SELECT) { float brush_strength = cache->bstrength; const float angle_cos = (use_normal && vd.no) ? - dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f; + dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f; if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && ((data->vp->flag & VP_FLAG_PROJECT_FLAT) || @@ -2711,6 +2723,8 @@ static void do_vpaint_brush_smear_task_cb_ex( SculptBrushTest test; SculptBrushTestFn sculpt_brush_test_sq_fn = sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape); + const float *sculpt_normal_frontface = + sculpt_brush_frontface_normal_from_falloff_shape(ss, data->brush->falloff_shape); /* For each vertex */ PBVHVertexIter vd; @@ -2730,7 +2744,7 @@ static void do_vpaint_brush_smear_task_cb_ex( * (ie splash prevention factor), and only paint front facing verts. */ float brush_strength = cache->bstrength; const float angle_cos = (use_normal && vd.no) ? - dot_vf3vs3(ss->cache->sculpt_normal_symm, vd.no) : 1.0f; + dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f; if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && ((data->vp->flag & VP_FLAG_PROJECT_FLAT) || diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 5f38eaa4de2..ad58adfe4af 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -651,6 +651,19 @@ SculptBrushTestFn sculpt_brush_test_init_with_falloff_shape( return sculpt_brush_test_sq_fn; } +const float *sculpt_brush_frontface_normal_from_falloff_shape( + SculptSession *ss, char falloff_shape) +{ + if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { + return ss->cache->sculpt_normal_symm; + } + else { + /* PAINT_FALLOFF_SHAPE_TUBE */ + return ss->cache->view_normal; + } +} + + static float frontface(const Brush *br, const float sculpt_normal[3], const short no[3], const float fno[3]) { diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 73581d402cf..aaea13ce5d0 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -219,6 +219,8 @@ bool sculpt_search_circle_cb(PBVHNode *node, void *data_v); SculptBrushTestFn sculpt_brush_test_init_with_falloff_shape( SculptSession *ss, SculptBrushTest *test, char falloff_shape); +const float *sculpt_brush_frontface_normal_from_falloff_shape( + SculptSession *ss, char falloff_shape); float tex_strength( struct SculptSession *ss, const struct Brush *br, -- cgit v1.2.3 From 471be7e7f58a4776857666df13e473c8ea0f4fd5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 6 Oct 2017 20:11:17 +1100 Subject: Vertex Paint: move normal falloff into the brush All related settings are already in the brush, so it's inconvenient to switch panels to change this one option. --- source/blender/editors/sculpt_paint/paint_vertex.c | 23 ++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'source/blender/editors/sculpt_paint') diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index d10f483c52e..6a1dbfc6b46 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -104,6 +104,7 @@ struct NormalAnglePrecalc { static void view_angle_limits_init( struct NormalAnglePrecalc *a, float angle, bool do_mask_normal) { + angle = RAD2DEGF(angle); a->do_mask_normal = do_mask_normal; if (do_mask_normal) { a->angle_inner = angle; @@ -144,7 +145,7 @@ static float view_angle_limits_apply_falloff( static bool vwpaint_use_normal(const VPaint *vp) { return ((vp->paint.brush->flag & BRUSH_FRONTFACE) != 0) || - ((vp->flag & VP_FLAG_PROJECT_FLAT) == 0); + ((vp->paint.brush->flag & BRUSH_FRONTFACE_FALLOFF) != 0); } @@ -356,7 +357,7 @@ static float calc_vp_alpha_col_dl( if (strength > 0.0f) { float alpha = brush_alpha_pressure * strength; - if ((vp->flag & VP_FLAG_PROJECT_FLAT) == 0) { + if ((vp->paint.brush->flag & BRUSH_FRONTFACE_FALLOFF) != 0) { float dvec[3]; /* transpose ! */ @@ -1380,7 +1381,8 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo wpd = MEM_callocN(sizeof(struct WPaintData), "WPaintData"); paint_stroke_set_mode_data(stroke, wpd); view3d_set_viewcontext(C, &wpd->vc); - view_angle_limits_init(&wpd->normal_angle_precalc, vp->normal_angle, (vp->flag & VP_FLAG_PROJECT_FLAT) == 0); + view_angle_limits_init(&wpd->normal_angle_precalc, vp->paint.brush->falloff_angle, + (vp->paint.brush->flag & BRUSH_FRONTFACE_FALLOFF) != 0); wpd->active.index = vgroup_index.active; wpd->mirror.index = vgroup_index.mirror; @@ -1560,7 +1562,7 @@ static void do_wpaint_brush_blur_task_cb_ex( dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f; if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && - ((data->vp->flag & VP_FLAG_PROJECT_FLAT) || + ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 || view_angle_limits_apply_falloff(&data->wpd->normal_angle_precalc, angle_cos, &brush_strength))) { const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius); @@ -1638,7 +1640,7 @@ static void do_wpaint_brush_smear_task_cb_ex( dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f; if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && - ((data->vp->flag & VP_FLAG_PROJECT_FLAT) || + ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 || view_angle_limits_apply_falloff(&data->wpd->normal_angle_precalc, angle_cos, &brush_strength))) { bool do_color = false; @@ -1741,7 +1743,7 @@ static void do_wpaint_brush_draw_task_cb_ex( dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f; if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && - ((data->vp->flag & VP_FLAG_PROJECT_FLAT) || + ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 || view_angle_limits_apply_falloff(&data->wpd->normal_angle_precalc, angle_cos, &brush_strength))) { const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius); @@ -2375,7 +2377,8 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f vpd = MEM_callocN(sizeof(*vpd), "VPaintData"); paint_stroke_set_mode_data(stroke, vpd); view3d_set_viewcontext(C, &vpd->vc); - view_angle_limits_init(&vpd->normal_angle_precalc, vp->normal_angle, (vp->flag & VP_FLAG_PROJECT_FLAT) == 0); + view_angle_limits_init(&vpd->normal_angle_precalc, vp->paint.brush->falloff_angle, + (vp->paint.brush->flag & BRUSH_FRONTFACE_FALLOFF) != 0); vpd->paintcol = vpaint_get_current_col(scene, vp); @@ -2542,7 +2545,7 @@ static void do_vpaint_brush_draw_task_cb_ex( dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f; if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && - ((data->vp->flag & VP_FLAG_PROJECT_FLAT) || + ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 || view_angle_limits_apply_falloff(&data->vpd->normal_angle_precalc, angle_cos, &brush_strength))) { const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius); @@ -2630,7 +2633,7 @@ static void do_vpaint_brush_blur_task_cb_ex( dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f; if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && - ((data->vp->flag & VP_FLAG_PROJECT_FLAT) || + ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 || view_angle_limits_apply_falloff(&data->vpd->normal_angle_precalc, angle_cos, &brush_strength))) { const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius); @@ -2747,7 +2750,7 @@ static void do_vpaint_brush_smear_task_cb_ex( dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f; if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && - ((data->vp->flag & VP_FLAG_PROJECT_FLAT) || + ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 || view_angle_limits_apply_falloff(&data->vpd->normal_angle_precalc, angle_cos, &brush_strength))) { const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius); -- cgit v1.2.3 From 3df139c53062a141403ea9d359715ca3635c243c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 6 Oct 2017 21:05:34 +1100 Subject: Cleanup: Math lib naming (use v3 suffix) --- source/blender/editors/sculpt_paint/paint_vertex.c | 2 +- source/blender/editors/sculpt_paint/sculpt.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source/blender/editors/sculpt_paint') diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 6a1dbfc6b46..65306f1dd86 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -1907,7 +1907,7 @@ static PBVHNode **vwpaint_pbvh_gather_generic( } else { struct DistRayAABB_Precalc dist_ray_to_aabb_precalc; - dist_squared_ray_to_aabb_precalc(&dist_ray_to_aabb_precalc, ss->cache->location, ss->cache->view_normal); + dist_squared_ray_to_aabb_v3_precalc(&dist_ray_to_aabb_precalc, ss->cache->location, ss->cache->view_normal); SculptSearchCircleData data = { .ss = ss, .sd = sd, diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index ad58adfe4af..84bb4652d33 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1278,7 +1278,7 @@ bool sculpt_search_circle_cb(PBVHNode *node, void *data_v) BKE_pbvh_node_get_BB(node, bb_min, bb_min); float dummy_co[3], dummy_depth; - const float dist_sq = dist_squared_ray_to_aabb( + const float dist_sq = dist_squared_ray_to_aabb_v3( data->dist_ray_to_aabb_precalc, bb_min, bb_max, dummy_co, &dummy_depth); return dist_sq < data->radius_squared || 1; @@ -1318,7 +1318,7 @@ static PBVHNode **sculpt_pbvh_gather_generic( } else { struct DistRayAABB_Precalc dist_ray_to_aabb_precalc; - dist_squared_ray_to_aabb_precalc(&dist_ray_to_aabb_precalc, ss->cache->location, ss->cache->view_normal); + dist_squared_ray_to_aabb_v3_precalc(&dist_ray_to_aabb_precalc, ss->cache->location, ss->cache->view_normal); SculptSearchCircleData data = { .ss = ss, .sd = sd, -- cgit v1.2.3