From 268524c0257fe313c3c25b4c3e93913690435bea Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 30 Mar 2015 21:17:07 +1100 Subject: Cleanup: use const for typeinfo --- source/blender/editors/sculpt_paint/sculpt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index ea046b7d4d5..5c55ad1c63d 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -4746,7 +4746,7 @@ static int sculpt_dynamic_topology_toggle_invoke(bContext *C, wmOperator *op, co /* exception for shape keys because we can edit those */ for (; md; md = md->next) { - ModifierTypeInfo *mti = modifierType_getInfo(md->type); + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); if (!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue; if (mti->type == eModifierTypeType_Constructive) { -- cgit v1.2.3 From 7acd69958b336663e62f85deb50b3eb1da92cf95 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 4 Apr 2015 15:15:50 +1100 Subject: Cleanup: use BKE_sculptsession_* prefix --- source/blender/editors/sculpt_paint/sculpt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 5c55ad1c63d..6ca368ea4f7 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -4912,7 +4912,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) /* Leave sculptmode */ ob->mode &= ~mode_flag; - BKE_free_sculptsession(ob); + BKE_sculptsession_free(ob); paint_cursor_delete_textures(); } @@ -4950,7 +4950,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) /* Create sculpt mode session data */ if (ob->sculpt) - BKE_free_sculptsession(ob); + BKE_sculptsession_free(ob); sculpt_init_session(scene, ob); -- cgit v1.2.3 From 356ceded279b190bfca801afe25323efadd40571 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 15 Apr 2015 15:22:37 +1000 Subject: Sculpt: change behavior of crease brush Pinch would give a flat result on either side of the stroke, because points were dragged towards a single point. Now pinch is projected on the sculpt plane, which gives a tighter crease. The reverse is true too - blob brush which shares the code is also more curved. --- source/blender/editors/sculpt_paint/sculpt.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 6ca368ea4f7..411ccefe5c0 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1699,6 +1699,16 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod float brush_alpha; int n; + /* vars for handling projection when calculating the pinch vector. + * Use surface normal for 'v_proj',s o the vertices are pinched towards a line instead of a single point. + * Without this we get a 'flat' surface surrounding the pinch */ + const float *pinch_proj = ss->cache->sculpt_normal_symm; + const float pinch_proj_len_sq = len_squared_v3(pinch_proj); + const bool do_pinch_proj = (pinch_proj_len_sq > FLT_EPSILON); + /* simplifies projection calc below */ + const float pinch_proj_len_sq_inv_neg = do_pinch_proj ? -1.0f / pinch_proj_len_sq : 0.0f; + + /* offset with as much as possible factored in already */ mul_v3_v3fl(offset, ss->cache->sculpt_normal_symm, ss->cache->radius); mul_v3_v3(offset, ss->cache->scale); @@ -1739,6 +1749,15 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod sub_v3_v3v3(val1, test.location, vd.co); mul_v3_fl(val1, fade * flippedbstrength); + if (do_pinch_proj) { +#if 0 + project_plane_v3_v3v3(val1, val1, v_proj); +#else + /* inline the projection, cache `-1.0 / dot_v3_v3(v_proj, v_proj)` */ + madd_v3_v3fl(val1, pinch_proj, dot_v3v3(val1, pinch_proj) * pinch_proj_len_sq_inv_neg); +#endif + } + /* then we draw */ mul_v3_v3fl(val2, offset, fade); -- cgit v1.2.3 From 9a711f98a7f55a2534f1f6fe3756914d8f7f8861 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 15 Apr 2015 15:34:06 +1000 Subject: typo in last commit --- source/blender/editors/sculpt_paint/sculpt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 411ccefe5c0..b14fbc40049 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -328,7 +328,7 @@ static int sculpt_stroke_dynamic_topology(const SculptSession *ss, * dynamic-topology */ !(brush->flag & BRUSH_ANCHORED) && !(brush->flag & BRUSH_DRAG_DOT) && - + (!ELEM(brush->sculpt_tool, /* These brushes, as currently coded, cannot * support dynamic topology */ @@ -1700,7 +1700,7 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod int n; /* vars for handling projection when calculating the pinch vector. - * Use surface normal for 'v_proj',s o the vertices are pinched towards a line instead of a single point. + * Use surface normal for 'pinch_proj', so the vertices are pinched towards a line instead of a single point. * Without this we get a 'flat' surface surrounding the pinch */ const float *pinch_proj = ss->cache->sculpt_normal_symm; const float pinch_proj_len_sq = len_squared_v3(pinch_proj); -- cgit v1.2.3 From afc2f415ab6997168b838102ab29ba15b306b80e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 17 Apr 2015 03:10:57 +1000 Subject: Cleanup: use const for sculpt code --- source/blender/editors/sculpt_paint/sculpt.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index b14fbc40049..165de4ca791 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -705,10 +705,10 @@ static float calc_symmetry_feather(Sculpt *sd, StrokeCache *cache) /* Return modified brush strength. Includes the direction of the brush, positive * values pull vertices, negative values push. Uses tablet pressure and a * special multiplier found experimentally to scale the strength factor. */ -static float brush_strength(Sculpt *sd, StrokeCache *cache, float feather, UnifiedPaintSettings *ups) +static float brush_strength(const Sculpt *sd, const StrokeCache *cache, const float feather, const UnifiedPaintSettings *ups) { const Scene *scene = cache->vc->scene; - Brush *brush = BKE_paint_brush(&sd->paint); + const Brush *brush = BKE_paint_brush((Paint *)&sd->paint); /* Primary strength input; square it to make lower values more sensitive */ const float root_alpha = BKE_brush_alpha_get(scene, brush); @@ -2450,20 +2450,24 @@ static void calc_sculpt_plane(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn } /* Projects a point onto a plane along the plane's normal */ -static void point_plane_project(float intr[3], float co[3], float plane_normal[3], float plane_center[3]) +static void point_plane_project( + float intr[3], + const float co[3], const float plane_normal[3], const float plane_center[3]) { sub_v3_v3v3(intr, co, plane_center); mul_v3_v3fl(intr, plane_normal, dot_v3v3(plane_normal, intr)); sub_v3_v3v3(intr, co, intr); } -static int plane_trim(StrokeCache *cache, Brush *brush, float val[3]) +static int plane_trim(const StrokeCache *cache, const Brush *brush, const float val[3]) { return (!(brush->flag & BRUSH_PLANE_TRIM) || ((dot_v3v3(val, val) <= cache->radius_squared * cache->plane_trim_squared))); } -static int plane_point_side_flip(float co[3], float plane_normal[3], float plane_center[3], int flip) +static bool plane_point_side_flip( + const float co[3], const float plane_normal[3], const float plane_center[3], + const bool flip) { float delta[3]; float d; @@ -2476,7 +2480,7 @@ static int plane_point_side_flip(float co[3], float plane_normal[3], float plane return d <= 0.0f; } -static int plane_point_side(float co[3], float plane_normal[3], float plane_center[3]) +static int plane_point_side(const float co[3], const float plane_normal[3], const float plane_center[3]) { float delta[3]; @@ -2577,7 +2581,7 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) float temp[3]; - int flip; + bool flip; calc_sculpt_plane(sd, ob, nodes, totnode, an, fc); @@ -2655,7 +2659,7 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t float scale[4][4]; float tmat[4][4]; - int flip; + bool flip; calc_sculpt_plane(sd, ob, nodes, totnode, sn, fc); -- cgit v1.2.3 From e05f719b8bc11457b4555bdd8bddf8fe6858ef9d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 17 Apr 2015 17:31:56 +1000 Subject: Dyntopo: avoid redundant lookup on original data --- source/blender/editors/sculpt_paint/sculpt.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 165de4ca791..2c76b3dee21 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -285,26 +285,22 @@ static void sculpt_orig_vert_data_update(SculptOrigVertData *orig_data, PBVHVertexIter *iter) { if (orig_data->unode->type == SCULPT_UNDO_COORDS) { - if (orig_data->coords) { - orig_data->co = orig_data->coords[iter->i]; + if (orig_data->bm_log) { + BM_log_original_vert_data( + orig_data->bm_log, iter->bm_vert, + &orig_data->co, &orig_data->no); } else { - orig_data->co = BM_log_original_vert_co(orig_data->bm_log, iter->bm_vert); - } - - if (orig_data->normals) { + orig_data->co = orig_data->coords[iter->i]; orig_data->no = orig_data->normals[iter->i]; } - else { - orig_data->no = BM_log_original_vert_no(orig_data->bm_log, iter->bm_vert); - } } else if (orig_data->unode->type == SCULPT_UNDO_MASK) { - if (orig_data->vmasks) { - orig_data->mask = orig_data->vmasks[iter->i]; + if (orig_data->bm_log) { + orig_data->mask = BM_log_original_mask(orig_data->bm_log, iter->bm_vert); } else { - orig_data->mask = BM_log_original_mask(orig_data->bm_log, iter->bm_vert); + orig_data->mask = orig_data->vmasks[iter->i]; } } } -- cgit v1.2.3 From 15d3d8560d7cee0def23b8a1145ddd0801fca8ea Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 17 Apr 2015 20:55:33 +1000 Subject: Cleanup: remove unused face normals also use const --- source/blender/editors/sculpt_paint/sculpt.c | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 2c76b3dee21..67d81ab75b7 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -182,8 +182,6 @@ typedef struct StrokeCache { ViewContext *vc; Brush *brush; - float (*face_norms)[3]; /* Copy of the mesh faces' normals */ - float special_rotation; float grab_delta[3], grab_delta_symmetry[3]; float old_grab_location[3], orig_grab_location[3]; @@ -345,9 +343,7 @@ static int sculpt_stroke_dynamic_topology(const SculptSession *ss, static void paint_mesh_restore_co(Sculpt *sd, Object *ob) { SculptSession *ss = ob->sculpt; - StrokeCache *cache = ss->cache; const Brush *brush = BKE_paint_brush(&sd->paint); - int i; PBVHNode **nodes; int n, totnode; @@ -400,12 +396,6 @@ static void paint_mesh_restore_co(Sculpt *sd, Object *ob) } } - if (ss->face_normals) { - for (i = 0; i < ss->totpoly; i++) { - copy_v3_v3(ss->face_normals[i], cache->face_norms[i]); - } - } - if (nodes) MEM_freeN(nodes); } @@ -505,7 +495,7 @@ static void sculpt_brush_test_init(SculptSession *ss, SculptBrushTest *test) } } -BLI_INLINE bool sculpt_brush_test_clipping(SculptBrushTest *test, const float co[3]) +BLI_INLINE bool sculpt_brush_test_clipping(const SculptBrushTest *test, const float co[3]) { RegionView3D *rv3d = test->clip_rv3d; return (rv3d && (ED_view3d_clipping_test(rv3d, co, true))); @@ -543,7 +533,7 @@ static bool sculpt_brush_test_sq(SculptBrushTest *test, const float co[3]) } } -static bool sculpt_brush_test_fast(SculptBrushTest *test, float co[3]) +static bool sculpt_brush_test_fast(const SculptBrushTest *test, const float co[3]) { if (sculpt_brush_test_clipping(test, co)) { return 0; @@ -551,7 +541,7 @@ static bool sculpt_brush_test_fast(SculptBrushTest *test, float co[3]) return len_squared_v3v3(co, test->location) <= test->radius_squared; } -static bool sculpt_brush_test_cube(SculptBrushTest *test, float co[3], float local[4][4]) +static bool sculpt_brush_test_cube(SculptBrushTest *test, const float co[3], float local[4][4]) { float side = M_SQRT1_2; float local_co[3]; @@ -3503,8 +3493,6 @@ static const char *sculpt_tool_name(Sculpt *sd) static void sculpt_cache_free(StrokeCache *cache) { - if (cache->face_norms) - MEM_freeN(cache->face_norms); if (cache->dial) MEM_freeN(cache->dial); MEM_freeN(cache); @@ -3764,13 +3752,6 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio /* Make copies of the mesh vertex locations and normals for some tools */ if (brush->flag & BRUSH_ANCHORED) { - if (ss->face_normals) { - cache->face_norms = MEM_mallocN(sizeof(float) * 3 * ss->totpoly, "Sculpt face norms"); - for (i = 0; i < ss->totpoly; ++i) { - copy_v3_v3(cache->face_norms[i], ss->face_normals[i]); - } - } - cache->original = 1; } -- cgit v1.2.3 From 28b9a0276fd6cfce0da7a8f434c13b252fc2cbbb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 18 Apr 2015 02:50:58 +1000 Subject: Cleanup: simplify sculpt plane accumulation --- source/blender/editors/sculpt_paint/sculpt.c | 100 +++++++++++---------------- 1 file changed, 39 insertions(+), 61 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 67d81ab75b7..436375707e7 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -2263,88 +2263,66 @@ static void calc_area_normal_and_flatten_center(Sculpt *sd, Object *ob, PBVHVertexIter vd; SculptBrushTest test; SculptUndoNode *unode; - float private_an[3] = {0.0f, 0.0f, 0.0f}; - float private_out_flip[3] = {0.0f, 0.0f, 0.0f}; - float private_fc[3] = {0.0f, 0.0f, 0.0f}; - float private_fc_flip[3] = {0.0f, 0.0f, 0.0f}; - int private_count = 0; - int private_count_flip = 0; + /* 0=towards view, 1=flipped */ + float private_co[2][3] = {{0.0f}}; + float private_no[2][3] = {{0.0f}}; + int private_count[2] = {0, 0}; + bool use_original; unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS); sculpt_brush_test_init(ss, &test); - if (ss->cache->original && unode->co) { - BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) - { - if (sculpt_brush_test_fast(&test, unode->co[vd.i])) { - /* for area normal */ - float fno[3]; + use_original = (ss->cache->original && unode->co); - normal_short_to_float_v3(fno, unode->no[vd.i]); + BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) + { + const float *co; - if (dot_v3v3(ss->cache->view_normal, fno) > 0) { - add_v3_v3(private_an, fno); - add_v3_v3(private_fc, unode->co[vd.i]); - private_count++; - } - else { - add_v3_v3(private_out_flip, fno); - add_v3_v3(private_fc_flip, unode->co[vd.i]); - private_count_flip++; - } - } + if (use_original) { + co = unode->co[vd.i]; + } + else { + co = vd.co; } - BKE_pbvh_vertex_iter_end; - } - else { - BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) - { - if (sculpt_brush_test_fast(&test, vd.co)) { - /* for area normal */ - if (vd.no) { - float fno[3]; - normal_short_to_float_v3(fno, vd.no); + if (sculpt_brush_test_fast(&test, co)) { + float no_buf[3]; + const float *no; + int flip_index; - if (dot_v3v3(ss->cache->view_normal, fno) > 0) { - add_v3_v3(private_an, fno); - add_v3_v3(private_fc, vd.co); - private_count++; - } - else { - add_v3_v3(private_out_flip, fno); - add_v3_v3(private_fc_flip, vd.co); - private_count_flip++; - } + if (use_original) { + normal_short_to_float_v3(no_buf, unode->no[vd.i]); + no = no_buf; + } + else { + if (vd.no) { + normal_short_to_float_v3(no_buf, vd.no); + no = no_buf; } else { - if (dot_v3v3(ss->cache->view_normal, vd.fno) > 0) { - add_v3_v3(private_an, vd.fno); - add_v3_v3(private_fc, vd.co); - private_count++; - } - else { - add_v3_v3(private_out_flip, vd.fno); - add_v3_v3(private_fc_flip, vd.co); - private_count_flip++; - } + no = vd.fno; } } + + flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f); + add_v3_v3(private_co[flip_index], co); + add_v3_v3(private_no[flip_index], no); + private_count[flip_index] += 1; } - BKE_pbvh_vertex_iter_end; } + BKE_pbvh_vertex_iter_end; #pragma omp critical { /* for area normal */ - add_v3_v3(an, private_an); - add_v3_v3(out_flip, private_out_flip); + add_v3_v3(an, private_no[0]); + add_v3_v3(out_flip, private_no[1]); /* for flatten center */ - add_v3_v3(fc, private_fc); - add_v3_v3(fc_flip, private_fc_flip); - count += private_count; - count_flipped += private_count_flip; + add_v3_v3(fc, private_co[0]); + add_v3_v3(fc_flip, private_co[1]); + count += private_count[0]; + count_flipped += private_count[1]; } } -- cgit v1.2.3 From b0c2fdd927d1478ca76a312442f0c452a704607f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 18 Apr 2015 03:09:16 +1000 Subject: Cleanup: simplify sculpt normal accumulation --- source/blender/editors/sculpt_paint/sculpt.c | 84 ++++++++++++---------------- 1 file changed, 35 insertions(+), 49 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 436375707e7..63b95aa9c64 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -2156,73 +2156,59 @@ static void calc_flatten_center(Sculpt *sd, Object *ob, PBVHNode **nodes, int to PBVHVertexIter vd; SculptBrushTest test; SculptUndoNode *unode; - float private_fc[3] = {0.0f, 0.0f, 0.0f}; - float private_fc_flip[3] = {0.0f, 0.0f, 0.0f}; - int private_count = 0; - int private_count_flip = 0; + /* 0=towards view, 1=flipped */ + float private_co[2][3] = {{0.0f}}; + int private_count[2] = {0, 0}; + bool use_original; unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS); sculpt_brush_test_init(ss, &test); - if (ss->cache->original && unode->co) { - BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) - { - if (sculpt_brush_test_fast(&test, unode->co[vd.i])) { - float fno[3]; + use_original = (ss->cache->original && unode->co); - normal_short_to_float_v3(fno, unode->no[vd.i]); - if (dot_v3v3(ss->cache->view_normal, fno) > 0) { - add_v3_v3(private_fc, unode->co[vd.i]); - private_count++; - } - else { - add_v3_v3(private_fc_flip, unode->co[vd.i]); - private_count_flip++; - } - } + BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) + { + const float *co; + + if (use_original) { + co = unode->co[vd.i]; + } + else { + co = vd.co; } - BKE_pbvh_vertex_iter_end; - } - else { - BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) - { - if (sculpt_brush_test_fast(&test, vd.co)) { - /* for area normal */ - if (vd.no) { - float fno[3]; - normal_short_to_float_v3(fno, vd.no); + if (sculpt_brush_test_fast(&test, co)) { + float no_buf[3]; + const float *no; + int flip_index; - if (dot_v3v3(ss->cache->view_normal, fno) > 0) { - add_v3_v3(private_fc, vd.co); - private_count++; - } - else { - add_v3_v3(private_fc_flip, vd.co); - private_count_flip++; - } + if (use_original) { + normal_short_to_float_v3(no_buf, unode->no[vd.i]); + no = no_buf; + } + else { + if (vd.no) { + normal_short_to_float_v3(no_buf, vd.no); + no = no_buf; } else { - if (dot_v3v3(ss->cache->view_normal, vd.fno) > 0) { - add_v3_v3(private_fc, vd.co); - private_count++; - } - else { - add_v3_v3(private_fc_flip, vd.co); - private_count_flip++; - } + no = vd.fno; } } + + flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f); + add_v3_v3(private_co[flip_index], co); + private_count[flip_index] += 1; } BKE_pbvh_vertex_iter_end; } #pragma omp critical { - add_v3_v3(fc, private_fc); - add_v3_v3(fc_flip, private_fc_flip); - count += private_count; - count_flip += private_count_flip; + add_v3_v3(fc, private_co[0]); + add_v3_v3(fc_flip, private_co[1]); + count += private_count[0]; + count_flip += private_count[1]; } } if (count != 0) -- cgit v1.2.3 From 05b6de545ac59dfa8487c94c0f2a7e75063fb8b3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 18 Apr 2015 04:57:23 +1000 Subject: Fix T44390: Clay brush weirdness part-1 Clay brush had a feedback loop with dyntopo, getting the plane from the cursor center didn't support original data. --- source/blender/editors/sculpt_paint/sculpt.c | 175 +++++++++++++++++++-------- 1 file changed, 124 insertions(+), 51 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 63b95aa9c64..41f53769c4e 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -2164,43 +2164,79 @@ static void calc_flatten_center(Sculpt *sd, Object *ob, PBVHNode **nodes, int to unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS); sculpt_brush_test_init(ss, &test); - use_original = (ss->cache->original && unode->co); - - BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) - { - const float *co; - - if (use_original) { - co = unode->co[vd.i]; - } - else { - co = vd.co; + 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) */ + if (use_original && unode->bm_entry) { + float (*orco_coords)[3]; + int (*orco_tris)[3]; + int orco_tris_num; + int i; + + BKE_pbvh_node_get_bm_orco_data( + nodes[n], + &orco_tris, &orco_tris_num, &orco_coords); + + for (i = 0; i < orco_tris_num; i++) { + const float *co_tri[3] = { + orco_coords[orco_tris[i][0]], + orco_coords[orco_tris[i][1]], + orco_coords[orco_tris[i][2]], + }; + float co[3]; + + closest_on_tri_to_point_v3(co, test.location, UNPACK3(co_tri)); + + if (sculpt_brush_test_fast(&test, co)) { + float no[3]; + int flip_index; + + normal_tri_v3(no, UNPACK3(co_tri)); + + flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f); + add_v3_v3(private_co[flip_index], co); + private_count[flip_index] += 1; + } } - - if (sculpt_brush_test_fast(&test, co)) { - float no_buf[3]; - const float *no; - int flip_index; + } + else { + BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) + { + const float *co; if (use_original) { - normal_short_to_float_v3(no_buf, unode->no[vd.i]); - no = no_buf; + co = unode->co[vd.i]; } else { - if (vd.no) { - normal_short_to_float_v3(no_buf, vd.no); + co = vd.co; + } + + if (sculpt_brush_test_fast(&test, co)) { + float no_buf[3]; + const float *no; + int flip_index; + + if (use_original) { + normal_short_to_float_v3(no_buf, unode->no[vd.i]); no = no_buf; } else { - no = vd.fno; + 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); - add_v3_v3(private_co[flip_index], co); - private_count[flip_index] += 1; + flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f); + add_v3_v3(private_co[flip_index], co); + private_count[flip_index] += 1; + } + BKE_pbvh_vertex_iter_end; } - BKE_pbvh_vertex_iter_end; } #pragma omp critical @@ -2258,45 +2294,82 @@ static void calc_area_normal_and_flatten_center(Sculpt *sd, Object *ob, unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS); sculpt_brush_test_init(ss, &test); - use_original = (ss->cache->original && unode->co); + use_original = (ss->cache->original && (unode->co || unode->bm_entry)); - BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) - { - const float *co; + /* when the mesh is edited we can't rely on original coords + * (original mesh may not even have verts in brush radius) */ + if (use_original && unode->bm_entry) { + float (*orco_coords)[3]; + int (*orco_tris)[3]; + int orco_tris_num; + int i; - if (use_original) { - co = unode->co[vd.i]; - } - else { - co = vd.co; - } + BKE_pbvh_node_get_bm_orco_data( + nodes[n], + &orco_tris, &orco_tris_num, &orco_coords); + + for (i = 0; i < orco_tris_num; i++) { + const float *co_tri[3] = { + orco_coords[orco_tris[i][0]], + orco_coords[orco_tris[i][1]], + orco_coords[orco_tris[i][2]], + }; + float co[3]; + + closest_on_tri_to_point_v3(co, test.location, UNPACK3(co_tri)); + + if (sculpt_brush_test_fast(&test, co)) { + float no[3]; + int flip_index; - if (sculpt_brush_test_fast(&test, co)) { - float no_buf[3]; - const float *no; - int flip_index; + normal_tri_v3(no, UNPACK3(co_tri)); + + flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f); + add_v3_v3(private_co[flip_index], co); + add_v3_v3(private_no[flip_index], no); + private_count[flip_index] += 1; + } + } + } + else { + BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) + { + const float *co; if (use_original) { - normal_short_to_float_v3(no_buf, unode->no[vd.i]); - no = no_buf; + co = unode->co[vd.i]; } else { - if (vd.no) { - normal_short_to_float_v3(no_buf, vd.no); + co = vd.co; + } + + if (sculpt_brush_test_fast(&test, co)) { + float no_buf[3]; + const float *no; + int flip_index; + + if (use_original) { + normal_short_to_float_v3(no_buf, unode->no[vd.i]); no = no_buf; } else { - no = vd.fno; + 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); - add_v3_v3(private_co[flip_index], co); - add_v3_v3(private_no[flip_index], no); - private_count[flip_index] += 1; + flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f); + add_v3_v3(private_co[flip_index], co); + add_v3_v3(private_no[flip_index], no); + private_count[flip_index] += 1; + } } + BKE_pbvh_vertex_iter_end; } - BKE_pbvh_vertex_iter_end; #pragma omp critical { -- cgit v1.2.3 From 3a4a2a942703762bd8c999af5b910f92b13df180 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 18 Apr 2015 05:03:29 +1000 Subject: Fix T44390: Clay brush weirdness part-2 Use the normal of the plane instead of the vertex normal, since projecting using the vertex normal frequently causes artifacts. --- source/blender/editors/sculpt_paint/sculpt.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 41f53769c4e..95eddbf2a69 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -2645,8 +2645,10 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) sub_v3_v3v3(val, intr, vd.co); if (plane_trim(ss->cache, brush, val)) { + /* 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); + NULL, an, vd.mask ? *vd.mask : 0.0f); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -2746,9 +2748,11 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t sub_v3_v3v3(val, intr, vd.co); if (plane_trim(ss->cache, brush, val)) { + /* 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); + NULL, an, vd.mask ? *vd.mask : 0.0f); mul_v3_v3fl(proxy[vd.i], val, fade); -- cgit v1.2.3 From 9ac618a90eddf90071a1d94fa2ae076ce239c785 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 19 Apr 2015 14:21:23 +1000 Subject: Sculpt: smooth brush, exclude self from average Was including the vertices own location when accumulating. --- source/blender/editors/sculpt_paint/sculpt.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 95eddbf2a69..73a9abeac41 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1177,12 +1177,11 @@ static void neighbor_average(SculptSession *ss, float avg[3], unsigned vert) for (i = 0; i < vert_map->count; i++) { const MPoly *p = &ss->mpoly[vert_map->indices[i]]; - unsigned f_adj_v[3]; + unsigned f_adj_v[2]; if (poly_get_adj_loops_from_vert(f_adj_v, p, ss->mloop, vert) != -1) { int j; - - for (j = 0; j < 3; j++) { + for (j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) { if (vert_map->count != 2 || ss->pmap[f_adj_v[j]].count <= 2) { add_v3_v3(avg, deform_co ? deform_co[f_adj_v[j]] : mvert[f_adj_v[j]].co); @@ -1213,12 +1212,11 @@ static float neighbor_average_mask(SculptSession *ss, unsigned vert) for (i = 0; i < ss->pmap[vert].count; i++) { const MPoly *p = &ss->mpoly[ss->pmap[vert].indices[i]]; - unsigned f_adj_v[3]; + unsigned f_adj_v[2]; if (poly_get_adj_loops_from_vert(f_adj_v, p, ss->mloop, vert) != -1) { int j; - - for (j = 0; j < 3; j++) { + for (j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) { avg += vmask[f_adj_v[j]]; total++; } @@ -1245,9 +1243,9 @@ static void bmesh_neighbor_average(float avg[3], BMVert *v) int i, total = 0; BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { - BMVert *adj_v[3] = {l->prev->v, v, l->next->v}; + BMVert *adj_v[2] = {l->prev->v, l->next->v}; - for (i = 0; i < 3; i++) { + for (i = 0; i < ARRAY_SIZE(adj_v); i++) { if (vfcount != 2 || BM_vert_face_count(adj_v[i]) <= 2) { add_v3_v3(avg, adj_v[i]->co); total++; @@ -1273,9 +1271,10 @@ static float bmesh_neighbor_average_mask(BMesh *bm, BMVert *v) int i, total = 0; BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { - BMVert *adj_v[3] = {l->prev->v, v, l->next->v}; + /* skip this vertex */ + BMVert *adj_v[2] = {l->prev->v, l->next->v}; - for (i = 0; i < 3; i++) { + for (i = 0; i < ARRAY_SIZE(adj_v); i++) { BMVert *v2 = adj_v[i]; float *vmask = CustomData_bmesh_get(&bm->vdata, v2->head.data, -- cgit v1.2.3 From 2448c21cb365af0afc22008953f4ebe08de7cb0f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 19 Apr 2015 14:38:16 +1000 Subject: Sculpt: avoid CD lookup /w mask smooth --- source/blender/editors/sculpt_paint/sculpt.c | 35 +++++++++++++--------------- 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 73a9abeac41..8efd6ab3fbe 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1169,12 +1169,12 @@ static void neighbor_average(SculptSession *ss, float avg[3], unsigned vert) const MVert *mvert = ss->mvert; float (*deform_co)[3] = ss->deform_cos; - zero_v3(avg); - /* Don't modify corner vertices */ if (vert_map->count > 1) { int i, total = 0; + zero_v3(avg); + for (i = 0; i < vert_map->count; i++) { const MPoly *p = &ss->mpoly[vert_map->indices[i]]; unsigned f_adj_v[2]; @@ -1234,20 +1234,21 @@ static void bmesh_neighbor_average(float avg[3], BMVert *v) { const int vfcount = BM_vert_face_count(v); - zero_v3(avg); - /* Don't modify corner vertices */ if (vfcount > 1) { BMIter liter; BMLoop *l; int i, total = 0; + zero_v3(avg); + BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { - BMVert *adj_v[2] = {l->prev->v, l->next->v}; + const BMVert *adj_v[2] = {l->prev->v, l->next->v}; for (i = 0; i < ARRAY_SIZE(adj_v); i++) { - if (vfcount != 2 || BM_vert_face_count(adj_v[i]) <= 2) { - add_v3_v3(avg, adj_v[i]->co); + const BMVert *v_other = adj_v[i]; + if (vfcount != 2 || BM_vert_face_count(v_other) <= 2) { + add_v3_v3(avg, v_other->co); total++; } } @@ -1263,7 +1264,7 @@ static void bmesh_neighbor_average(float avg[3], BMVert *v) } /* Same logic as neighbor_average_mask(), but for bmesh rather than mesh */ -static float bmesh_neighbor_average_mask(BMesh *bm, BMVert *v) +static float bmesh_neighbor_average_mask(BMVert *v, const int cd_vert_mask_offset) { BMIter liter; BMLoop *l; @@ -1272,13 +1273,11 @@ static float bmesh_neighbor_average_mask(BMesh *bm, BMVert *v) BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { /* skip this vertex */ - BMVert *adj_v[2] = {l->prev->v, l->next->v}; + const BMVert *adj_v[2] = {l->prev->v, l->next->v}; for (i = 0; i < ARRAY_SIZE(adj_v); i++) { - BMVert *v2 = adj_v[i]; - float *vmask = CustomData_bmesh_get(&bm->vdata, - v2->head.data, - CD_PAINT_MASK); + const BMVert *v_other = adj_v[i]; + const float *vmask = BM_ELEM_CD_GET_VOID_P(v_other, cd_vert_mask_offset); avg += (*vmask); total++; } @@ -1288,9 +1287,7 @@ static float bmesh_neighbor_average_mask(BMesh *bm, BMVert *v) return avg / (float)total; } else { - float *vmask = CustomData_bmesh_get(&bm->vdata, - v->head.data, - CD_PAINT_MASK); + const float *vmask = BM_ELEM_CD_GET_VOID_P(v, cd_vert_mask_offset); return (*vmask); } } @@ -1353,7 +1350,7 @@ static void do_bmesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node, vd.no, vd.fno, smooth_mask ? 0 : *vd.mask); if (smooth_mask) { - float val = bmesh_neighbor_average_mask(ss->bm, vd.bm_vert) - *vd.mask; + float val = bmesh_neighbor_average_mask(vd.bm_vert, vd.cd_vert_mask_offset) - *vd.mask; val *= fade * bstrength; *vd.mask += val; CLAMP(*vd.mask, 0, 1); @@ -1389,7 +1386,7 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no float *tmpgrid_mask, *tmprow_mask; int v1, v2, v3, v4; int thread_num; - BLI_bitmap **grid_hidden; + BLI_bitmap * const *grid_hidden; int *grid_indices, totgrid, gridsize, i, x, y; sculpt_brush_test_init(ss, &test); @@ -1414,7 +1411,7 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no for (i = 0; i < totgrid; ++i) { int gi = grid_indices[i]; - BLI_bitmap *gh = grid_hidden[gi]; + const BLI_bitmap *gh = grid_hidden[gi]; data = griddata[gi]; adj = &gridadj[gi]; -- cgit v1.2.3 From 550c3c2c1ec6fb3ad064a59cfd23f2472766a4d2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 19 Apr 2015 14:42:54 +1000 Subject: Dyntopo: avoid over-counting /w neighbor average --- source/blender/editors/sculpt_paint/sculpt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 8efd6ab3fbe..b0f4cf062f6 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1232,7 +1232,8 @@ static float neighbor_average_mask(SculptSession *ss, unsigned vert) /* Same logic as neighbor_average(), but for bmesh rather than mesh */ static void bmesh_neighbor_average(float avg[3], BMVert *v) { - const int vfcount = BM_vert_face_count(v); + /* logic for 3 or more is identical */ + const int vfcount = BM_vert_face_count_ex(v, 3); /* Don't modify corner vertices */ if (vfcount > 1) { @@ -1247,7 +1248,7 @@ static void bmesh_neighbor_average(float avg[3], BMVert *v) for (i = 0; i < ARRAY_SIZE(adj_v); i++) { const BMVert *v_other = adj_v[i]; - if (vfcount != 2 || BM_vert_face_count(v_other) <= 2) { + if (vfcount != 2 || BM_vert_face_count_ex(v_other, 2) <= 2) { add_v3_v3(avg, v_other->co); total++; } -- cgit v1.2.3 From 57b020528b802feb15ada3bfd9de74029ed0bb89 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 19 Apr 2015 17:03:51 +1000 Subject: Cleanup: calculating sculpt center & normal also avoid sqrt calculating dyntopo center (only checks for flipping) --- source/blender/editors/sculpt_paint/sculpt.c | 118 ++++++++++++++------------- 1 file changed, 62 insertions(+), 56 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index b0f4cf062f6..1f57059cd64 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -2134,28 +2134,28 @@ static void do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno } } -static void calc_flatten_center(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float fc[3]) +static void calc_flatten_center( + Sculpt *sd, Object *ob, + PBVHNode **nodes, int totnode, + float r_area_co[3]) { SculptSession *ss = ob->sculpt; int n; - int count = 0; - int count_flip = 0; + /* 0=towards view, 1=flipped */ + float area_co[2][3] = {{0.0f}}; - float fc_flip[3] = {0.0, 0.0, 0.0}; + int count[2] = {0}; (void)sd; /* unused w/o openmp */ - zero_v3(fc); - #pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) for (n = 0; n < totnode; n++) { PBVHVertexIter vd; SculptBrushTest test; SculptUndoNode *unode; - /* 0=towards view, 1=flipped */ float private_co[2][3] = {{0.0f}}; - int private_count[2] = {0, 0}; + int private_count[2] = {0}; bool use_original; unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS); @@ -2189,7 +2189,7 @@ static void calc_flatten_center(Sculpt *sd, Object *ob, PBVHNode **nodes, int to float no[3]; int flip_index; - normal_tri_v3(no, UNPACK3(co_tri)); + cross_tri_v3(no, UNPACK3(co_tri)); flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f); add_v3_v3(private_co[flip_index], co); @@ -2232,60 +2232,60 @@ static void calc_flatten_center(Sculpt *sd, Object *ob, PBVHNode **nodes, int to add_v3_v3(private_co[flip_index], co); private_count[flip_index] += 1; } - BKE_pbvh_vertex_iter_end; } + BKE_pbvh_vertex_iter_end; } #pragma omp critical { - add_v3_v3(fc, private_co[0]); - add_v3_v3(fc_flip, private_co[1]); - count += private_count[0]; - count_flip += private_count[1]; + /* for flatten center */ + add_v3_v3(area_co[0], private_co[0]); + add_v3_v3(area_co[1], private_co[1]); + + /* weights */ + count[0] += private_count[0]; + count[1] += private_count[1]; } } - if (count != 0) - mul_v3_fl(fc, 1.0f / count); - else if (count_flip != 0) - mul_v3_v3fl(fc, fc_flip, 1.0f / count_flip); - else - zero_v3(fc); + + /* for flatten center */ + for (n = 0; n < ARRAY_SIZE(area_co); n++) { + if (count[n] != 0) { + mul_v3_v3fl(r_area_co, area_co[n], 1.0f / count[n]); + break; + } + } + if (n == 2) { + zero_v3(r_area_co); + } } /* 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_flatten_center(Sculpt *sd, Object *ob, - PBVHNode **nodes, int totnode, - float an[3], float fc[3]) +static void calc_area_normal_and_flatten_center( + Sculpt *sd, Object *ob, + PBVHNode **nodes, int totnode, + float r_area_no[3], float r_area_co[3]) { SculptSession *ss = ob->sculpt; int n; - /* for area normal */ - float out_flip[3] = {0.0f, 0.0f, 0.0f}; - float fc_flip[3] = {0.0f, 0.0f, 0.0f}; + /* 0=towards view, 1=flipped */ + float area_co[2][3] = {{0.0f}}; + float area_no[2][3] = {{0.0f}}; - /* for flatten center */ - int count = 0; - int count_flipped = 0; + int count[2] = {0}; (void)sd; /* unused w/o openmp */ - - /* for area normal */ - zero_v3(an); - - /* for flatten center */ - zero_v3(fc); #pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) for (n = 0; n < totnode; n++) { PBVHVertexIter vd; SculptBrushTest test; SculptUndoNode *unode; - /* 0=towards view, 1=flipped */ float private_co[2][3] = {{0.0f}}; float private_no[2][3] = {{0.0f}}; - int private_count[2] = {0, 0}; + int private_count[2] = {0}; bool use_original; unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS); @@ -2370,31 +2370,37 @@ static void calc_area_normal_and_flatten_center(Sculpt *sd, Object *ob, #pragma omp critical { + /* for flatten center */ + add_v3_v3(area_co[0], private_co[0]); + add_v3_v3(area_co[1], private_co[1]); + /* for area normal */ - add_v3_v3(an, private_no[0]); - add_v3_v3(out_flip, private_no[1]); + add_v3_v3(area_no[0], private_no[0]); + add_v3_v3(area_no[1], private_no[1]); - /* for flatten center */ - add_v3_v3(fc, private_co[0]); - add_v3_v3(fc_flip, private_co[1]); - count += private_count[0]; - count_flipped += private_count[1]; + /* weights */ + count[0] += private_count[0]; + count[1] += private_count[1]; } } - /* for area normal */ - if (is_zero_v3(an)) - copy_v3_v3(an, out_flip); - - normalize_v3(an); - /* for flatten center */ - if (count != 0) - mul_v3_fl(fc, 1.0f / count); - else if (count_flipped != 0) - mul_v3_v3fl(fc, fc_flip, 1.0f / count_flipped); - else - zero_v3(fc); + for (n = 0; n < ARRAY_SIZE(area_co); n++) { + if (count[n] != 0) { + mul_v3_v3fl(r_area_co, area_co[n], 1.0f / count[n]); + break; + } + } + if (n == 2) { + zero_v3(r_area_co); + } + + /* for area normal */ + for (n = 0; n < ARRAY_SIZE(area_no); n++) { + if (normalize_v3_v3(r_area_no, area_no[n]) != 0.0f) { + break; + } + } } static void calc_sculpt_plane(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float an[3], float fc[3]) -- cgit v1.2.3 From fe39ebea12aa7d16e3b01b44ba2faa8884ad2585 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 19 Apr 2015 17:52:35 +1000 Subject: Cleanup: move project code into util function --- source/blender/editors/sculpt_paint/sculpt.c | 64 ++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 17 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 1f57059cd64..a08ea2ba60e 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -303,6 +303,47 @@ static void sculpt_orig_vert_data_update(SculptOrigVertData *orig_data, } } +/** \name SculptProjectVector + * + * Fast-path for #project_plane_v3_v3v3 + * + * \{ */ + +typedef struct SculptProjectVector { + float plane[3]; + float len_sq; + float len_sq_inv_neg; + bool is_valid; + +} SculptProjectVector; + +/** + * \param plane Direction, can be any length. + */ +static void sculpt_project_v3_cache_init( + SculptProjectVector *spvc, const float plane[3]) +{ + copy_v3_v3(spvc->plane, plane); + spvc->len_sq = len_squared_v3(spvc->plane); + spvc->is_valid = (spvc->len_sq > FLT_EPSILON); + spvc->len_sq_inv_neg = (spvc->is_valid) ? -1.0f / spvc->len_sq : 0.0f; +} + +static void sculpt_project_v3( + const SculptProjectVector *spvc, const float vec[3], + float r_vec[3]) +{ +#if 0 + project_plane_v3_v3v3(r_vec, vec, spvc->plane); +#else + /* inline the projection, cache `-1.0 / dot_v3_v3(v_proj, v_proj)` */ + madd_v3_v3fl(r_vec, spvc->plane, dot_v3v3(vec, spvc->plane) * spvc->len_sq_inv_neg); +#endif +} + +/** \} */ + + /**********************************************************************/ /* Returns true if the stroke will use dynamic topology, false @@ -1682,15 +1723,7 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod float brush_alpha; int n; - /* vars for handling projection when calculating the pinch vector. - * Use surface normal for 'pinch_proj', so the vertices are pinched towards a line instead of a single point. - * Without this we get a 'flat' surface surrounding the pinch */ - const float *pinch_proj = ss->cache->sculpt_normal_symm; - const float pinch_proj_len_sq = len_squared_v3(pinch_proj); - const bool do_pinch_proj = (pinch_proj_len_sq > FLT_EPSILON); - /* simplifies projection calc below */ - const float pinch_proj_len_sq_inv_neg = do_pinch_proj ? -1.0f / pinch_proj_len_sq : 0.0f; - + SculptProjectVector spvc; /* offset with as much as possible factored in already */ mul_v3_v3fl(offset, ss->cache->sculpt_normal_symm, ss->cache->radius); @@ -1708,6 +1741,10 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod if (brush->sculpt_tool == SCULPT_TOOL_BLOB) flippedbstrength *= -1.0f; + /* Use surface normal for 'spvc', so the vertices are pinched towards a line instead of a single point. + * Without this we get a 'flat' surface surrounding the pinch */ + sculpt_project_v3_cache_init(&spvc, ss->cache->sculpt_normal_symm); + /* threaded loop over nodes */ #pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) for (n = 0; n < totnode; n++) { @@ -1732,14 +1769,7 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod sub_v3_v3v3(val1, test.location, vd.co); mul_v3_fl(val1, fade * flippedbstrength); - if (do_pinch_proj) { -#if 0 - project_plane_v3_v3v3(val1, val1, v_proj); -#else - /* inline the projection, cache `-1.0 / dot_v3_v3(v_proj, v_proj)` */ - madd_v3_v3fl(val1, pinch_proj, dot_v3v3(val1, pinch_proj) * pinch_proj_len_sq_inv_neg); -#endif - } + sculpt_project_v3(&spvc, val1, val1); /* then we draw */ mul_v3_v3fl(val2, offset, fade); -- cgit v1.2.3 From fb6a0d24e1078574135ca1d083c2b933191d9bda Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 19 Apr 2015 18:22:25 +1000 Subject: Dyntopo: support for original normal access Rename calc_flatten_center to calc_area_center, since theres no 'flatten' spesific logic there. Also refactor calc_area_center, calc_area_normal, calc_area_normal_and_center so they're next to eachother - they're almost the same, having them scattered about isn't helpful. --- source/blender/editors/sculpt_paint/sculpt.c | 1037 ++++++++++++++------------ 1 file changed, 549 insertions(+), 488 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index a08ea2ba60e..4e3d03f916f 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -729,6 +729,429 @@ static float calc_symmetry_feather(Sculpt *sd, StrokeCache *cache) } } +/** \name Calculate Normal and Center + * + * Calculate geometry surrounding the brush center. + * (optionally using original coordinates). + * + * Functions are: + * - #calc_area_center + * - #calc_area_normal + * - #calc_area_normal_and_center + * + * \note These are all _very_ similar, when changing one, check others. + * \{ */ + +static void calc_area_center( + Sculpt *sd, Object *ob, + PBVHNode **nodes, int totnode, + float r_area_co[3]) +{ + SculptSession *ss = ob->sculpt; + int n; + + /* 0=towards view, 1=flipped */ + float area_co[2][3] = {{0.0f}}; + + int count[2] = {0}; + + (void)sd; /* unused w/o openmp */ + +#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) + for (n = 0; n < totnode; n++) { + PBVHVertexIter vd; + SculptBrushTest test; + SculptUndoNode *unode; + float private_co[2][3] = {{0.0f}}; + int private_count[2] = {0}; + bool use_original; + + unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS); + 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) */ + if (use_original && unode->bm_entry) { + float (*orco_coords)[3]; + int (*orco_tris)[3]; + int orco_tris_num; + int i; + + BKE_pbvh_node_get_bm_orco_data( + nodes[n], + &orco_tris, &orco_tris_num, &orco_coords); + + for (i = 0; i < orco_tris_num; i++) { + const float *co_tri[3] = { + orco_coords[orco_tris[i][0]], + orco_coords[orco_tris[i][1]], + orco_coords[orco_tris[i][2]], + }; + float co[3]; + + closest_on_tri_to_point_v3(co, test.location, UNPACK3(co_tri)); + + if (sculpt_brush_test_fast(&test, co)) { + float no[3]; + int flip_index; + + cross_tri_v3(no, UNPACK3(co_tri)); + + flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f); + add_v3_v3(private_co[flip_index], co); + private_count[flip_index] += 1; + } + } + } + else { + BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) + { + const float *co; + + if (use_original) { + co = unode->co[vd.i]; + } + else { + co = vd.co; + } + + if (sculpt_brush_test_fast(&test, co)) { + float no_buf[3]; + const float *no; + int flip_index; + + if (use_original) { + normal_short_to_float_v3(no_buf, unode->no[vd.i]); + no = no_buf; + } + else { + 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); + add_v3_v3(private_co[flip_index], co); + private_count[flip_index] += 1; + } + } + BKE_pbvh_vertex_iter_end; + } + +#pragma omp critical + { + /* for flatten center */ + add_v3_v3(area_co[0], private_co[0]); + add_v3_v3(area_co[1], private_co[1]); + + /* weights */ + count[0] += private_count[0]; + count[1] += private_count[1]; + } + } + + /* for flatten center */ + for (n = 0; n < ARRAY_SIZE(area_co); n++) { + if (count[n] != 0) { + mul_v3_v3fl(r_area_co, area_co[n], 1.0f / count[n]); + break; + } + } + if (n == 2) { + zero_v3(r_area_co); + } +} + + +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); + SculptSession *ss = ob->sculpt; + int n; + + /* 0=towards view, 1=flipped */ + float area_no[2][3] = {{0.0f}}; + + int count[2] = {0}; + + /* Grab brush requires to test on original data (see T25371) */ + bool original; + + original = (brush->sculpt_tool == SCULPT_TOOL_GRAB) ? true : ss->cache->original; + /* In general the original coords are not available with dynamic + * topology + * + * Mask tool could not use undo nodes to get coordinates from + * since the coordinates are not stored in those nodes. + * And mask tool is not gonna to modify vertex coordinates, + * so we don't actually need to use modified coords. + */ + if (brush->sculpt_tool == SCULPT_TOOL_MASK) { + original = false; + } + +#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) + for (n = 0; n < totnode; n++) { + PBVHVertexIter vd; + SculptBrushTest test; + SculptUndoNode *unode; + float private_no[2][3] = {{0.0f}}; + int private_count[2] = {0}; + bool use_original; + + unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS); + sculpt_brush_test_init(ss, &test); + + use_original = (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) */ + if (use_original && unode->bm_entry) { + float (*orco_coords)[3]; + int (*orco_tris)[3]; + int orco_tris_num; + int i; + + BKE_pbvh_node_get_bm_orco_data( + nodes[n], + &orco_tris, &orco_tris_num, &orco_coords); + + for (i = 0; i < orco_tris_num; i++) { + const float *co_tri[3] = { + orco_coords[orco_tris[i][0]], + orco_coords[orco_tris[i][1]], + orco_coords[orco_tris[i][2]], + }; + float co[3]; + + closest_on_tri_to_point_v3(co, test.location, UNPACK3(co_tri)); + + if (sculpt_brush_test_fast(&test, co)) { + float no[3]; + int flip_index; + + normal_tri_v3(no, UNPACK3(co_tri)); + + flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f); + add_v3_v3(private_no[flip_index], no); + private_count[flip_index] += 1; + } + } + } + else { + BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) + { + const float *co; + + if (use_original) { + co = unode->co[vd.i]; + } + else { + co = vd.co; + } + + if (sculpt_brush_test_fast(&test, co)) { + float no_buf[3]; + const float *no; + int flip_index; + + if (use_original) { + normal_short_to_float_v3(no_buf, unode->no[vd.i]); + no = no_buf; + } + else { + 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); + add_v3_v3(private_no[flip_index], no); + private_count[flip_index] += 1; + } + } + BKE_pbvh_vertex_iter_end; + } + +#pragma omp critical + { + /* for area normal */ + add_v3_v3(area_no[0], private_no[0]); + add_v3_v3(area_no[1], private_no[1]); + + /* weights */ + count[0] += private_count[0]; + count[1] += private_count[1]; + } + } + + /* for area normal */ + for (n = 0; n < ARRAY_SIZE(area_no); n++) { + if (normalize_v3_v3(r_area_no, area_no[n]) != 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( + Sculpt *sd, Object *ob, + PBVHNode **nodes, int totnode, + float r_area_no[3], float r_area_co[3]) +{ + SculptSession *ss = ob->sculpt; + int n; + + /* 0=towards view, 1=flipped */ + float area_co[2][3] = {{0.0f}}; + float area_no[2][3] = {{0.0f}}; + + int count[2] = {0}; + + (void)sd; /* unused w/o openmp */ + +#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) + for (n = 0; n < totnode; n++) { + PBVHVertexIter vd; + SculptBrushTest test; + SculptUndoNode *unode; + float private_co[2][3] = {{0.0f}}; + float private_no[2][3] = {{0.0f}}; + int private_count[2] = {0}; + bool use_original; + + unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS); + 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) */ + if (use_original && unode->bm_entry) { + float (*orco_coords)[3]; + int (*orco_tris)[3]; + int orco_tris_num; + int i; + + BKE_pbvh_node_get_bm_orco_data( + nodes[n], + &orco_tris, &orco_tris_num, &orco_coords); + + for (i = 0; i < orco_tris_num; i++) { + const float *co_tri[3] = { + orco_coords[orco_tris[i][0]], + orco_coords[orco_tris[i][1]], + orco_coords[orco_tris[i][2]], + }; + float co[3]; + + closest_on_tri_to_point_v3(co, test.location, UNPACK3(co_tri)); + + if (sculpt_brush_test_fast(&test, co)) { + float no[3]; + int flip_index; + + normal_tri_v3(no, UNPACK3(co_tri)); + + flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f); + add_v3_v3(private_co[flip_index], co); + add_v3_v3(private_no[flip_index], no); + private_count[flip_index] += 1; + } + } + } + else { + BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) + { + const float *co; + + if (use_original) { + co = unode->co[vd.i]; + } + else { + co = vd.co; + } + + if (sculpt_brush_test_fast(&test, co)) { + float no_buf[3]; + const float *no; + int flip_index; + + if (use_original) { + normal_short_to_float_v3(no_buf, unode->no[vd.i]); + no = no_buf; + } + else { + 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); + add_v3_v3(private_co[flip_index], co); + add_v3_v3(private_no[flip_index], no); + private_count[flip_index] += 1; + } + } + BKE_pbvh_vertex_iter_end; + } + +#pragma omp critical + { + /* for flatten center */ + add_v3_v3(area_co[0], private_co[0]); + add_v3_v3(area_co[1], private_co[1]); + + /* for area normal */ + add_v3_v3(area_no[0], private_no[0]); + add_v3_v3(area_no[1], private_no[1]); + + /* weights */ + count[0] += private_count[0]; + count[1] += private_count[1]; + } + } + + /* for flatten center */ + for (n = 0; n < ARRAY_SIZE(area_co); n++) { + if (count[n] != 0) { + mul_v3_v3fl(r_area_co, area_co[n], 1.0f / count[n]); + break; + } + } + if (n == 2) { + zero_v3(r_area_co); + } + + /* for area normal */ + for (n = 0; n < ARRAY_SIZE(area_no); n++) { + if (normalize_v3_v3(r_area_no, area_no[n]) != 0.0f) { + break; + } + } +} + +/** \} */ + + /* Return modified brush strength. Includes the direction of the brush, positive * values pull vertices, negative values push. Uses tablet pressure and a * special multiplier found experimentally to scale the strength factor. */ @@ -928,123 +1351,30 @@ static bool sculpt_search_sphere_cb(PBVHNode *node, void *data_v) if (bb_min[i] > center[i]) nearest[i] = bb_min[i]; else if (bb_max[i] < center[i]) - nearest[i] = bb_max[i]; - else - nearest[i] = center[i]; - } - - sub_v3_v3v3(t, center, nearest); - - return len_squared_v3(t) < data->radius_squared; -} - -/* Handles clipping against a mirror modifier and SCULPT_LOCK axis flags */ -static void sculpt_clip(Sculpt *sd, SculptSession *ss, float co[3], const float val[3]) -{ - int i; - - for (i = 0; i < 3; ++i) { - if (sd->flags & (SCULPT_LOCK_X << i)) - continue; - - if ((ss->cache->flag & (CLIP_X << i)) && (fabsf(co[i]) <= ss->cache->clip_tolerance[i])) - co[i] = 0.0f; - else - co[i] = val[i]; - } -} - -static void add_norm_if(float view_vec[3], float out[3], float out_flip[3], float fno[3]) -{ - if ((dot_v3v3(view_vec, fno)) > 0) { - add_v3_v3(out, fno); - } - else { - add_v3_v3(out_flip, fno); /* out_flip is used when out is {0,0,0} */ - } -} - -static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nodes, int totnode) -{ - float out_flip[3] = {0.0f, 0.0f, 0.0f}; - - SculptSession *ss = ob->sculpt; - const Brush *brush = BKE_paint_brush(&sd->paint); - int n; - bool original; - - /* Grab brush requires to test on original data (see r33888 and - * bug #25371) */ - original = (BKE_paint_brush(&sd->paint)->sculpt_tool == SCULPT_TOOL_GRAB ? - true : ss->cache->original); - - /* In general the original coords are not available with dynamic - * topology - * - * Mask tool could not use undo nodes to get coordinates from - * since the coordinates are not stored in those odes. - * And mask tool is not gonna to modify vertex coordinates, - * so we don't actually need to use modified coords. - */ - if (ss->bm || brush->sculpt_tool == SCULPT_TOOL_MASK) - original = false; - - (void)sd; /* unused w/o openmp */ - - zero_v3(an); - -#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) - for (n = 0; n < totnode; n++) { - PBVHVertexIter vd; - SculptBrushTest test; - SculptUndoNode *unode; - float private_an[3] = {0.0f, 0.0f, 0.0f}; - float private_out_flip[3] = {0.0f, 0.0f, 0.0f}; - - unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS); - sculpt_brush_test_init(ss, &test); + nearest[i] = bb_max[i]; + else + nearest[i] = center[i]; + } + + sub_v3_v3v3(t, center, nearest); - if (original) { - BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) - { - if (sculpt_brush_test_fast(&test, unode->co[vd.i])) { - float fno[3]; + return len_squared_v3(t) < data->radius_squared; +} - normal_short_to_float_v3(fno, unode->no[vd.i]); - add_norm_if(ss->cache->view_normal, private_an, private_out_flip, fno); - } - } - BKE_pbvh_vertex_iter_end; - } - else { - BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) - { - if (sculpt_brush_test_fast(&test, vd.co)) { - if (vd.no) { - float fno[3]; +/* Handles clipping against a mirror modifier and SCULPT_LOCK axis flags */ +static void sculpt_clip(Sculpt *sd, SculptSession *ss, float co[3], const float val[3]) +{ + int i; - normal_short_to_float_v3(fno, vd.no); - add_norm_if(ss->cache->view_normal, private_an, private_out_flip, fno); - } - else { - add_norm_if(ss->cache->view_normal, private_an, private_out_flip, vd.fno); - } - } - } - BKE_pbvh_vertex_iter_end; - } + for (i = 0; i < 3; ++i) { + if (sd->flags & (SCULPT_LOCK_X << i)) + continue; -#pragma omp critical - { - add_v3_v3(an, private_an); - add_v3_v3(out_flip, private_out_flip); - } + if ((ss->cache->flag & (CLIP_X << i)) && (fabsf(co[i]) <= ss->cache->clip_tolerance[i])) + co[i] = 0.0f; + else + co[i] = val[i]; } - - if (is_zero_v3(an)) - copy_v3_v3(an, out_flip); - - normalize_v3(an); } /* Calculate primary direction of movement for many brushes */ @@ -1079,7 +1409,7 @@ static void calc_sculpt_normal(Sculpt *sd, Object *ob, break; case SCULPT_DISP_DIR_AREA: - calc_area_normal(sd, ob, an, nodes, totnode); + calc_area_normal(sd, ob, nodes, totnode, an); break; default: @@ -2014,422 +2344,153 @@ static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod Brush *brush = BKE_paint_brush(&sd->paint); float bstrength = ss->cache->bstrength; int n; - static const int flip[8] = { 1, -1, -1, 1, -1, 1, 1, -1 }; - float angle = ss->cache->vertex_rotation * flip[ss->cache->mirror_symmetry_pass]; - -#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) - for (n = 0; n < totnode; n++) { - PBVHVertexIter vd; - SculptBrushTest test; - SculptOrigVertData orig_data; - float (*proxy)[3]; - - sculpt_orig_vert_data_init(&orig_data, ob, nodes[n]); - - proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; - - sculpt_brush_test_init(ss, &test); - - BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) - { - sculpt_orig_vert_data_update(&orig_data, &vd); - - if (sculpt_brush_test(&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); - - sub_v3_v3v3(vec, orig_data.co, ss->cache->location); - axis_angle_normalized_to_mat3(rot, ss->cache->sculpt_normal_symm, angle * fade); - mul_v3_m3v3(proxy[vd.i], rot, vec); - add_v3_v3(proxy[vd.i], ss->cache->location); - sub_v3_v3(proxy[vd.i], orig_data.co); - - if (vd.mvert) - vd.mvert->flag |= ME_VERT_PBVH_UPDATE; - } - } - BKE_pbvh_vertex_iter_end; - } -} - -static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) -{ - SculptSession *ss = ob->sculpt; - Brush *brush = BKE_paint_brush(&sd->paint); - float bstrength = ss->cache->bstrength; - float offset[3]; - float lim = brush->height; - int n; - - if (bstrength < 0) - lim = -lim; - - mul_v3_v3v3(offset, ss->cache->scale, ss->cache->sculpt_normal_symm); - -#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) - for (n = 0; n < totnode; n++) { - PBVHVertexIter vd; - SculptBrushTest test; - SculptOrigVertData orig_data; - float *layer_disp; - /* XXX: layer brush needs conversion to proxy but its more complicated */ - /* proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; */ - - sculpt_orig_vert_data_init(&orig_data, ob, nodes[n]); - -#pragma omp critical - { - layer_disp = BKE_pbvh_node_layer_disp_get(ss->pbvh, nodes[n]); - } - - sculpt_brush_test_init(ss, &test); - - BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) - { - sculpt_orig_vert_data_update(&orig_data, &vd); - - if (sculpt_brush_test(&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); - float *disp = &layer_disp[vd.i]; - float val[3]; - - *disp += fade; - - /* Don't let the displacement go past the limit */ - if ((lim < 0 && *disp < lim) || (lim >= 0 && *disp > lim)) - *disp = lim; - - mul_v3_v3fl(val, offset, *disp); - - if (!ss->multires && !ss->bm && ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) { - int index = vd.vert_indices[vd.i]; - - /* persistent base */ - add_v3_v3(val, ss->layer_co[index]); - } - else { - add_v3_v3(val, orig_data.co); - } - - sculpt_clip(sd, ss, vd.co, val); - - if (vd.mvert) - vd.mvert->flag |= ME_VERT_PBVH_UPDATE; - } - } - BKE_pbvh_vertex_iter_end; - } -} - -static void do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) -{ - SculptSession *ss = ob->sculpt; - Brush *brush = BKE_paint_brush(&sd->paint); - float bstrength = ss->cache->bstrength; - int n; - -#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) - for (n = 0; n < totnode; n++) { - PBVHVertexIter vd; - SculptBrushTest test; - float (*proxy)[3]; - - proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; - - sculpt_brush_test_init(ss, &test); - - BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) - { - if (sculpt_brush_test(&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); - float val[3]; - - if (vd.fno) copy_v3_v3(val, vd.fno); - else normal_short_to_float_v3(val, vd.no); - - mul_v3_fl(val, fade * ss->cache->radius); - mul_v3_v3v3(proxy[vd.i], val, ss->cache->scale); - - if (vd.mvert) - vd.mvert->flag |= ME_VERT_PBVH_UPDATE; - } - } - BKE_pbvh_vertex_iter_end; - } -} - -static void calc_flatten_center( - Sculpt *sd, Object *ob, - PBVHNode **nodes, int totnode, - float r_area_co[3]) -{ - SculptSession *ss = ob->sculpt; - int n; - - /* 0=towards view, 1=flipped */ - float area_co[2][3] = {{0.0f}}; - - int count[2] = {0}; - - (void)sd; /* unused w/o openmp */ - -#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) - for (n = 0; n < totnode; n++) { - PBVHVertexIter vd; - SculptBrushTest test; - SculptUndoNode *unode; - float private_co[2][3] = {{0.0f}}; - int private_count[2] = {0}; - bool use_original; - - unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS); - 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) */ - if (use_original && unode->bm_entry) { - float (*orco_coords)[3]; - int (*orco_tris)[3]; - int orco_tris_num; - int i; - - BKE_pbvh_node_get_bm_orco_data( - nodes[n], - &orco_tris, &orco_tris_num, &orco_coords); - - for (i = 0; i < orco_tris_num; i++) { - const float *co_tri[3] = { - orco_coords[orco_tris[i][0]], - orco_coords[orco_tris[i][1]], - orco_coords[orco_tris[i][2]], - }; - float co[3]; - - closest_on_tri_to_point_v3(co, test.location, UNPACK3(co_tri)); - - if (sculpt_brush_test_fast(&test, co)) { - float no[3]; - int flip_index; - - cross_tri_v3(no, UNPACK3(co_tri)); - - flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f); - add_v3_v3(private_co[flip_index], co); - private_count[flip_index] += 1; - } - } - } - else { - BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) - { - const float *co; + static const int flip[8] = { 1, -1, -1, 1, -1, 1, 1, -1 }; + float angle = ss->cache->vertex_rotation * flip[ss->cache->mirror_symmetry_pass]; - if (use_original) { - co = unode->co[vd.i]; - } - else { - co = vd.co; - } +#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) + for (n = 0; n < totnode; n++) { + PBVHVertexIter vd; + SculptBrushTest test; + SculptOrigVertData orig_data; + float (*proxy)[3]; - if (sculpt_brush_test_fast(&test, co)) { - float no_buf[3]; - const float *no; - int flip_index; + sculpt_orig_vert_data_init(&orig_data, ob, nodes[n]); - if (use_original) { - normal_short_to_float_v3(no_buf, unode->no[vd.i]); - no = no_buf; - } - else { - if (vd.no) { - normal_short_to_float_v3(no_buf, vd.no); - no = no_buf; - } - else { - no = vd.fno; - } - } + proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; - flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f); - add_v3_v3(private_co[flip_index], co); - private_count[flip_index] += 1; - } - } - BKE_pbvh_vertex_iter_end; - } + sculpt_brush_test_init(ss, &test); -#pragma omp critical + BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { - /* for flatten center */ - add_v3_v3(area_co[0], private_co[0]); - add_v3_v3(area_co[1], private_co[1]); + sculpt_orig_vert_data_update(&orig_data, &vd); - /* weights */ - count[0] += private_count[0]; - count[1] += private_count[1]; - } - } + if (sculpt_brush_test(&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); - /* for flatten center */ - for (n = 0; n < ARRAY_SIZE(area_co); n++) { - if (count[n] != 0) { - mul_v3_v3fl(r_area_co, area_co[n], 1.0f / count[n]); - break; + sub_v3_v3v3(vec, orig_data.co, ss->cache->location); + axis_angle_normalized_to_mat3(rot, ss->cache->sculpt_normal_symm, angle * fade); + mul_v3_m3v3(proxy[vd.i], rot, vec); + add_v3_v3(proxy[vd.i], ss->cache->location); + sub_v3_v3(proxy[vd.i], orig_data.co); + + if (vd.mvert) + vd.mvert->flag |= ME_VERT_PBVH_UPDATE; + } } - } - if (n == 2) { - zero_v3(r_area_co); + BKE_pbvh_vertex_iter_end; } } -/* 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_flatten_center( - Sculpt *sd, Object *ob, - PBVHNode **nodes, int totnode, - float r_area_no[3], float r_area_co[3]) +static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) { SculptSession *ss = ob->sculpt; + Brush *brush = BKE_paint_brush(&sd->paint); + float bstrength = ss->cache->bstrength; + float offset[3]; + float lim = brush->height; int n; - /* 0=towards view, 1=flipped */ - float area_co[2][3] = {{0.0f}}; - float area_no[2][3] = {{0.0f}}; - - int count[2] = {0}; + if (bstrength < 0) + lim = -lim; - (void)sd; /* unused w/o openmp */ + mul_v3_v3v3(offset, ss->cache->scale, ss->cache->sculpt_normal_symm); #pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) for (n = 0; n < totnode; n++) { PBVHVertexIter vd; SculptBrushTest test; - SculptUndoNode *unode; - float private_co[2][3] = {{0.0f}}; - float private_no[2][3] = {{0.0f}}; - int private_count[2] = {0}; - bool use_original; + SculptOrigVertData orig_data; + float *layer_disp; + /* XXX: layer brush needs conversion to proxy but its more complicated */ + /* proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; */ + + sculpt_orig_vert_data_init(&orig_data, ob, nodes[n]); - unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS); +#pragma omp critical + { + layer_disp = BKE_pbvh_node_layer_disp_get(ss->pbvh, nodes[n]); + } + 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) */ - if (use_original && unode->bm_entry) { - float (*orco_coords)[3]; - int (*orco_tris)[3]; - int orco_tris_num; - int i; - - BKE_pbvh_node_get_bm_orco_data( - nodes[n], - &orco_tris, &orco_tris_num, &orco_coords); + BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) + { + sculpt_orig_vert_data_update(&orig_data, &vd); - for (i = 0; i < orco_tris_num; i++) { - const float *co_tri[3] = { - orco_coords[orco_tris[i][0]], - orco_coords[orco_tris[i][1]], - orco_coords[orco_tris[i][2]], - }; - float co[3]; + if (sculpt_brush_test(&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); + float *disp = &layer_disp[vd.i]; + float val[3]; - closest_on_tri_to_point_v3(co, test.location, UNPACK3(co_tri)); + *disp += fade; - if (sculpt_brush_test_fast(&test, co)) { - float no[3]; - int flip_index; + /* Don't let the displacement go past the limit */ + if ((lim < 0 && *disp < lim) || (lim >= 0 && *disp > lim)) + *disp = lim; - normal_tri_v3(no, UNPACK3(co_tri)); + mul_v3_v3fl(val, offset, *disp); - flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f); - add_v3_v3(private_co[flip_index], co); - add_v3_v3(private_no[flip_index], no); - private_count[flip_index] += 1; - } - } - } - else { - BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) - { - const float *co; + if (!ss->multires && !ss->bm && ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) { + int index = vd.vert_indices[vd.i]; - if (use_original) { - co = unode->co[vd.i]; + /* persistent base */ + add_v3_v3(val, ss->layer_co[index]); } else { - co = vd.co; + add_v3_v3(val, orig_data.co); } - if (sculpt_brush_test_fast(&test, co)) { - float no_buf[3]; - const float *no; - int flip_index; - - if (use_original) { - normal_short_to_float_v3(no_buf, unode->no[vd.i]); - no = no_buf; - } - else { - if (vd.no) { - normal_short_to_float_v3(no_buf, vd.no); - no = no_buf; - } - else { - no = vd.fno; - } - } + sculpt_clip(sd, ss, vd.co, val); - flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f); - add_v3_v3(private_co[flip_index], co); - add_v3_v3(private_no[flip_index], no); - private_count[flip_index] += 1; - } + if (vd.mvert) + vd.mvert->flag |= ME_VERT_PBVH_UPDATE; } - BKE_pbvh_vertex_iter_end; } + BKE_pbvh_vertex_iter_end; + } +} -#pragma omp critical - { - /* for flatten center */ - add_v3_v3(area_co[0], private_co[0]); - add_v3_v3(area_co[1], private_co[1]); +static void do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +{ + SculptSession *ss = ob->sculpt; + Brush *brush = BKE_paint_brush(&sd->paint); + float bstrength = ss->cache->bstrength; + int n; - /* for area normal */ - add_v3_v3(area_no[0], private_no[0]); - add_v3_v3(area_no[1], private_no[1]); +#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) + for (n = 0; n < totnode; n++) { + PBVHVertexIter vd; + SculptBrushTest test; + float (*proxy)[3]; - /* weights */ - count[0] += private_count[0]; - count[1] += private_count[1]; - } - } + proxy = BKE_pbvh_node_add_proxy(ss->pbvh, nodes[n])->co; - /* for flatten center */ - for (n = 0; n < ARRAY_SIZE(area_co); n++) { - if (count[n] != 0) { - mul_v3_v3fl(r_area_co, area_co[n], 1.0f / count[n]); - break; - } - } - if (n == 2) { - zero_v3(r_area_co); - } + sculpt_brush_test_init(ss, &test); - /* for area normal */ - for (n = 0; n < ARRAY_SIZE(area_no); n++) { - if (normalize_v3_v3(r_area_no, area_no[n]) != 0.0f) { - break; + BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) + { + if (sculpt_brush_test(&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); + float val[3]; + + if (vd.fno) copy_v3_v3(val, vd.fno); + else normal_short_to_float_v3(val, vd.no); + + mul_v3_fl(val, fade * ss->cache->radius); + mul_v3_v3v3(proxy[vd.i], val, ss->cache->scale); + + if (vd.mvert) + vd.mvert->flag |= ME_VERT_PBVH_UPDATE; + } } + BKE_pbvh_vertex_iter_end; } } @@ -2466,7 +2527,7 @@ static void calc_sculpt_plane(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn break; case SCULPT_DISP_DIR_AREA: - calc_area_normal_and_flatten_center(sd, ob, nodes, totnode, an, fc); + calc_area_normal_and_center(sd, ob, nodes, totnode, an, fc); break; default: @@ -2476,7 +2537,7 @@ static void calc_sculpt_plane(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn /* for flatten center */ /* flatten center has not been calculated yet if we are not using the area normal */ if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA) - calc_flatten_center(sd, ob, nodes, totnode, fc); + calc_area_center(sd, ob, nodes, totnode, fc); /* for area normal */ copy_v3_v3(ss->cache->sculpt_normal, an); @@ -2722,7 +2783,7 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t calc_sculpt_plane(sd, ob, nodes, totnode, sn, fc); if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA || (brush->flag & BRUSH_ORIGINAL_NORMAL)) - calc_area_normal(sd, ob, an, nodes, totnode); + calc_area_normal(sd, ob, nodes, totnode, an); else copy_v3_v3(an, sn); -- cgit v1.2.3 From ac73fe5fe0443dd3b0f237eb37523fd9c79dff4e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 19 Apr 2015 18:36:53 +1000 Subject: Cleanup: use meaningful names re: (fc, an, sn) --- source/blender/editors/sculpt_paint/sculpt.c | 154 +++++++++++++-------------- 1 file changed, 73 insertions(+), 81 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 4e3d03f916f..7ab80e8d791 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -635,7 +635,7 @@ static float frontface(Brush *br, const float sculpt_normal[3], #if 0 -static bool sculpt_brush_test_cyl(SculptBrushTest *test, float co[3], float location[3], float an[3]) +static bool sculpt_brush_test_cyl(SculptBrushTest *test, float co[3], float location[3], const float area_no[3]) { if (sculpt_brush_test_fast(test, co)) { float t1[3], t2[3], t3[3], dist; @@ -643,7 +643,7 @@ static bool sculpt_brush_test_cyl(SculptBrushTest *test, float co[3], float loca sub_v3_v3v3(t1, location, co); sub_v3_v3v3(t2, x2, location); - cross_v3_v3v3(t3, an, t1); + cross_v3_v3v3(t3, area_no, t1); dist = len_v3(t3) / len_v3(t2); @@ -1378,38 +1378,33 @@ static void sculpt_clip(Sculpt *sd, SculptSession *ss, float co[3], const float } /* Calculate primary direction of movement for many brushes */ -static void calc_sculpt_normal(Sculpt *sd, Object *ob, - PBVHNode **nodes, int totnode, - float an[3]) +static void calc_sculpt_normal( + Sculpt *sd, Object *ob, + PBVHNode **nodes, int totnode, + float r_area_no[3]) { const Brush *brush = BKE_paint_brush(&sd->paint); const SculptSession *ss = ob->sculpt; switch (brush->sculpt_plane) { case SCULPT_DISP_DIR_VIEW: - copy_v3_v3(an, ss->cache->true_view_normal); + copy_v3_v3(r_area_no, ss->cache->true_view_normal); break; case SCULPT_DISP_DIR_X: - an[1] = 0.0; - an[2] = 0.0; - an[0] = 1.0; + ARRAY_SET_ITEMS(r_area_no, 1, 0, 0); break; case SCULPT_DISP_DIR_Y: - an[0] = 0.0; - an[2] = 0.0; - an[1] = 1.0; + ARRAY_SET_ITEMS(r_area_no, 0, 1, 0); break; case SCULPT_DISP_DIR_Z: - an[0] = 0.0; - an[1] = 0.0; - an[2] = 1.0; + ARRAY_SET_ITEMS(r_area_no, 0, 0, 1); break; case SCULPT_DISP_DIR_AREA: - calc_area_normal(sd, ob, nodes, totnode, an); + calc_area_normal(sd, ob, nodes, totnode, r_area_no); break; default: @@ -2494,7 +2489,10 @@ static void do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno } } -static void calc_sculpt_plane(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float an[3], float fc[3]) +static void calc_sculpt_plane( + Sculpt *sd, Object *ob, + PBVHNode **nodes, int totnode, + float r_area_no[3], float r_area_co[3]) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -2505,29 +2503,23 @@ static void calc_sculpt_plane(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn { switch (brush->sculpt_plane) { case SCULPT_DISP_DIR_VIEW: - copy_v3_v3(an, ss->cache->true_view_normal); + copy_v3_v3(r_area_no, ss->cache->true_view_normal); break; case SCULPT_DISP_DIR_X: - an[1] = 0.0; - an[2] = 0.0; - an[0] = 1.0; + ARRAY_SET_ITEMS(r_area_no, 1, 0, 0); break; case SCULPT_DISP_DIR_Y: - an[0] = 0.0; - an[2] = 0.0; - an[1] = 1.0; + ARRAY_SET_ITEMS(r_area_no, 0, 1, 0); break; case SCULPT_DISP_DIR_Z: - an[0] = 0.0; - an[1] = 0.0; - an[2] = 1.0; + ARRAY_SET_ITEMS(r_area_no, 0, 0, 1); break; case SCULPT_DISP_DIR_AREA: - calc_area_normal_and_center(sd, ob, nodes, totnode, an, fc); + calc_area_normal_and_center(sd, ob, nodes, totnode, r_area_no, r_area_co); break; default: @@ -2537,32 +2529,32 @@ static void calc_sculpt_plane(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn /* for flatten center */ /* flatten center has not been calculated yet if we are not using the area normal */ if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA) - calc_area_center(sd, ob, nodes, totnode, fc); + calc_area_center(sd, ob, nodes, totnode, r_area_co); /* for area normal */ - copy_v3_v3(ss->cache->sculpt_normal, an); + copy_v3_v3(ss->cache->sculpt_normal, r_area_no); /* for flatten center */ - copy_v3_v3(ss->cache->last_center, fc); + copy_v3_v3(ss->cache->last_center, r_area_co); } else { /* for area normal */ - copy_v3_v3(an, ss->cache->sculpt_normal); + copy_v3_v3(r_area_no, ss->cache->sculpt_normal); /* for flatten center */ - copy_v3_v3(fc, ss->cache->last_center); + copy_v3_v3(r_area_co, ss->cache->last_center); /* for area normal */ - flip_v3(an, ss->cache->mirror_symmetry_pass); + flip_v3(r_area_no, ss->cache->mirror_symmetry_pass); /* for flatten center */ - flip_v3(fc, ss->cache->mirror_symmetry_pass); + flip_v3(r_area_co, ss->cache->mirror_symmetry_pass); /* for area normal */ - mul_m4_v3(ss->cache->symm_rot_mat, an); + mul_m4_v3(ss->cache->symm_rot_mat, r_area_no); /* for flatten center */ - mul_m4_v3(ss->cache->symm_rot_mat, fc); + mul_m4_v3(ss->cache->symm_rot_mat, r_area_co); } } @@ -2626,8 +2618,8 @@ static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno float bstrength = ss->cache->bstrength; const float radius = ss->cache->radius; - float an[3]; - float fc[3]; + float area_no[3]; + float area_co[3]; float offset = get_offset(sd, ss); @@ -2637,13 +2629,13 @@ static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno float temp[3]; - calc_sculpt_plane(sd, ob, nodes, totnode, an, fc); + calc_sculpt_plane(sd, ob, nodes, totnode, area_no, area_co); displace = radius * offset; - mul_v3_v3v3(temp, an, ss->cache->scale); + mul_v3_v3v3(temp, area_no, ss->cache->scale); mul_v3_fl(temp, displace); - add_v3_v3(fc, temp); + add_v3_v3(area_co, temp); #pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) for (n = 0; n < totnode; n++) { @@ -2661,7 +2653,7 @@ static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno float intr[3]; float val[3]; - point_plane_project(intr, vd.co, an, fc); + point_plane_project(intr, vd.co, area_no, area_co); sub_v3_v3v3(val, intr, vd.co); @@ -2691,8 +2683,8 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) float displace; - float an[3]; - float fc[3]; + float area_no[3]; + float area_co[3]; int n; @@ -2700,7 +2692,7 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) bool flip; - calc_sculpt_plane(sd, ob, nodes, totnode, an, fc); + calc_sculpt_plane(sd, ob, nodes, totnode, area_no, area_co); flip = bstrength < 0; @@ -2711,11 +2703,11 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) displace = radius * (0.25f + offset); - mul_v3_v3v3(temp, an, ss->cache->scale); + mul_v3_v3v3(temp, area_no, ss->cache->scale); mul_v3_fl(temp, displace); - add_v3_v3(fc, temp); + add_v3_v3(area_co, temp); - /* add_v3_v3v3(p, ss->cache->location, an); */ + /* add_v3_v3v3(p, ss->cache->location, area_no); */ #pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) for (n = 0; n < totnode; n++) { @@ -2730,11 +2722,11 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if (sculpt_brush_test_sq(&test, vd.co)) { - if (plane_point_side_flip(vd.co, an, fc, flip)) { + if (plane_point_side_flip(vd.co, area_no, area_co, flip)) { float intr[3]; float val[3]; - point_plane_project(intr, vd.co, an, fc); + point_plane_project(intr, vd.co, area_no, area_co); sub_v3_v3v3(val, intr, vd.co); @@ -2742,7 +2734,7 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) /* 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), - NULL, an, vd.mask ? *vd.mask : 0.0f); + NULL, area_no, vd.mask ? *vd.mask : 0.0f); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -2767,9 +2759,9 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t float displace; - float sn[3]; - float an[3]; - float fc[3]; + float area_no_sp[3]; /* the sculpt-plane normal (whatever its set to) */ + float area_no[3]; /* geometry normal */ + float area_co[3]; int n; @@ -2780,12 +2772,12 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t bool flip; - calc_sculpt_plane(sd, ob, nodes, totnode, sn, fc); + calc_sculpt_plane(sd, ob, nodes, totnode, area_no_sp, area_co); if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA || (brush->flag & BRUSH_ORIGINAL_NORMAL)) - calc_area_normal(sd, ob, nodes, totnode, an); + calc_area_normal(sd, ob, nodes, totnode, area_no); else - copy_v3_v3(an, sn); + copy_v3_v3(area_no, area_no_sp); /* delay the first daub because grab delta is not setup */ if (ss->cache->first_time) @@ -2800,16 +2792,16 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t displace = radius * (0.25f + offset); - mul_v3_v3v3(temp, sn, ss->cache->scale); + mul_v3_v3v3(temp, area_no_sp, ss->cache->scale); mul_v3_fl(temp, displace); - add_v3_v3(fc, temp); + add_v3_v3(area_co, temp); /* init mat */ - cross_v3_v3v3(mat[0], an, ss->cache->grab_delta_symmetry); + cross_v3_v3v3(mat[0], area_no, ss->cache->grab_delta_symmetry); mat[0][3] = 0; - cross_v3_v3v3(mat[1], an, mat[0]); + cross_v3_v3v3(mat[1], area_no, mat[0]); mat[1][3] = 0; - copy_v3_v3(mat[2], an); + copy_v3_v3(mat[2], area_no); mat[2][3] = 0; copy_v3_v3(mat[3], ss->cache->location); mat[3][3] = 1; @@ -2833,11 +2825,11 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if (sculpt_brush_test_cube(&test, vd.co, mat)) { - if (plane_point_side_flip(vd.co, sn, fc, flip)) { + if (plane_point_side_flip(vd.co, area_no_sp, area_co, flip)) { float intr[3]; float val[3]; - point_plane_project(intr, vd.co, sn, fc); + point_plane_project(intr, vd.co, area_no_sp, area_co); sub_v3_v3v3(val, intr, vd.co); @@ -2846,7 +2838,7 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t * causes glitch with planes, see: T44390 */ const float fade = bstrength * tex_strength(ss, brush, vd.co, ss->cache->radius * test.dist, - NULL, an, vd.mask ? *vd.mask : 0.0f); + NULL, area_no, vd.mask ? *vd.mask : 0.0f); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -2868,8 +2860,8 @@ static void do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) float bstrength = ss->cache->bstrength; const float radius = ss->cache->radius; - float an[3]; - float fc[3]; + float area_no[3]; + float area_co[3]; float offset = get_offset(sd, ss); float displace; @@ -2878,13 +2870,13 @@ static void do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) float temp[3]; - calc_sculpt_plane(sd, ob, nodes, totnode, an, fc); + calc_sculpt_plane(sd, ob, nodes, totnode, area_no, area_co); displace = radius * offset; - mul_v3_v3v3(temp, an, ss->cache->scale); + mul_v3_v3v3(temp, area_no, ss->cache->scale); mul_v3_fl(temp, displace); - add_v3_v3(fc, temp); + add_v3_v3(area_co, temp); #pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) for (n = 0; n < totnode; n++) { @@ -2899,11 +2891,11 @@ static void do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if (sculpt_brush_test_sq(&test, vd.co)) { - if (plane_point_side(vd.co, an, fc)) { + if (plane_point_side(vd.co, area_no, area_co)) { float intr[3]; float val[3]; - point_plane_project(intr, vd.co, an, fc); + point_plane_project(intr, vd.co, area_no, area_co); sub_v3_v3v3(val, intr, vd.co); @@ -2932,8 +2924,8 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod float bstrength = ss->cache->bstrength; const float radius = ss->cache->radius; - float an[3]; - float fc[3]; + float area_no[3]; + float area_co[3]; float offset = get_offset(sd, ss); float displace; @@ -2942,13 +2934,13 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod float temp[3]; - calc_sculpt_plane(sd, ob, nodes, totnode, an, fc); + calc_sculpt_plane(sd, ob, nodes, totnode, area_no, area_co); displace = -radius * offset; - mul_v3_v3v3(temp, an, ss->cache->scale); + mul_v3_v3v3(temp, area_no, ss->cache->scale); mul_v3_fl(temp, displace); - add_v3_v3(fc, temp); + add_v3_v3(area_co, temp); #pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) for (n = 0; n < totnode; n++) { @@ -2963,11 +2955,11 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if (sculpt_brush_test_sq(&test, vd.co)) { - if (!plane_point_side(vd.co, an, fc)) { + if (!plane_point_side(vd.co, area_no, area_co)) { float intr[3]; float val[3]; - point_plane_project(intr, vd.co, an, fc); + point_plane_project(intr, vd.co, area_no, area_co); sub_v3_v3v3(val, intr, vd.co); @@ -2993,7 +2985,7 @@ static void do_gravity(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, fl SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); - float offset[3]/*, an[3]*/; + float offset[3]/*, area_no[3]*/; int n; float gravity_vector[3]; -- cgit v1.2.3 From e5048dd4ca8b8b40dacda52b87fce642fa51e922 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 19 Apr 2015 19:51:02 +1000 Subject: Dyntopo: non-topology tool origdata support Brushes that don't change topology didn't have access to original data. --- source/blender/editors/sculpt_paint/sculpt.c | 52 +++++++++++++++++++--------- 1 file changed, 35 insertions(+), 17 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 7ab80e8d791..0af93e625ac 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -389,10 +389,6 @@ static void paint_mesh_restore_co(Sculpt *sd, Object *ob) PBVHNode **nodes; int n, totnode; -#ifndef _OPENMP - (void)sd; /* quied unused warning */ -#endif - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); /* Disable OpenMP when dynamic-topology is enabled. Otherwise, new @@ -747,7 +743,9 @@ static void calc_area_center( PBVHNode **nodes, int totnode, float r_area_co[3]) { + const Brush *brush = BKE_paint_brush(&sd->paint); SculptSession *ss = ob->sculpt; + const bool has_bm_orco = ss->bm && sculpt_stroke_dynamic_topology(ss, brush); int n; /* 0=towards view, 1=flipped */ @@ -755,8 +753,6 @@ static void calc_area_center( int count[2] = {0}; - (void)sd; /* unused w/o openmp */ - #pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) for (n = 0; n < totnode; n++) { PBVHVertexIter vd; @@ -773,7 +769,7 @@ static void calc_area_center( /* when the mesh is edited we can't rely on original coords * (original mesh may not even have verts in brush radius) */ - if (use_original && unode->bm_entry) { + if (use_original && has_bm_orco) { float (*orco_coords)[3]; int (*orco_tris)[3]; int orco_tris_num; @@ -809,9 +805,16 @@ static void calc_area_center( BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { const float *co; + const short *no_s; /* bm_vert only */ if (use_original) { - co = unode->co[vd.i]; + if (unode->bm_entry) { + BM_log_original_vert_data(ss->bm_log, vd.bm_vert, &co, &no_s); + } + else { + co = unode->co[vd.i]; + no_s = unode->no[vd.i]; + } } else { co = vd.co; @@ -823,7 +826,7 @@ static void calc_area_center( int flip_index; if (use_original) { - normal_short_to_float_v3(no_buf, unode->no[vd.i]); + normal_short_to_float_v3(no_buf, no_s); no = no_buf; } else { @@ -876,6 +879,7 @@ static void calc_area_normal( { const Brush *brush = BKE_paint_brush(&sd->paint); SculptSession *ss = ob->sculpt; + const bool has_bm_orco = ss->bm && sculpt_stroke_dynamic_topology(ss, brush); int n; /* 0=towards view, 1=flipped */ @@ -915,7 +919,7 @@ static void calc_area_normal( /* when the mesh is edited we can't rely on original coords * (original mesh may not even have verts in brush radius) */ - if (use_original && unode->bm_entry) { + if (use_original && has_bm_orco) { float (*orco_coords)[3]; int (*orco_tris)[3]; int orco_tris_num; @@ -951,9 +955,16 @@ static void calc_area_normal( BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { const float *co; + const short *no_s; /* bm_vert only */ if (use_original) { - co = unode->co[vd.i]; + if (unode->bm_entry) { + BM_log_original_vert_data(ss->bm_log, vd.bm_vert, &co, &no_s); + } + else { + co = unode->co[vd.i]; + no_s = unode->no[vd.i]; + } } else { co = vd.co; @@ -965,7 +976,7 @@ static void calc_area_normal( int flip_index; if (use_original) { - normal_short_to_float_v3(no_buf, unode->no[vd.i]); + normal_short_to_float_v3(no_buf, no_s); no = no_buf; } else { @@ -1013,7 +1024,9 @@ static void calc_area_normal_and_center( PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3]) { + const Brush *brush = BKE_paint_brush(&sd->paint); SculptSession *ss = ob->sculpt; + const bool has_bm_orco = ss->bm && sculpt_stroke_dynamic_topology(ss, brush); int n; /* 0=towards view, 1=flipped */ @@ -1022,8 +1035,6 @@ static void calc_area_normal_and_center( int count[2] = {0}; - (void)sd; /* unused w/o openmp */ - #pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) for (n = 0; n < totnode; n++) { PBVHVertexIter vd; @@ -1041,7 +1052,7 @@ static void calc_area_normal_and_center( /* when the mesh is edited we can't rely on original coords * (original mesh may not even have verts in brush radius) */ - if (use_original && unode->bm_entry) { + if (use_original && has_bm_orco) { float (*orco_coords)[3]; int (*orco_tris)[3]; int orco_tris_num; @@ -1078,9 +1089,16 @@ static void calc_area_normal_and_center( BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { const float *co; + const short *no_s; /* bm_vert only */ if (use_original) { - co = unode->co[vd.i]; + if (unode->bm_entry) { + BM_log_original_vert_data(ss->bm_log, vd.bm_vert, &co, &no_s); + } + else { + co = unode->co[vd.i]; + no_s = unode->no[vd.i]; + } } else { co = vd.co; @@ -1092,7 +1110,7 @@ static void calc_area_normal_and_center( int flip_index; if (use_original) { - normal_short_to_float_v3(no_buf, unode->no[vd.i]); + normal_short_to_float_v3(no_buf, no_s); no = no_buf; } else { -- cgit v1.2.3 From 436004b6b17a99b878f6ac9ba79ed3c00c6d39c0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 20 Apr 2015 12:35:49 +1000 Subject: Sculpt: clay-strips was missing accumulate button Correct & de-duplicate check for accumulate. --- source/blender/editors/sculpt_paint/sculpt.c | 117 +++++++++++++-------------- 1 file changed, 58 insertions(+), 59 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 0af93e625ac..9c7edb5b567 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -116,6 +116,13 @@ static int system_physical_thread_count(void) } #endif /* __APPLE__ */ +/** \name Tool Capabilities + * + * Avoid duplicate checks, internal logic only, + * share logic with #rna_def_sculpt_capabilities where possible. + * + * \{ */ + /* Check if there are any active modifiers in stack (used for flushing updates at enter/exit sculpt mode) */ static bool sculpt_has_active_modifiers(Scene *scene, Object *ob) { @@ -133,6 +140,43 @@ static bool sculpt_has_active_modifiers(Scene *scene, Object *ob) return 0; } +static bool sculpt_tool_needs_original(const char sculpt_tool) +{ + return ELEM(sculpt_tool, + SCULPT_TOOL_GRAB, + SCULPT_TOOL_ROTATE, + SCULPT_TOOL_THUMB, + SCULPT_TOOL_LAYER); +} + +static bool sculpt_tool_is_proxy_used(const char sculpt_tool) +{ + return ELEM(sculpt_tool, + SCULPT_TOOL_SMOOTH, + SCULPT_TOOL_LAYER); +} + +/** + * Test whether the #StrokeCache.sculpt_normal needs update in #do_brush_action + */ +static int sculpt_brush_needs_normal(const Brush *brush) +{ + return ((SCULPT_TOOL_HAS_NORMAL_WEIGHT(brush->sculpt_tool) && + (brush->normal_weight > 0)) || + + ELEM(brush->sculpt_tool, + SCULPT_TOOL_BLOB, + SCULPT_TOOL_CREASE, + SCULPT_TOOL_DRAW, + SCULPT_TOOL_LAYER, + SCULPT_TOOL_NUDGE, + SCULPT_TOOL_ROTATE, + SCULPT_TOOL_THUMB) || + + (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA)); +} + +/** \} */ typedef enum StrokeFlags { @@ -352,8 +396,8 @@ static void sculpt_project_v3( * Factors: some brushes like grab cannot do dynamic topology. * Others, like smooth, are better without. Same goes for alt- * key smoothing. */ -static int sculpt_stroke_dynamic_topology(const SculptSession *ss, - const Brush *brush) +static bool sculpt_stroke_is_dynamic_topology( + const SculptSession *ss, const Brush *brush) { return ((BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) && @@ -364,19 +408,7 @@ static int sculpt_stroke_dynamic_topology(const SculptSession *ss, !(brush->flag & BRUSH_ANCHORED) && !(brush->flag & BRUSH_DRAG_DOT) && - (!ELEM(brush->sculpt_tool, - /* These brushes, as currently coded, cannot - * support dynamic topology */ - SCULPT_TOOL_GRAB, - SCULPT_TOOL_ROTATE, - SCULPT_TOOL_THUMB, - SCULPT_TOOL_LAYER, - - /* These brushes could handle dynamic topology, - * but user feedback indicates it's better not - * to */ - SCULPT_TOOL_SMOOTH, - SCULPT_TOOL_MASK))); + SCULPT_TOOL_HAS_DYNTOPO(brush->sculpt_tool)); } /*** paint mesh ***/ @@ -745,7 +777,7 @@ static void calc_area_center( { const Brush *brush = BKE_paint_brush(&sd->paint); SculptSession *ss = ob->sculpt; - const bool has_bm_orco = ss->bm && sculpt_stroke_dynamic_topology(ss, brush); + const bool has_bm_orco = ss->bm && sculpt_stroke_is_dynamic_topology(ss, brush); int n; /* 0=towards view, 1=flipped */ @@ -879,7 +911,7 @@ static void calc_area_normal( { const Brush *brush = BKE_paint_brush(&sd->paint); SculptSession *ss = ob->sculpt; - const bool has_bm_orco = ss->bm && sculpt_stroke_dynamic_topology(ss, brush); + const bool has_bm_orco = ss->bm && sculpt_stroke_is_dynamic_topology(ss, brush); int n; /* 0=towards view, 1=flipped */ @@ -1026,7 +1058,7 @@ static void calc_area_normal_and_center( { const Brush *brush = BKE_paint_brush(&sd->paint); SculptSession *ss = ob->sculpt; - const bool has_bm_orco = ss->bm && sculpt_stroke_dynamic_topology(ss, brush); + const bool has_bm_orco = ss->bm && sculpt_stroke_is_dynamic_topology(ss, brush); int n; /* 0=towards view, 1=flipped */ @@ -1523,27 +1555,6 @@ static void update_brush_local_mat(Sculpt *sd, Object *ob) } } -/* Test whether the StrokeCache.sculpt_normal needs update in - * do_brush_action() */ -static int brush_needs_sculpt_normal(const Brush *brush) -{ - return ((ELEM(brush->sculpt_tool, - SCULPT_TOOL_GRAB, - SCULPT_TOOL_SNAKE_HOOK) && - (brush->normal_weight > 0)) || - - ELEM(brush->sculpt_tool, - SCULPT_TOOL_BLOB, - SCULPT_TOOL_CREASE, - SCULPT_TOOL_DRAW, - SCULPT_TOOL_LAYER, - SCULPT_TOOL_NUDGE, - SCULPT_TOOL_ROTATE, - SCULPT_TOOL_THUMB) || - - (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA)); -} - /* For the smooth brush, uses the neighboring vertices around vert to calculate * a smoothed location for vert. Skips corner vertices (used by only one * polygon.) */ @@ -3100,11 +3111,7 @@ static void sculpt_topology_update(Sculpt *sd, Object *ob, Brush *brush, Unified radius = ss->cache->radius * 1.25f; data.radius_squared = radius * radius; - data.original = ELEM(brush->sculpt_tool, - SCULPT_TOOL_GRAB, - SCULPT_TOOL_ROTATE, - SCULPT_TOOL_THUMB, - SCULPT_TOOL_LAYER) ? true : ss->cache->original; + 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); @@ -3159,11 +3166,7 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe data.ss = ss; data.sd = sd; data.radius_squared = ss->cache->radius_squared; - data.original = ELEM(brush->sculpt_tool, - SCULPT_TOOL_GRAB, - SCULPT_TOOL_ROTATE, - SCULPT_TOOL_THUMB, - SCULPT_TOOL_LAYER) ? true : ss->cache->original; + 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); /* Only act if some verts are inside the brush area */ @@ -3178,7 +3181,7 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe BKE_pbvh_node_mark_update(nodes[n]); } - if (brush_needs_sculpt_normal(brush)) + if (sculpt_brush_needs_normal(brush)) update_sculpt_normal(sd, ob, nodes, totnode); if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA) @@ -3298,8 +3301,8 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob) BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode); /* first line is tools that don't support proxies */ - if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_LAYER) || - ss->cache->supports_gravity) + if (ss->cache->supports_gravity || + (sculpt_tool_is_proxy_used(brush->sculpt_tool) == false)) { /* these brushes start from original coordinates */ const bool use_orco = ELEM(brush->sculpt_tool, SCULPT_TOOL_GRAB, @@ -3377,7 +3380,7 @@ static void sculpt_flush_stroke_deform(Sculpt *sd, Object *ob) SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); - if (ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_LAYER)) { + if (sculpt_tool_is_proxy_used(brush->sculpt_tool)) { /* this brushes aren't using proxies, so sculpt_combine_proxies() wouldn't * propagate needed deformation to original base */ @@ -3900,11 +3903,7 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio cache->original = 1; } - if (ELEM(brush->sculpt_tool, - SCULPT_TOOL_DRAW, SCULPT_TOOL_CREASE, SCULPT_TOOL_BLOB, - SCULPT_TOOL_LAYER, SCULPT_TOOL_INFLATE, SCULPT_TOOL_CLAY, - SCULPT_TOOL_CLAY_STRIPS, SCULPT_TOOL_ROTATE, SCULPT_TOOL_FLATTEN)) - { + if (SCULPT_TOOL_HAS_ACCUMULATE(brush->sculpt_tool)) { if (!(brush->flag & BRUSH_ACCUMULATE)) { cache->original = 1; } @@ -4404,7 +4403,7 @@ static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *UNUSED(st (float)(sd->detail_size * U.pixelsize) / 0.4f); } - if (sculpt_stroke_dynamic_topology(ss, brush)) { + if (sculpt_stroke_is_dynamic_topology(ss, brush)) { do_symmetrical_brush_actions(sd, ob, sculpt_topology_update, ups); } -- cgit v1.2.3 From 79319b3fba306524eef71946098deda71a449134 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 20 Apr 2015 13:36:51 +1000 Subject: Sculpt: remove workaround T25371 It's no longer needed, and made calc_area_normal different to the normal from calc_area_normal_and_center. --- source/blender/editors/sculpt_paint/sculpt.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 9c7edb5b567..40ef8970d68 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -919,22 +919,6 @@ static void calc_area_normal( int count[2] = {0}; - /* Grab brush requires to test on original data (see T25371) */ - bool original; - - original = (brush->sculpt_tool == SCULPT_TOOL_GRAB) ? true : ss->cache->original; - /* In general the original coords are not available with dynamic - * topology - * - * Mask tool could not use undo nodes to get coordinates from - * since the coordinates are not stored in those nodes. - * And mask tool is not gonna to modify vertex coordinates, - * so we don't actually need to use modified coords. - */ - if (brush->sculpt_tool == SCULPT_TOOL_MASK) { - original = false; - } - #pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) for (n = 0; n < totnode; n++) { PBVHVertexIter vd; @@ -947,7 +931,7 @@ static void calc_area_normal( unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS); sculpt_brush_test_init(ss, &test); - use_original = (original && (unode->co || unode->bm_entry)); + 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) */ -- cgit v1.2.3 From ddb5f962959d3ceead4137ab63b1237685198de8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 27 Apr 2015 03:35:16 +1000 Subject: Sculpt: symmetrize was leaving edge-tags dirty This is used for the edge-queue --- source/blender/editors/sculpt_paint/sculpt.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 40ef8970d68..1d2f623bf9d 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -4966,6 +4966,9 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *UNUSED(op)) sd->symmetrize_direction, 0.00001f); sculpt_dynamic_topology_triangulate(ss->bm); + /* bisect operator flags edges (keep tags clean for edge queue) */ + BM_mesh_elem_hflag_disable_all(ss->bm, BM_EDGE, BM_ELEM_TAG, false); + /* Finish undo */ BM_log_all_added(ss->bm, ss->bm_log); sculpt_undo_push_end(); -- cgit v1.2.3 From de180aba35ea0bc203abb4995b9fbcaa2d97aaa2 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Wed, 6 May 2015 22:51:49 +0200 Subject: Feature request: Dyntopo detail expressed in percentage of brush radius. Not sure how useful this will be but people have requested it so, here it is... --- source/blender/editors/sculpt_paint/sculpt.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 1d2f623bf9d..e2403a57556 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -4379,6 +4379,9 @@ static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *UNUSED(st if (sd->flags & SCULPT_DYNTOPO_DETAIL_CONSTANT) { BKE_pbvh_bmesh_detail_size_set(ss->pbvh, sd->constant_detail / 100.0f); } + else if (sd->flags & SCULPT_DYNTOPO_DETAIL_BRUSH) { + BKE_pbvh_bmesh_detail_size_set(ss->pbvh, ss->cache->radius * sd->detail_percent / 100.0f); + } else { BKE_pbvh_bmesh_detail_size_set( ss->pbvh, @@ -5072,10 +5075,10 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) ts->sculpt->flags |= SCULPT_DYNTOPO_SUBDIVIDE | SCULPT_DYNTOPO_COLLAPSE; } - if (!ts->sculpt->detail_size) { + if (!ts->sculpt->detail_size) ts->sculpt->detail_size = 12; - } - + if (!ts->sculpt->detail_percent) + ts->sculpt->detail_percent = 25; if (ts->sculpt->constant_detail == 0.0f) ts->sculpt->constant_detail = 30.0f; @@ -5308,6 +5311,10 @@ static int sculpt_set_detail_size_exec(bContext *C, wmOperator *UNUSED(op)) set_brush_rc_props(&props_ptr, "sculpt", "constant_detail", NULL, 0); RNA_string_set(&props_ptr, "data_path_primary", "tool_settings.sculpt.constant_detail"); } + else if (sd->flags & SCULPT_DYNTOPO_DETAIL_BRUSH) { + set_brush_rc_props(&props_ptr, "sculpt", "constant_detail", NULL, 0); + RNA_string_set(&props_ptr, "data_path_primary", "tool_settings.sculpt.detail_percent"); + } else { set_brush_rc_props(&props_ptr, "sculpt", "detail_size", NULL, 0); RNA_string_set(&props_ptr, "data_path_primary", "tool_settings.sculpt.detail_size"); -- cgit v1.2.3 From 5dfe88adbaeec63ede5c76dd84457e240f2fb602 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 18 May 2015 18:22:31 +1000 Subject: Fix T44553: Dyntopo ignores front-face option When 'Front Faces' brush option was enabled, dyntop would still adjust detail on back-faces. --- source/blender/editors/sculpt_paint/sculpt.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index e2403a57556..0d1ee08cc75 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -3126,9 +3126,11 @@ static void sculpt_topology_update(Sculpt *sd, Object *ob, Brush *brush, Unified } if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) { - BKE_pbvh_bmesh_update_topology(ss->pbvh, mode, - ss->cache->location, - ss->cache->radius); + BKE_pbvh_bmesh_update_topology( + ss->pbvh, mode, + ss->cache->location, + (brush->flag & BRUSH_FRONTFACE) ? ss->cache->view_normal : NULL, + ss->cache->radius); } MEM_freeN(nodes); @@ -5167,7 +5169,10 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op)) sculpt_undo_push_begin("Dynamic topology flood fill"); sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_COORDS); - while (BKE_pbvh_bmesh_update_topology(ss->pbvh, PBVH_Collapse | PBVH_Subdivide, bb_min, size)) { + while (BKE_pbvh_bmesh_update_topology( + ss->pbvh, PBVH_Collapse | PBVH_Subdivide, + bb_min, NULL, size)) + { for (i = 0; i < totnodes; i++) BKE_pbvh_node_mark_topology_update(nodes[i]); } -- cgit v1.2.3 From dc3533030abe2f188316fee993b274d7f83df288 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Tue, 19 May 2015 11:48:05 +0200 Subject: Fix T44553. Front face option did not get the correct normals to function - area normal would always point to the direction of the stroke --- source/blender/editors/sculpt_paint/sculpt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 0d1ee08cc75..8bdbe23ead8 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -2747,7 +2747,7 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) /* 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), - NULL, area_no, vd.mask ? *vd.mask : 0.0f); + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -2851,7 +2851,7 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t * causes glitch with planes, see: T44390 */ const float fade = bstrength * tex_strength(ss, brush, vd.co, ss->cache->radius * test.dist, - NULL, area_no, vd.mask ? *vd.mask : 0.0f); + vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f); mul_v3_v3fl(proxy[vd.i], val, fade); -- cgit v1.2.3 From 5d30c23c35aafba3a9bc772b4e66dd70b1ed84de Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 20 May 2015 12:54:45 +1000 Subject: doxygen: corrections/updates Also add depsgraph & physics --- source/blender/editors/sculpt_paint/sculpt.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 8bdbe23ead8..19777e0093c 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -373,6 +373,9 @@ static void sculpt_project_v3_cache_init( spvc->len_sq_inv_neg = (spvc->is_valid) ? -1.0f / spvc->len_sq : 0.0f; } +/** + * Calculate the projection. + */ static void sculpt_project_v3( const SculptProjectVector *spvc, const float vec[3], float r_vec[3]) -- cgit v1.2.3 From 07def553d2ad948f128a6be390abbab726dc89f0 Mon Sep 17 00:00:00 2001 From: Antony Riakiotakis Date: Wed, 27 May 2015 19:52:12 +0200 Subject: Fix T44745 non manifold edges of mesh do not work when smoothing in multires. Code had special guards for such edges to stop this from happening. I don't see why this is needed though since code above assigns smoothed positions for all vertices in the grid. After removing the guards I saw that this in fact was the only place where grd adjacency was used, so I completely removed it. --- source/blender/editors/sculpt_paint/sculpt.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 19777e0093c..0e75a344699 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1764,7 +1764,6 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no SculptBrushTest test; CCGElem **griddata, *data; CCGKey key; - DMGridAdjacency *gridadj, *adj; float (*tmpgrid_co)[3], (*tmprow_co)[3]; float *tmpgrid_mask, *tmprow_mask; int v1, v2, v3, v4; @@ -1777,7 +1776,7 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no CLAMP(bstrength, 0.0f, 1.0f); BKE_pbvh_node_get_grids(ss->pbvh, node, &grid_indices, &totgrid, - NULL, &gridsize, &griddata, &gridadj); + NULL, &gridsize, &griddata); BKE_pbvh_get_grid_key(ss->pbvh, &key); grid_hidden = BKE_pbvh_grid_hidden(ss->pbvh); @@ -1796,7 +1795,6 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no int gi = grid_indices[i]; const BLI_bitmap *gh = grid_hidden[gi]; data = griddata[gi]; - adj = &gridadj[gi]; if (smooth_mask) memset(tmpgrid_mask, 0, sizeof(float) * gridsize * gridsize); @@ -1862,18 +1860,6 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no continue; } - if (x == 0 && adj->index[0] == -1) - continue; - - if (x == gridsize - 1 && adj->index[2] == -1) - continue; - - if (y == 0 && adj->index[3] == -1) - continue; - - if (y == gridsize - 1 && adj->index[1] == -1) - continue; - index = x + y * gridsize; co = CCG_elem_offset_co(&key, data, index); fno = CCG_elem_offset_no(&key, data, index); @@ -3701,7 +3687,7 @@ static void sculpt_omp_start(Sculpt *sd, SculptSession *ss) if (ss->multires) { int i, gridsize, array_mem_size; BKE_pbvh_node_get_grids(ss->pbvh, NULL, NULL, NULL, NULL, - &gridsize, NULL, NULL); + &gridsize, NULL); array_mem_size = cache->num_threads * sizeof(void *); -- cgit v1.2.3 From 7a0f57cd01d337f6f3a9cf02ecece635551b881d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 4 Jun 2015 15:28:26 +1000 Subject: Cleanup: clarify order of precedence: &/? --- source/blender/editors/sculpt_paint/sculpt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/editors/sculpt_paint/sculpt.c') diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 0e75a344699..ede90b6e1f1 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1200,7 +1200,7 @@ static float brush_strength(const Sculpt *sd, const StrokeCache *cache, const fl /* Primary strength input; square it to make lower values more sensitive */ const float root_alpha = BKE_brush_alpha_get(scene, brush); float alpha = root_alpha * root_alpha; - float dir = brush->flag & BRUSH_DIR_IN ? -1 : 1; + float dir = (brush->flag & BRUSH_DIR_IN) ? -1 : 1; float pressure = BKE_brush_use_alpha_pressure(scene, brush) ? cache->pressure : 1; float pen_flip = cache->pen_flip ? -1 : 1; float invert = cache->invert ? -1 : 1; -- cgit v1.2.3